ActivityManagerService.java revision 8cd28b57ed732656d002d97879e15c5695b54fff
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    ArraySet<TaskRecord> mTmpRecents = new ArraySet<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 mWaitingUpdate = false;
893    boolean mDidUpdate = false;
894    boolean mOnBattery = false;
895    boolean mLaunchWarningShown = false;
896
897    Context mContext;
898
899    int mFactoryTest;
900
901    boolean mCheckedForSetup;
902
903    /**
904     * The time at which we will allow normal application switches again,
905     * after a call to {@link #stopAppSwitches()}.
906     */
907    long mAppSwitchesAllowedTime;
908
909    /**
910     * This is set to true after the first switch after mAppSwitchesAllowedTime
911     * is set; any switches after that will clear the time.
912     */
913    boolean mDidAppSwitch;
914
915    /**
916     * Last time (in realtime) at which we checked for power usage.
917     */
918    long mLastPowerCheckRealtime;
919
920    /**
921     * Last time (in uptime) at which we checked for power usage.
922     */
923    long mLastPowerCheckUptime;
924
925    /**
926     * Set while we are wanting to sleep, to prevent any
927     * activities from being started/resumed.
928     */
929    private boolean mSleeping = false;
930
931    /**
932     * Set while we are running a voice interaction.  This overrides
933     * sleeping while it is active.
934     */
935    private boolean mRunningVoice = false;
936
937    /**
938     * State of external calls telling us if the device is asleep.
939     */
940    private boolean mWentToSleep = false;
941
942    /**
943     * State of external call telling us if the lock screen is shown.
944     */
945    private boolean mLockScreenShown = false;
946
947    /**
948     * Set if we are shutting down the system, similar to sleeping.
949     */
950    boolean mShuttingDown = false;
951
952    /**
953     * Current sequence id for oom_adj computation traversal.
954     */
955    int mAdjSeq = 0;
956
957    /**
958     * Current sequence id for process LRU updating.
959     */
960    int mLruSeq = 0;
961
962    /**
963     * Keep track of the non-cached/empty process we last found, to help
964     * determine how to distribute cached/empty processes next time.
965     */
966    int mNumNonCachedProcs = 0;
967
968    /**
969     * Keep track of the number of cached hidden procs, to balance oom adj
970     * distribution between those and empty procs.
971     */
972    int mNumCachedHiddenProcs = 0;
973
974    /**
975     * Keep track of the number of service processes we last found, to
976     * determine on the next iteration which should be B services.
977     */
978    int mNumServiceProcs = 0;
979    int mNewNumAServiceProcs = 0;
980    int mNewNumServiceProcs = 0;
981
982    /**
983     * Allow the current computed overall memory level of the system to go down?
984     * This is set to false when we are killing processes for reasons other than
985     * memory management, so that the now smaller process list will not be taken as
986     * an indication that memory is tighter.
987     */
988    boolean mAllowLowerMemLevel = false;
989
990    /**
991     * The last computed memory level, for holding when we are in a state that
992     * processes are going away for other reasons.
993     */
994    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
995
996    /**
997     * The last total number of process we have, to determine if changes actually look
998     * like a shrinking number of process due to lower RAM.
999     */
1000    int mLastNumProcesses;
1001
1002    /**
1003     * The uptime of the last time we performed idle maintenance.
1004     */
1005    long mLastIdleTime = SystemClock.uptimeMillis();
1006
1007    /**
1008     * Total time spent with RAM that has been added in the past since the last idle time.
1009     */
1010    long mLowRamTimeSinceLastIdle = 0;
1011
1012    /**
1013     * If RAM is currently low, when that horrible situation started.
1014     */
1015    long mLowRamStartTime = 0;
1016
1017    /**
1018     * For reporting to battery stats the current top application.
1019     */
1020    private String mCurResumedPackage = null;
1021    private int mCurResumedUid = -1;
1022
1023    /**
1024     * For reporting to battery stats the apps currently running foreground
1025     * service.  The ProcessMap is package/uid tuples; each of these contain
1026     * an array of the currently foreground processes.
1027     */
1028    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1029            = new ProcessMap<ArrayList<ProcessRecord>>();
1030
1031    /**
1032     * This is set if we had to do a delayed dexopt of an app before launching
1033     * it, to increase the ANR timeouts in that case.
1034     */
1035    boolean mDidDexOpt;
1036
1037    /**
1038     * Set if the systemServer made a call to enterSafeMode.
1039     */
1040    boolean mSafeMode;
1041
1042    String mDebugApp = null;
1043    boolean mWaitForDebugger = false;
1044    boolean mDebugTransient = false;
1045    String mOrigDebugApp = null;
1046    boolean mOrigWaitForDebugger = false;
1047    boolean mAlwaysFinishActivities = false;
1048    IActivityController mController = null;
1049    String mProfileApp = null;
1050    ProcessRecord mProfileProc = null;
1051    String mProfileFile;
1052    ParcelFileDescriptor mProfileFd;
1053    int mSamplingInterval = 0;
1054    boolean mAutoStopProfiler = false;
1055    int mProfileType = 0;
1056    String mOpenGlTraceApp = null;
1057
1058    static class ProcessChangeItem {
1059        static final int CHANGE_ACTIVITIES = 1<<0;
1060        static final int CHANGE_PROCESS_STATE = 1<<1;
1061        int changes;
1062        int uid;
1063        int pid;
1064        int processState;
1065        boolean foregroundActivities;
1066    }
1067
1068    final RemoteCallbackList<IProcessObserver> mProcessObservers
1069            = new RemoteCallbackList<IProcessObserver>();
1070    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1071
1072    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1075            = new ArrayList<ProcessChangeItem>();
1076
1077    /**
1078     * Runtime CPU use collection thread.  This object's lock is used to
1079     * protect all related state.
1080     */
1081    final Thread mProcessCpuThread;
1082
1083    /**
1084     * Used to collect process stats when showing not responding dialog.
1085     * Protected by mProcessCpuThread.
1086     */
1087    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1088            MONITOR_THREAD_CPU_USAGE);
1089    final AtomicLong mLastCpuTime = new AtomicLong(0);
1090    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1091
1092    long mLastWriteTime = 0;
1093
1094    /**
1095     * Used to retain an update lock when the foreground activity is in
1096     * immersive mode.
1097     */
1098    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1099
1100    /**
1101     * Set to true after the system has finished booting.
1102     */
1103    boolean mBooted = false;
1104
1105    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1106    int mProcessLimitOverride = -1;
1107
1108    WindowManagerService mWindowManager;
1109
1110    final ActivityThread mSystemThread;
1111
1112    // Holds the current foreground user's id
1113    int mCurrentUserId = 0;
1114    // Holds the target user's id during a user switch
1115    int mTargetUserId = UserHandle.USER_NULL;
1116    // If there are multiple profiles for the current user, their ids are here
1117    // Currently only the primary user can have managed profiles
1118    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1119
1120    /**
1121     * Mapping from each known user ID to the profile group ID it is associated with.
1122     */
1123    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1124
1125    private UserManagerService mUserManager;
1126
1127    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1128        final ProcessRecord mApp;
1129        final int mPid;
1130        final IApplicationThread mAppThread;
1131
1132        AppDeathRecipient(ProcessRecord app, int pid,
1133                IApplicationThread thread) {
1134            if (localLOGV) Slog.v(
1135                TAG, "New death recipient " + this
1136                + " for thread " + thread.asBinder());
1137            mApp = app;
1138            mPid = pid;
1139            mAppThread = thread;
1140        }
1141
1142        @Override
1143        public void binderDied() {
1144            if (localLOGV) Slog.v(
1145                TAG, "Death received in " + this
1146                + " for thread " + mAppThread.asBinder());
1147            synchronized(ActivityManagerService.this) {
1148                appDiedLocked(mApp, mPid, mAppThread);
1149            }
1150        }
1151    }
1152
1153    static final int SHOW_ERROR_MSG = 1;
1154    static final int SHOW_NOT_RESPONDING_MSG = 2;
1155    static final int SHOW_FACTORY_ERROR_MSG = 3;
1156    static final int UPDATE_CONFIGURATION_MSG = 4;
1157    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1158    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1159    static final int SERVICE_TIMEOUT_MSG = 12;
1160    static final int UPDATE_TIME_ZONE = 13;
1161    static final int SHOW_UID_ERROR_MSG = 14;
1162    static final int IM_FEELING_LUCKY_MSG = 15;
1163    static final int PROC_START_TIMEOUT_MSG = 20;
1164    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1165    static final int KILL_APPLICATION_MSG = 22;
1166    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1167    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1168    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1169    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1170    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1171    static final int CLEAR_DNS_CACHE_MSG = 28;
1172    static final int UPDATE_HTTP_PROXY_MSG = 29;
1173    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1174    static final int DISPATCH_PROCESSES_CHANGED = 31;
1175    static final int DISPATCH_PROCESS_DIED = 32;
1176    static final int REPORT_MEM_USAGE_MSG = 33;
1177    static final int REPORT_USER_SWITCH_MSG = 34;
1178    static final int CONTINUE_USER_SWITCH_MSG = 35;
1179    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1180    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1181    static final int PERSIST_URI_GRANTS_MSG = 38;
1182    static final int REQUEST_ALL_PSS_MSG = 39;
1183    static final int START_PROFILES_MSG = 40;
1184    static final int UPDATE_TIME = 41;
1185    static final int SYSTEM_USER_START_MSG = 42;
1186    static final int SYSTEM_USER_CURRENT_MSG = 43;
1187    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1188    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1189    static final int START_USER_SWITCH_MSG = 46;
1190
1191    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1192    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1193    static final int FIRST_COMPAT_MODE_MSG = 300;
1194    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1195
1196    AlertDialog mUidAlert;
1197    CompatModeDialog mCompatModeDialog;
1198    long mLastMemUsageReportTime = 0;
1199
1200    private LockToAppRequestDialog mLockToAppRequest;
1201
1202    /**
1203     * Flag whether the current user is a "monkey", i.e. whether
1204     * the UI is driven by a UI automation tool.
1205     */
1206    private boolean mUserIsMonkey;
1207
1208    /** Flag whether the device has a Recents UI */
1209    boolean mHasRecents;
1210
1211    /** The dimensions of the thumbnails in the Recents UI. */
1212    int mThumbnailWidth;
1213    int mThumbnailHeight;
1214
1215    final ServiceThread mHandlerThread;
1216    final MainHandler mHandler;
1217
1218    final class MainHandler extends Handler {
1219        public MainHandler(Looper looper) {
1220            super(looper, null, true);
1221        }
1222
1223        @Override
1224        public void handleMessage(Message msg) {
1225            switch (msg.what) {
1226            case SHOW_ERROR_MSG: {
1227                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1228                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1229                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1230                synchronized (ActivityManagerService.this) {
1231                    ProcessRecord proc = (ProcessRecord)data.get("app");
1232                    AppErrorResult res = (AppErrorResult) data.get("result");
1233                    if (proc != null && proc.crashDialog != null) {
1234                        Slog.e(TAG, "App already has crash dialog: " + proc);
1235                        if (res != null) {
1236                            res.set(0);
1237                        }
1238                        return;
1239                    }
1240                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1241                            >= Process.FIRST_APPLICATION_UID
1242                            && proc.pid != MY_PID);
1243                    for (int userId : mCurrentProfileIds) {
1244                        isBackground &= (proc.userId != userId);
1245                    }
1246                    if (isBackground && !showBackground) {
1247                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1248                        if (res != null) {
1249                            res.set(0);
1250                        }
1251                        return;
1252                    }
1253                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1254                        Dialog d = new AppErrorDialog(mContext,
1255                                ActivityManagerService.this, res, proc);
1256                        d.show();
1257                        proc.crashDialog = d;
1258                    } else {
1259                        // The device is asleep, so just pretend that the user
1260                        // saw a crash dialog and hit "force quit".
1261                        if (res != null) {
1262                            res.set(0);
1263                        }
1264                    }
1265                }
1266
1267                ensureBootCompleted();
1268            } break;
1269            case SHOW_NOT_RESPONDING_MSG: {
1270                synchronized (ActivityManagerService.this) {
1271                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                    ProcessRecord proc = (ProcessRecord)data.get("app");
1273                    if (proc != null && proc.anrDialog != null) {
1274                        Slog.e(TAG, "App already has anr dialog: " + proc);
1275                        return;
1276                    }
1277
1278                    Intent intent = new Intent("android.intent.action.ANR");
1279                    if (!mProcessesReady) {
1280                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1281                                | Intent.FLAG_RECEIVER_FOREGROUND);
1282                    }
1283                    broadcastIntentLocked(null, null, intent,
1284                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1285                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1286
1287                    if (mShowDialogs) {
1288                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1289                                mContext, proc, (ActivityRecord)data.get("activity"),
1290                                msg.arg1 != 0);
1291                        d.show();
1292                        proc.anrDialog = d;
1293                    } else {
1294                        // Just kill the app if there is no dialog to be shown.
1295                        killAppAtUsersRequest(proc, null);
1296                    }
1297                }
1298
1299                ensureBootCompleted();
1300            } break;
1301            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1302                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1303                synchronized (ActivityManagerService.this) {
1304                    ProcessRecord proc = (ProcessRecord) data.get("app");
1305                    if (proc == null) {
1306                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1307                        break;
1308                    }
1309                    if (proc.crashDialog != null) {
1310                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1311                        return;
1312                    }
1313                    AppErrorResult res = (AppErrorResult) data.get("result");
1314                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1315                        Dialog d = new StrictModeViolationDialog(mContext,
1316                                ActivityManagerService.this, res, proc);
1317                        d.show();
1318                        proc.crashDialog = d;
1319                    } else {
1320                        // The device is asleep, so just pretend that the user
1321                        // saw a crash dialog and hit "force quit".
1322                        res.set(0);
1323                    }
1324                }
1325                ensureBootCompleted();
1326            } break;
1327            case SHOW_FACTORY_ERROR_MSG: {
1328                Dialog d = new FactoryErrorDialog(
1329                    mContext, msg.getData().getCharSequence("msg"));
1330                d.show();
1331                ensureBootCompleted();
1332            } break;
1333            case UPDATE_CONFIGURATION_MSG: {
1334                final ContentResolver resolver = mContext.getContentResolver();
1335                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1336            } break;
1337            case GC_BACKGROUND_PROCESSES_MSG: {
1338                synchronized (ActivityManagerService.this) {
1339                    performAppGcsIfAppropriateLocked();
1340                }
1341            } break;
1342            case WAIT_FOR_DEBUGGER_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    ProcessRecord app = (ProcessRecord)msg.obj;
1345                    if (msg.arg1 != 0) {
1346                        if (!app.waitedForDebugger) {
1347                            Dialog d = new AppWaitingForDebuggerDialog(
1348                                    ActivityManagerService.this,
1349                                    mContext, app);
1350                            app.waitDialog = d;
1351                            app.waitedForDebugger = true;
1352                            d.show();
1353                        }
1354                    } else {
1355                        if (app.waitDialog != null) {
1356                            app.waitDialog.dismiss();
1357                            app.waitDialog = null;
1358                        }
1359                    }
1360                }
1361            } break;
1362            case SERVICE_TIMEOUT_MSG: {
1363                if (mDidDexOpt) {
1364                    mDidDexOpt = false;
1365                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1366                    nmsg.obj = msg.obj;
1367                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1368                    return;
1369                }
1370                mServices.serviceTimeout((ProcessRecord)msg.obj);
1371            } break;
1372            case UPDATE_TIME_ZONE: {
1373                synchronized (ActivityManagerService.this) {
1374                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1375                        ProcessRecord r = mLruProcesses.get(i);
1376                        if (r.thread != null) {
1377                            try {
1378                                r.thread.updateTimeZone();
1379                            } catch (RemoteException ex) {
1380                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1381                            }
1382                        }
1383                    }
1384                }
1385            } break;
1386            case CLEAR_DNS_CACHE_MSG: {
1387                synchronized (ActivityManagerService.this) {
1388                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1389                        ProcessRecord r = mLruProcesses.get(i);
1390                        if (r.thread != null) {
1391                            try {
1392                                r.thread.clearDnsCache();
1393                            } catch (RemoteException ex) {
1394                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1395                            }
1396                        }
1397                    }
1398                }
1399            } break;
1400            case UPDATE_HTTP_PROXY_MSG: {
1401                ProxyInfo proxy = (ProxyInfo)msg.obj;
1402                String host = "";
1403                String port = "";
1404                String exclList = "";
1405                Uri pacFileUrl = Uri.EMPTY;
1406                if (proxy != null) {
1407                    host = proxy.getHost();
1408                    port = Integer.toString(proxy.getPort());
1409                    exclList = proxy.getExclusionListAsString();
1410                    pacFileUrl = proxy.getPacFileUrl();
1411                }
1412                synchronized (ActivityManagerService.this) {
1413                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1414                        ProcessRecord r = mLruProcesses.get(i);
1415                        if (r.thread != null) {
1416                            try {
1417                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1418                            } catch (RemoteException ex) {
1419                                Slog.w(TAG, "Failed to update http proxy for: " +
1420                                        r.info.processName);
1421                            }
1422                        }
1423                    }
1424                }
1425            } break;
1426            case SHOW_UID_ERROR_MSG: {
1427                String title = "System UIDs Inconsistent";
1428                String text = "UIDs on the system are inconsistent, you need to wipe your"
1429                        + " data partition or your device will be unstable.";
1430                Log.e(TAG, title + ": " + text);
1431                if (mShowDialogs) {
1432                    // XXX This is a temporary dialog, no need to localize.
1433                    AlertDialog d = new BaseErrorDialog(mContext);
1434                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1435                    d.setCancelable(false);
1436                    d.setTitle(title);
1437                    d.setMessage(text);
1438                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1439                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1440                    mUidAlert = d;
1441                    d.show();
1442                }
1443            } break;
1444            case IM_FEELING_LUCKY_MSG: {
1445                if (mUidAlert != null) {
1446                    mUidAlert.dismiss();
1447                    mUidAlert = null;
1448                }
1449            } break;
1450            case PROC_START_TIMEOUT_MSG: {
1451                if (mDidDexOpt) {
1452                    mDidDexOpt = false;
1453                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1454                    nmsg.obj = msg.obj;
1455                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1456                    return;
1457                }
1458                ProcessRecord app = (ProcessRecord)msg.obj;
1459                synchronized (ActivityManagerService.this) {
1460                    processStartTimedOutLocked(app);
1461                }
1462            } break;
1463            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1464                synchronized (ActivityManagerService.this) {
1465                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1466                }
1467            } break;
1468            case KILL_APPLICATION_MSG: {
1469                synchronized (ActivityManagerService.this) {
1470                    int appid = msg.arg1;
1471                    boolean restart = (msg.arg2 == 1);
1472                    Bundle bundle = (Bundle)msg.obj;
1473                    String pkg = bundle.getString("pkg");
1474                    String reason = bundle.getString("reason");
1475                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1476                            false, UserHandle.USER_ALL, reason);
1477                }
1478            } break;
1479            case FINALIZE_PENDING_INTENT_MSG: {
1480                ((PendingIntentRecord)msg.obj).completeFinalize();
1481            } break;
1482            case POST_HEAVY_NOTIFICATION_MSG: {
1483                INotificationManager inm = NotificationManager.getService();
1484                if (inm == null) {
1485                    return;
1486                }
1487
1488                ActivityRecord root = (ActivityRecord)msg.obj;
1489                ProcessRecord process = root.app;
1490                if (process == null) {
1491                    return;
1492                }
1493
1494                try {
1495                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1496                    String text = mContext.getString(R.string.heavy_weight_notification,
1497                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1498                    Notification notification = new Notification();
1499                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1500                    notification.when = 0;
1501                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1502                    notification.tickerText = text;
1503                    notification.defaults = 0; // please be quiet
1504                    notification.sound = null;
1505                    notification.vibrate = null;
1506                    notification.color = mContext.getResources().getColor(
1507                            com.android.internal.R.color.system_notification_accent_color);
1508                    notification.setLatestEventInfo(context, text,
1509                            mContext.getText(R.string.heavy_weight_notification_detail),
1510                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1511                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1512                                    new UserHandle(root.userId)));
1513
1514                    try {
1515                        int[] outId = new int[1];
1516                        inm.enqueueNotificationWithTag("android", "android", null,
1517                                R.string.heavy_weight_notification,
1518                                notification, outId, root.userId);
1519                    } catch (RuntimeException e) {
1520                        Slog.w(ActivityManagerService.TAG,
1521                                "Error showing notification for heavy-weight app", e);
1522                    } catch (RemoteException e) {
1523                    }
1524                } catch (NameNotFoundException e) {
1525                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1526                }
1527            } break;
1528            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1529                INotificationManager inm = NotificationManager.getService();
1530                if (inm == null) {
1531                    return;
1532                }
1533                try {
1534                    inm.cancelNotificationWithTag("android", null,
1535                            R.string.heavy_weight_notification,  msg.arg1);
1536                } catch (RuntimeException e) {
1537                    Slog.w(ActivityManagerService.TAG,
1538                            "Error canceling notification for service", e);
1539                } catch (RemoteException e) {
1540                }
1541            } break;
1542            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1543                synchronized (ActivityManagerService.this) {
1544                    checkExcessivePowerUsageLocked(true);
1545                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1546                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1547                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1548                }
1549            } break;
1550            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1551                synchronized (ActivityManagerService.this) {
1552                    ActivityRecord ar = (ActivityRecord)msg.obj;
1553                    if (mCompatModeDialog != null) {
1554                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1555                                ar.info.applicationInfo.packageName)) {
1556                            return;
1557                        }
1558                        mCompatModeDialog.dismiss();
1559                        mCompatModeDialog = null;
1560                    }
1561                    if (ar != null && false) {
1562                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1563                                ar.packageName)) {
1564                            int mode = mCompatModePackages.computeCompatModeLocked(
1565                                    ar.info.applicationInfo);
1566                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1567                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1568                                mCompatModeDialog = new CompatModeDialog(
1569                                        ActivityManagerService.this, mContext,
1570                                        ar.info.applicationInfo);
1571                                mCompatModeDialog.show();
1572                            }
1573                        }
1574                    }
1575                }
1576                break;
1577            }
1578            case DISPATCH_PROCESSES_CHANGED: {
1579                dispatchProcessesChanged();
1580                break;
1581            }
1582            case DISPATCH_PROCESS_DIED: {
1583                final int pid = msg.arg1;
1584                final int uid = msg.arg2;
1585                dispatchProcessDied(pid, uid);
1586                break;
1587            }
1588            case REPORT_MEM_USAGE_MSG: {
1589                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1590                Thread thread = new Thread() {
1591                    @Override public void run() {
1592                        final SparseArray<ProcessMemInfo> infoMap
1593                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1594                        for (int i=0, N=memInfos.size(); i<N; i++) {
1595                            ProcessMemInfo mi = memInfos.get(i);
1596                            infoMap.put(mi.pid, mi);
1597                        }
1598                        updateCpuStatsNow();
1599                        synchronized (mProcessCpuThread) {
1600                            final int N = mProcessCpuTracker.countStats();
1601                            for (int i=0; i<N; i++) {
1602                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1603                                if (st.vsize > 0) {
1604                                    long pss = Debug.getPss(st.pid, null);
1605                                    if (pss > 0) {
1606                                        if (infoMap.indexOfKey(st.pid) < 0) {
1607                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1608                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1609                                            mi.pss = pss;
1610                                            memInfos.add(mi);
1611                                        }
1612                                    }
1613                                }
1614                            }
1615                        }
1616
1617                        long totalPss = 0;
1618                        for (int i=0, N=memInfos.size(); i<N; i++) {
1619                            ProcessMemInfo mi = memInfos.get(i);
1620                            if (mi.pss == 0) {
1621                                mi.pss = Debug.getPss(mi.pid, null);
1622                            }
1623                            totalPss += mi.pss;
1624                        }
1625                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1626                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1627                                if (lhs.oomAdj != rhs.oomAdj) {
1628                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1629                                }
1630                                if (lhs.pss != rhs.pss) {
1631                                    return lhs.pss < rhs.pss ? 1 : -1;
1632                                }
1633                                return 0;
1634                            }
1635                        });
1636
1637                        StringBuilder tag = new StringBuilder(128);
1638                        StringBuilder stack = new StringBuilder(128);
1639                        tag.append("Low on memory -- ");
1640                        appendMemBucket(tag, totalPss, "total", false);
1641                        appendMemBucket(stack, totalPss, "total", true);
1642
1643                        StringBuilder logBuilder = new StringBuilder(1024);
1644                        logBuilder.append("Low on memory:\n");
1645
1646                        boolean firstLine = true;
1647                        int lastOomAdj = Integer.MIN_VALUE;
1648                        for (int i=0, N=memInfos.size(); i<N; i++) {
1649                            ProcessMemInfo mi = memInfos.get(i);
1650
1651                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1652                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1653                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1654                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1655                                if (lastOomAdj != mi.oomAdj) {
1656                                    lastOomAdj = mi.oomAdj;
1657                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1658                                        tag.append(" / ");
1659                                    }
1660                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1661                                        if (firstLine) {
1662                                            stack.append(":");
1663                                            firstLine = false;
1664                                        }
1665                                        stack.append("\n\t at ");
1666                                    } else {
1667                                        stack.append("$");
1668                                    }
1669                                } else {
1670                                    tag.append(" ");
1671                                    stack.append("$");
1672                                }
1673                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1674                                    appendMemBucket(tag, mi.pss, mi.name, false);
1675                                }
1676                                appendMemBucket(stack, mi.pss, mi.name, true);
1677                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1678                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1679                                    stack.append("(");
1680                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1681                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1682                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1683                                            stack.append(":");
1684                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1685                                        }
1686                                    }
1687                                    stack.append(")");
1688                                }
1689                            }
1690
1691                            logBuilder.append("  ");
1692                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1693                            logBuilder.append(' ');
1694                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1695                            logBuilder.append(' ');
1696                            ProcessList.appendRamKb(logBuilder, mi.pss);
1697                            logBuilder.append(" kB: ");
1698                            logBuilder.append(mi.name);
1699                            logBuilder.append(" (");
1700                            logBuilder.append(mi.pid);
1701                            logBuilder.append(") ");
1702                            logBuilder.append(mi.adjType);
1703                            logBuilder.append('\n');
1704                            if (mi.adjReason != null) {
1705                                logBuilder.append("                      ");
1706                                logBuilder.append(mi.adjReason);
1707                                logBuilder.append('\n');
1708                            }
1709                        }
1710
1711                        logBuilder.append("           ");
1712                        ProcessList.appendRamKb(logBuilder, totalPss);
1713                        logBuilder.append(" kB: TOTAL\n");
1714
1715                        long[] infos = new long[Debug.MEMINFO_COUNT];
1716                        Debug.getMemInfo(infos);
1717                        logBuilder.append("  MemInfo: ");
1718                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1719                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1720                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1721                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1722                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1723                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1724                            logBuilder.append("  ZRAM: ");
1725                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1726                            logBuilder.append(" kB RAM, ");
1727                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1728                            logBuilder.append(" kB swap total, ");
1729                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1730                            logBuilder.append(" kB swap free\n");
1731                        }
1732                        Slog.i(TAG, logBuilder.toString());
1733
1734                        StringBuilder dropBuilder = new StringBuilder(1024);
1735                        /*
1736                        StringWriter oomSw = new StringWriter();
1737                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1738                        StringWriter catSw = new StringWriter();
1739                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1740                        String[] emptyArgs = new String[] { };
1741                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1742                        oomPw.flush();
1743                        String oomString = oomSw.toString();
1744                        */
1745                        dropBuilder.append(stack);
1746                        dropBuilder.append('\n');
1747                        dropBuilder.append('\n');
1748                        dropBuilder.append(logBuilder);
1749                        dropBuilder.append('\n');
1750                        /*
1751                        dropBuilder.append(oomString);
1752                        dropBuilder.append('\n');
1753                        */
1754                        StringWriter catSw = new StringWriter();
1755                        synchronized (ActivityManagerService.this) {
1756                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1757                            String[] emptyArgs = new String[] { };
1758                            catPw.println();
1759                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1760                            catPw.println();
1761                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1762                                    false, false, null);
1763                            catPw.println();
1764                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1765                            catPw.flush();
1766                        }
1767                        dropBuilder.append(catSw.toString());
1768                        addErrorToDropBox("lowmem", null, "system_server", null,
1769                                null, tag.toString(), dropBuilder.toString(), null, null);
1770                        //Slog.i(TAG, "Sent to dropbox:");
1771                        //Slog.i(TAG, dropBuilder.toString());
1772                        synchronized (ActivityManagerService.this) {
1773                            long now = SystemClock.uptimeMillis();
1774                            if (mLastMemUsageReportTime < now) {
1775                                mLastMemUsageReportTime = now;
1776                            }
1777                        }
1778                    }
1779                };
1780                thread.start();
1781                break;
1782            }
1783            case START_USER_SWITCH_MSG: {
1784                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1785                break;
1786            }
1787            case REPORT_USER_SWITCH_MSG: {
1788                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1789                break;
1790            }
1791            case CONTINUE_USER_SWITCH_MSG: {
1792                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1793                break;
1794            }
1795            case USER_SWITCH_TIMEOUT_MSG: {
1796                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1797                break;
1798            }
1799            case IMMERSIVE_MODE_LOCK_MSG: {
1800                final boolean nextState = (msg.arg1 != 0);
1801                if (mUpdateLock.isHeld() != nextState) {
1802                    if (DEBUG_IMMERSIVE) {
1803                        final ActivityRecord r = (ActivityRecord) msg.obj;
1804                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1805                    }
1806                    if (nextState) {
1807                        mUpdateLock.acquire();
1808                    } else {
1809                        mUpdateLock.release();
1810                    }
1811                }
1812                break;
1813            }
1814            case PERSIST_URI_GRANTS_MSG: {
1815                writeGrantedUriPermissions();
1816                break;
1817            }
1818            case REQUEST_ALL_PSS_MSG: {
1819                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1820                break;
1821            }
1822            case START_PROFILES_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    startProfilesLocked();
1825                }
1826                break;
1827            }
1828            case UPDATE_TIME: {
1829                synchronized (ActivityManagerService.this) {
1830                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1831                        ProcessRecord r = mLruProcesses.get(i);
1832                        if (r.thread != null) {
1833                            try {
1834                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1835                            } catch (RemoteException ex) {
1836                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1837                            }
1838                        }
1839                    }
1840                }
1841                break;
1842            }
1843            case SYSTEM_USER_START_MSG: {
1844                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1845                        Integer.toString(msg.arg1), msg.arg1);
1846                mSystemServiceManager.startUser(msg.arg1);
1847                break;
1848            }
1849            case SYSTEM_USER_CURRENT_MSG: {
1850                mBatteryStatsService.noteEvent(
1851                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1852                        Integer.toString(msg.arg2), msg.arg2);
1853                mBatteryStatsService.noteEvent(
1854                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1855                        Integer.toString(msg.arg1), msg.arg1);
1856                mSystemServiceManager.switchUser(msg.arg1);
1857                mLockToAppRequest.clearPrompt();
1858                break;
1859            }
1860            case ENTER_ANIMATION_COMPLETE_MSG: {
1861                synchronized (ActivityManagerService.this) {
1862                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1863                    if (r != null && r.app != null && r.app.thread != null) {
1864                        try {
1865                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1866                        } catch (RemoteException e) {
1867                        }
1868                    }
1869                }
1870                break;
1871            }
1872            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1873                enableScreenAfterBoot();
1874                break;
1875            }
1876            }
1877        }
1878    };
1879
1880    static final int COLLECT_PSS_BG_MSG = 1;
1881
1882    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1883        @Override
1884        public void handleMessage(Message msg) {
1885            switch (msg.what) {
1886            case COLLECT_PSS_BG_MSG: {
1887                long start = SystemClock.uptimeMillis();
1888                MemInfoReader memInfo = null;
1889                synchronized (ActivityManagerService.this) {
1890                    if (mFullPssPending) {
1891                        mFullPssPending = false;
1892                        memInfo = new MemInfoReader();
1893                    }
1894                }
1895                if (memInfo != null) {
1896                    updateCpuStatsNow();
1897                    long nativeTotalPss = 0;
1898                    synchronized (mProcessCpuThread) {
1899                        final int N = mProcessCpuTracker.countStats();
1900                        for (int j=0; j<N; j++) {
1901                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1902                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1903                                // This is definitely an application process; skip it.
1904                                continue;
1905                            }
1906                            synchronized (mPidsSelfLocked) {
1907                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1908                                    // This is one of our own processes; skip it.
1909                                    continue;
1910                                }
1911                            }
1912                            nativeTotalPss += Debug.getPss(st.pid, null);
1913                        }
1914                    }
1915                    memInfo.readMemInfo();
1916                    synchronized (this) {
1917                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1918                                + (SystemClock.uptimeMillis()-start) + "ms");
1919                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1920                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1921                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1922                                        +memInfo.getSlabSizeKb(),
1923                                nativeTotalPss);
1924                    }
1925                }
1926
1927                int i=0, num=0;
1928                long[] tmp = new long[1];
1929                do {
1930                    ProcessRecord proc;
1931                    int procState;
1932                    int pid;
1933                    synchronized (ActivityManagerService.this) {
1934                        if (i >= mPendingPssProcesses.size()) {
1935                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1936                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1937                            mPendingPssProcesses.clear();
1938                            return;
1939                        }
1940                        proc = mPendingPssProcesses.get(i);
1941                        procState = proc.pssProcState;
1942                        if (proc.thread != null && procState == proc.setProcState) {
1943                            pid = proc.pid;
1944                        } else {
1945                            proc = null;
1946                            pid = 0;
1947                        }
1948                        i++;
1949                    }
1950                    if (proc != null) {
1951                        long pss = Debug.getPss(pid, tmp);
1952                        synchronized (ActivityManagerService.this) {
1953                            if (proc.thread != null && proc.setProcState == procState
1954                                    && proc.pid == pid) {
1955                                num++;
1956                                proc.lastPssTime = SystemClock.uptimeMillis();
1957                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1958                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1959                                        + ": " + pss + " lastPss=" + proc.lastPss
1960                                        + " state=" + ProcessList.makeProcStateString(procState));
1961                                if (proc.initialIdlePss == 0) {
1962                                    proc.initialIdlePss = pss;
1963                                }
1964                                proc.lastPss = pss;
1965                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1966                                    proc.lastCachedPss = pss;
1967                                }
1968                            }
1969                        }
1970                    }
1971                } while (true);
1972            }
1973            }
1974        }
1975    };
1976
1977    /**
1978     * Monitor for package changes and update our internal state.
1979     */
1980    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1981        @Override
1982        public void onPackageRemoved(String packageName, int uid) {
1983            // Remove all tasks with activities in the specified package from the list of recent tasks
1984            synchronized (ActivityManagerService.this) {
1985                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1986                    TaskRecord tr = mRecentTasks.get(i);
1987                    ComponentName cn = tr.intent.getComponent();
1988                    if (cn != null && cn.getPackageName().equals(packageName)) {
1989                        // If the package name matches, remove the task and kill the process
1990                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1991                    }
1992                }
1993            }
1994        }
1995
1996        @Override
1997        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1998            onPackageModified(packageName);
1999            return true;
2000        }
2001
2002        @Override
2003        public void onPackageModified(String packageName) {
2004            final PackageManager pm = mContext.getPackageManager();
2005            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2006                    new ArrayList<Pair<Intent, Integer>>();
2007            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2008            // Copy the list of recent tasks so that we don't hold onto the lock on
2009            // ActivityManagerService for long periods while checking if components exist.
2010            synchronized (ActivityManagerService.this) {
2011                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2012                    TaskRecord tr = mRecentTasks.get(i);
2013                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2014                }
2015            }
2016            // Check the recent tasks and filter out all tasks with components that no longer exist.
2017            Intent tmpI = new Intent();
2018            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2019                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2020                ComponentName cn = p.first.getComponent();
2021                if (cn != null && cn.getPackageName().equals(packageName)) {
2022                    try {
2023                        // Add the task to the list to remove if the component no longer exists
2024                        tmpI.setComponent(cn);
2025                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2026                            tasksToRemove.add(p.second);
2027                        }
2028                    } catch (Exception e) {}
2029                }
2030            }
2031            // Prune all the tasks with removed components from the list of recent tasks
2032            synchronized (ActivityManagerService.this) {
2033                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2034                    // Remove the task but don't kill the process (since other components in that
2035                    // package may still be running and in the background)
2036                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2037                }
2038            }
2039        }
2040
2041        @Override
2042        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2043            // Force stop the specified packages
2044            if (packages != null) {
2045                for (String pkg : packages) {
2046                    synchronized (ActivityManagerService.this) {
2047                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2048                                "finished booting")) {
2049                            return true;
2050                        }
2051                    }
2052                }
2053            }
2054            return false;
2055        }
2056    };
2057
2058    public void setSystemProcess() {
2059        try {
2060            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2061            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2062            ServiceManager.addService("meminfo", new MemBinder(this));
2063            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2064            ServiceManager.addService("dbinfo", new DbBinder(this));
2065            if (MONITOR_CPU_USAGE) {
2066                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2067            }
2068            ServiceManager.addService("permission", new PermissionController(this));
2069
2070            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2071                    "android", STOCK_PM_FLAGS);
2072            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2073
2074            synchronized (this) {
2075                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2076                app.persistent = true;
2077                app.pid = MY_PID;
2078                app.maxAdj = ProcessList.SYSTEM_ADJ;
2079                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2080                mProcessNames.put(app.processName, app.uid, app);
2081                synchronized (mPidsSelfLocked) {
2082                    mPidsSelfLocked.put(app.pid, app);
2083                }
2084                updateLruProcessLocked(app, false, null);
2085                updateOomAdjLocked();
2086            }
2087        } catch (PackageManager.NameNotFoundException e) {
2088            throw new RuntimeException(
2089                    "Unable to find android system package", e);
2090        }
2091    }
2092
2093    public void setWindowManager(WindowManagerService wm) {
2094        mWindowManager = wm;
2095        mStackSupervisor.setWindowManager(wm);
2096    }
2097
2098    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2099        mUsageStatsService = usageStatsManager;
2100    }
2101
2102    public void startObservingNativeCrashes() {
2103        final NativeCrashListener ncl = new NativeCrashListener(this);
2104        ncl.start();
2105    }
2106
2107    public IAppOpsService getAppOpsService() {
2108        return mAppOpsService;
2109    }
2110
2111    static class MemBinder extends Binder {
2112        ActivityManagerService mActivityManagerService;
2113        MemBinder(ActivityManagerService activityManagerService) {
2114            mActivityManagerService = activityManagerService;
2115        }
2116
2117        @Override
2118        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2119            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2120                    != PackageManager.PERMISSION_GRANTED) {
2121                pw.println("Permission Denial: can't dump meminfo from from pid="
2122                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2123                        + " without permission " + android.Manifest.permission.DUMP);
2124                return;
2125            }
2126
2127            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2128        }
2129    }
2130
2131    static class GraphicsBinder extends Binder {
2132        ActivityManagerService mActivityManagerService;
2133        GraphicsBinder(ActivityManagerService activityManagerService) {
2134            mActivityManagerService = activityManagerService;
2135        }
2136
2137        @Override
2138        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2139            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2140                    != PackageManager.PERMISSION_GRANTED) {
2141                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2142                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2143                        + " without permission " + android.Manifest.permission.DUMP);
2144                return;
2145            }
2146
2147            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2148        }
2149    }
2150
2151    static class DbBinder extends Binder {
2152        ActivityManagerService mActivityManagerService;
2153        DbBinder(ActivityManagerService activityManagerService) {
2154            mActivityManagerService = activityManagerService;
2155        }
2156
2157        @Override
2158        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2159            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2160                    != PackageManager.PERMISSION_GRANTED) {
2161                pw.println("Permission Denial: can't dump dbinfo from from pid="
2162                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2163                        + " without permission " + android.Manifest.permission.DUMP);
2164                return;
2165            }
2166
2167            mActivityManagerService.dumpDbInfo(fd, pw, args);
2168        }
2169    }
2170
2171    static class CpuBinder extends Binder {
2172        ActivityManagerService mActivityManagerService;
2173        CpuBinder(ActivityManagerService activityManagerService) {
2174            mActivityManagerService = activityManagerService;
2175        }
2176
2177        @Override
2178        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2179            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2180                    != PackageManager.PERMISSION_GRANTED) {
2181                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2182                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2183                        + " without permission " + android.Manifest.permission.DUMP);
2184                return;
2185            }
2186
2187            synchronized (mActivityManagerService.mProcessCpuThread) {
2188                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2189                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2190                        SystemClock.uptimeMillis()));
2191            }
2192        }
2193    }
2194
2195    public static final class Lifecycle extends SystemService {
2196        private final ActivityManagerService mService;
2197
2198        public Lifecycle(Context context) {
2199            super(context);
2200            mService = new ActivityManagerService(context);
2201        }
2202
2203        @Override
2204        public void onStart() {
2205            mService.start();
2206        }
2207
2208        public ActivityManagerService getService() {
2209            return mService;
2210        }
2211    }
2212
2213    // Note: This method is invoked on the main thread but may need to attach various
2214    // handlers to other threads.  So take care to be explicit about the looper.
2215    public ActivityManagerService(Context systemContext) {
2216        mContext = systemContext;
2217        mFactoryTest = FactoryTest.getMode();
2218        mSystemThread = ActivityThread.currentActivityThread();
2219
2220        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2221
2222        mHandlerThread = new ServiceThread(TAG,
2223                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2224        mHandlerThread.start();
2225        mHandler = new MainHandler(mHandlerThread.getLooper());
2226
2227        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2228                "foreground", BROADCAST_FG_TIMEOUT, false);
2229        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2230                "background", BROADCAST_BG_TIMEOUT, true);
2231        mBroadcastQueues[0] = mFgBroadcastQueue;
2232        mBroadcastQueues[1] = mBgBroadcastQueue;
2233
2234        mServices = new ActiveServices(this);
2235        mProviderMap = new ProviderMap(this);
2236
2237        // TODO: Move creation of battery stats service outside of activity manager service.
2238        File dataDir = Environment.getDataDirectory();
2239        File systemDir = new File(dataDir, "system");
2240        systemDir.mkdirs();
2241        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2242        mBatteryStatsService.getActiveStatistics().readLocked();
2243        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2244        mOnBattery = DEBUG_POWER ? true
2245                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2246        mBatteryStatsService.getActiveStatistics().setCallback(this);
2247
2248        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2249
2250        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2251
2252        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2253
2254        // User 0 is the first and only user that runs at boot.
2255        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2256        mUserLru.add(Integer.valueOf(0));
2257        updateStartedUserArrayLocked();
2258
2259        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2260            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2261
2262        mConfiguration.setToDefaults();
2263        mConfiguration.setLocale(Locale.getDefault());
2264
2265        mConfigurationSeq = mConfiguration.seq = 1;
2266        mProcessCpuTracker.init();
2267
2268        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2269        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2270        mStackSupervisor = new ActivityStackSupervisor(this);
2271        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2272
2273        mProcessCpuThread = new Thread("CpuTracker") {
2274            @Override
2275            public void run() {
2276                while (true) {
2277                    try {
2278                        try {
2279                            synchronized(this) {
2280                                final long now = SystemClock.uptimeMillis();
2281                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2282                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2283                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2284                                //        + ", write delay=" + nextWriteDelay);
2285                                if (nextWriteDelay < nextCpuDelay) {
2286                                    nextCpuDelay = nextWriteDelay;
2287                                }
2288                                if (nextCpuDelay > 0) {
2289                                    mProcessCpuMutexFree.set(true);
2290                                    this.wait(nextCpuDelay);
2291                                }
2292                            }
2293                        } catch (InterruptedException e) {
2294                        }
2295                        updateCpuStatsNow();
2296                    } catch (Exception e) {
2297                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2298                    }
2299                }
2300            }
2301        };
2302
2303        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2304
2305        Watchdog.getInstance().addMonitor(this);
2306        Watchdog.getInstance().addThread(mHandler);
2307    }
2308
2309    public void setSystemServiceManager(SystemServiceManager mgr) {
2310        mSystemServiceManager = mgr;
2311    }
2312
2313    private void start() {
2314        Process.removeAllProcessGroups();
2315        mProcessCpuThread.start();
2316
2317        mBatteryStatsService.publish(mContext);
2318        mAppOpsService.publish(mContext);
2319        Slog.d("AppOps", "AppOpsService published");
2320        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2321    }
2322
2323    public void initPowerManagement() {
2324        mStackSupervisor.initPowerManagement();
2325        mBatteryStatsService.initPowerManagement();
2326    }
2327
2328    @Override
2329    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2330            throws RemoteException {
2331        if (code == SYSPROPS_TRANSACTION) {
2332            // We need to tell all apps about the system property change.
2333            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2334            synchronized(this) {
2335                final int NP = mProcessNames.getMap().size();
2336                for (int ip=0; ip<NP; ip++) {
2337                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2338                    final int NA = apps.size();
2339                    for (int ia=0; ia<NA; ia++) {
2340                        ProcessRecord app = apps.valueAt(ia);
2341                        if (app.thread != null) {
2342                            procs.add(app.thread.asBinder());
2343                        }
2344                    }
2345                }
2346            }
2347
2348            int N = procs.size();
2349            for (int i=0; i<N; i++) {
2350                Parcel data2 = Parcel.obtain();
2351                try {
2352                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2353                } catch (RemoteException e) {
2354                }
2355                data2.recycle();
2356            }
2357        }
2358        try {
2359            return super.onTransact(code, data, reply, flags);
2360        } catch (RuntimeException e) {
2361            // The activity manager only throws security exceptions, so let's
2362            // log all others.
2363            if (!(e instanceof SecurityException)) {
2364                Slog.wtf(TAG, "Activity Manager Crash", e);
2365            }
2366            throw e;
2367        }
2368    }
2369
2370    void updateCpuStats() {
2371        final long now = SystemClock.uptimeMillis();
2372        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2373            return;
2374        }
2375        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2376            synchronized (mProcessCpuThread) {
2377                mProcessCpuThread.notify();
2378            }
2379        }
2380    }
2381
2382    void updateCpuStatsNow() {
2383        synchronized (mProcessCpuThread) {
2384            mProcessCpuMutexFree.set(false);
2385            final long now = SystemClock.uptimeMillis();
2386            boolean haveNewCpuStats = false;
2387
2388            if (MONITOR_CPU_USAGE &&
2389                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2390                mLastCpuTime.set(now);
2391                haveNewCpuStats = true;
2392                mProcessCpuTracker.update();
2393                //Slog.i(TAG, mProcessCpu.printCurrentState());
2394                //Slog.i(TAG, "Total CPU usage: "
2395                //        + mProcessCpu.getTotalCpuPercent() + "%");
2396
2397                // Slog the cpu usage if the property is set.
2398                if ("true".equals(SystemProperties.get("events.cpu"))) {
2399                    int user = mProcessCpuTracker.getLastUserTime();
2400                    int system = mProcessCpuTracker.getLastSystemTime();
2401                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2402                    int irq = mProcessCpuTracker.getLastIrqTime();
2403                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2404                    int idle = mProcessCpuTracker.getLastIdleTime();
2405
2406                    int total = user + system + iowait + irq + softIrq + idle;
2407                    if (total == 0) total = 1;
2408
2409                    EventLog.writeEvent(EventLogTags.CPU,
2410                            ((user+system+iowait+irq+softIrq) * 100) / total,
2411                            (user * 100) / total,
2412                            (system * 100) / total,
2413                            (iowait * 100) / total,
2414                            (irq * 100) / total,
2415                            (softIrq * 100) / total);
2416                }
2417            }
2418
2419            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2420            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2421            synchronized(bstats) {
2422                synchronized(mPidsSelfLocked) {
2423                    if (haveNewCpuStats) {
2424                        if (mOnBattery) {
2425                            int perc = bstats.startAddingCpuLocked();
2426                            int totalUTime = 0;
2427                            int totalSTime = 0;
2428                            final int N = mProcessCpuTracker.countStats();
2429                            for (int i=0; i<N; i++) {
2430                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2431                                if (!st.working) {
2432                                    continue;
2433                                }
2434                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2435                                int otherUTime = (st.rel_utime*perc)/100;
2436                                int otherSTime = (st.rel_stime*perc)/100;
2437                                totalUTime += otherUTime;
2438                                totalSTime += otherSTime;
2439                                if (pr != null) {
2440                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2441                                    if (ps == null || !ps.isActive()) {
2442                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2443                                                pr.info.uid, pr.processName);
2444                                    }
2445                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2446                                            st.rel_stime-otherSTime);
2447                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2448                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2449                                } else {
2450                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2451                                    if (ps == null || !ps.isActive()) {
2452                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2453                                                bstats.mapUid(st.uid), st.name);
2454                                    }
2455                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2456                                            st.rel_stime-otherSTime);
2457                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2458                                }
2459                            }
2460                            bstats.finishAddingCpuLocked(perc, totalUTime,
2461                                    totalSTime, cpuSpeedTimes);
2462                        }
2463                    }
2464                }
2465
2466                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2467                    mLastWriteTime = now;
2468                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2469                }
2470            }
2471        }
2472    }
2473
2474    @Override
2475    public void batteryNeedsCpuUpdate() {
2476        updateCpuStatsNow();
2477    }
2478
2479    @Override
2480    public void batteryPowerChanged(boolean onBattery) {
2481        // When plugging in, update the CPU stats first before changing
2482        // the plug state.
2483        updateCpuStatsNow();
2484        synchronized (this) {
2485            synchronized(mPidsSelfLocked) {
2486                mOnBattery = DEBUG_POWER ? true : onBattery;
2487            }
2488        }
2489    }
2490
2491    /**
2492     * Initialize the application bind args. These are passed to each
2493     * process when the bindApplication() IPC is sent to the process. They're
2494     * lazily setup to make sure the services are running when they're asked for.
2495     */
2496    private HashMap<String, IBinder> getCommonServicesLocked() {
2497        if (mAppBindArgs == null) {
2498            mAppBindArgs = new HashMap<String, IBinder>();
2499
2500            // Setup the application init args
2501            mAppBindArgs.put("package", ServiceManager.getService("package"));
2502            mAppBindArgs.put("window", ServiceManager.getService("window"));
2503            mAppBindArgs.put(Context.ALARM_SERVICE,
2504                    ServiceManager.getService(Context.ALARM_SERVICE));
2505        }
2506        return mAppBindArgs;
2507    }
2508
2509    final void setFocusedActivityLocked(ActivityRecord r) {
2510        if (mFocusedActivity != r) {
2511            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2512            mFocusedActivity = r;
2513            if (r.task != null && r.task.voiceInteractor != null) {
2514                startRunningVoiceLocked();
2515            } else {
2516                finishRunningVoiceLocked();
2517            }
2518            mStackSupervisor.setFocusedStack(r);
2519            if (r != null) {
2520                mWindowManager.setFocusedApp(r.appToken, true);
2521            }
2522            applyUpdateLockStateLocked(r);
2523        }
2524    }
2525
2526    final void clearFocusedActivity(ActivityRecord r) {
2527        if (mFocusedActivity == r) {
2528            mFocusedActivity = null;
2529        }
2530    }
2531
2532    @Override
2533    public void setFocusedStack(int stackId) {
2534        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2535        synchronized (ActivityManagerService.this) {
2536            ActivityStack stack = mStackSupervisor.getStack(stackId);
2537            if (stack != null) {
2538                ActivityRecord r = stack.topRunningActivityLocked(null);
2539                if (r != null) {
2540                    setFocusedActivityLocked(r);
2541                }
2542            }
2543        }
2544    }
2545
2546    @Override
2547    public void notifyActivityDrawn(IBinder token) {
2548        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2549        synchronized (this) {
2550            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2551            if (r != null) {
2552                r.task.stack.notifyActivityDrawnLocked(r);
2553            }
2554        }
2555    }
2556
2557    final void applyUpdateLockStateLocked(ActivityRecord r) {
2558        // Modifications to the UpdateLock state are done on our handler, outside
2559        // the activity manager's locks.  The new state is determined based on the
2560        // state *now* of the relevant activity record.  The object is passed to
2561        // the handler solely for logging detail, not to be consulted/modified.
2562        final boolean nextState = r != null && r.immersive;
2563        mHandler.sendMessage(
2564                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2565    }
2566
2567    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2568        Message msg = Message.obtain();
2569        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2570        msg.obj = r.task.askedCompatMode ? null : r;
2571        mHandler.sendMessage(msg);
2572    }
2573
2574    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2575            String what, Object obj, ProcessRecord srcApp) {
2576        app.lastActivityTime = now;
2577
2578        if (app.activities.size() > 0) {
2579            // Don't want to touch dependent processes that are hosting activities.
2580            return index;
2581        }
2582
2583        int lrui = mLruProcesses.lastIndexOf(app);
2584        if (lrui < 0) {
2585            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2586                    + what + " " + obj + " from " + srcApp);
2587            return index;
2588        }
2589
2590        if (lrui >= index) {
2591            // Don't want to cause this to move dependent processes *back* in the
2592            // list as if they were less frequently used.
2593            return index;
2594        }
2595
2596        if (lrui >= mLruProcessActivityStart) {
2597            // Don't want to touch dependent processes that are hosting activities.
2598            return index;
2599        }
2600
2601        mLruProcesses.remove(lrui);
2602        if (index > 0) {
2603            index--;
2604        }
2605        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2606                + " in LRU list: " + app);
2607        mLruProcesses.add(index, app);
2608        return index;
2609    }
2610
2611    final void removeLruProcessLocked(ProcessRecord app) {
2612        int lrui = mLruProcesses.lastIndexOf(app);
2613        if (lrui >= 0) {
2614            if (lrui <= mLruProcessActivityStart) {
2615                mLruProcessActivityStart--;
2616            }
2617            if (lrui <= mLruProcessServiceStart) {
2618                mLruProcessServiceStart--;
2619            }
2620            mLruProcesses.remove(lrui);
2621        }
2622    }
2623
2624    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2625            ProcessRecord client) {
2626        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2627                || app.treatLikeActivity;
2628        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2629        if (!activityChange && hasActivity) {
2630            // The process has activities, so we are only allowing activity-based adjustments
2631            // to move it.  It should be kept in the front of the list with other
2632            // processes that have activities, and we don't want those to change their
2633            // order except due to activity operations.
2634            return;
2635        }
2636
2637        mLruSeq++;
2638        final long now = SystemClock.uptimeMillis();
2639        app.lastActivityTime = now;
2640
2641        // First a quick reject: if the app is already at the position we will
2642        // put it, then there is nothing to do.
2643        if (hasActivity) {
2644            final int N = mLruProcesses.size();
2645            if (N > 0 && mLruProcesses.get(N-1) == app) {
2646                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2647                return;
2648            }
2649        } else {
2650            if (mLruProcessServiceStart > 0
2651                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2652                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2653                return;
2654            }
2655        }
2656
2657        int lrui = mLruProcesses.lastIndexOf(app);
2658
2659        if (app.persistent && lrui >= 0) {
2660            // We don't care about the position of persistent processes, as long as
2661            // they are in the list.
2662            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2663            return;
2664        }
2665
2666        /* In progress: compute new position first, so we can avoid doing work
2667           if the process is not actually going to move.  Not yet working.
2668        int addIndex;
2669        int nextIndex;
2670        boolean inActivity = false, inService = false;
2671        if (hasActivity) {
2672            // Process has activities, put it at the very tipsy-top.
2673            addIndex = mLruProcesses.size();
2674            nextIndex = mLruProcessServiceStart;
2675            inActivity = true;
2676        } else if (hasService) {
2677            // Process has services, put it at the top of the service list.
2678            addIndex = mLruProcessActivityStart;
2679            nextIndex = mLruProcessServiceStart;
2680            inActivity = true;
2681            inService = true;
2682        } else  {
2683            // Process not otherwise of interest, it goes to the top of the non-service area.
2684            addIndex = mLruProcessServiceStart;
2685            if (client != null) {
2686                int clientIndex = mLruProcesses.lastIndexOf(client);
2687                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2688                        + app);
2689                if (clientIndex >= 0 && addIndex > clientIndex) {
2690                    addIndex = clientIndex;
2691                }
2692            }
2693            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2694        }
2695
2696        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2697                + mLruProcessActivityStart + "): " + app);
2698        */
2699
2700        if (lrui >= 0) {
2701            if (lrui < mLruProcessActivityStart) {
2702                mLruProcessActivityStart--;
2703            }
2704            if (lrui < mLruProcessServiceStart) {
2705                mLruProcessServiceStart--;
2706            }
2707            /*
2708            if (addIndex > lrui) {
2709                addIndex--;
2710            }
2711            if (nextIndex > lrui) {
2712                nextIndex--;
2713            }
2714            */
2715            mLruProcesses.remove(lrui);
2716        }
2717
2718        /*
2719        mLruProcesses.add(addIndex, app);
2720        if (inActivity) {
2721            mLruProcessActivityStart++;
2722        }
2723        if (inService) {
2724            mLruProcessActivityStart++;
2725        }
2726        */
2727
2728        int nextIndex;
2729        if (hasActivity) {
2730            final int N = mLruProcesses.size();
2731            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2732                // Process doesn't have activities, but has clients with
2733                // activities...  move it up, but one below the top (the top
2734                // should always have a real activity).
2735                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2736                mLruProcesses.add(N-1, app);
2737                // To keep it from spamming the LRU list (by making a bunch of clients),
2738                // we will push down any other entries owned by the app.
2739                final int uid = app.info.uid;
2740                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2741                    ProcessRecord subProc = mLruProcesses.get(i);
2742                    if (subProc.info.uid == uid) {
2743                        // We want to push this one down the list.  If the process after
2744                        // it is for the same uid, however, don't do so, because we don't
2745                        // want them internally to be re-ordered.
2746                        if (mLruProcesses.get(i-1).info.uid != uid) {
2747                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2748                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2749                            ProcessRecord tmp = mLruProcesses.get(i);
2750                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2751                            mLruProcesses.set(i-1, tmp);
2752                            i--;
2753                        }
2754                    } else {
2755                        // A gap, we can stop here.
2756                        break;
2757                    }
2758                }
2759            } else {
2760                // Process has activities, put it at the very tipsy-top.
2761                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2762                mLruProcesses.add(app);
2763            }
2764            nextIndex = mLruProcessServiceStart;
2765        } else if (hasService) {
2766            // Process has services, put it at the top of the service list.
2767            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2768            mLruProcesses.add(mLruProcessActivityStart, app);
2769            nextIndex = mLruProcessServiceStart;
2770            mLruProcessActivityStart++;
2771        } else  {
2772            // Process not otherwise of interest, it goes to the top of the non-service area.
2773            int index = mLruProcessServiceStart;
2774            if (client != null) {
2775                // If there is a client, don't allow the process to be moved up higher
2776                // in the list than that client.
2777                int clientIndex = mLruProcesses.lastIndexOf(client);
2778                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2779                        + " when updating " + app);
2780                if (clientIndex <= lrui) {
2781                    // Don't allow the client index restriction to push it down farther in the
2782                    // list than it already is.
2783                    clientIndex = lrui;
2784                }
2785                if (clientIndex >= 0 && index > clientIndex) {
2786                    index = clientIndex;
2787                }
2788            }
2789            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2790            mLruProcesses.add(index, app);
2791            nextIndex = index-1;
2792            mLruProcessActivityStart++;
2793            mLruProcessServiceStart++;
2794        }
2795
2796        // If the app is currently using a content provider or service,
2797        // bump those processes as well.
2798        for (int j=app.connections.size()-1; j>=0; j--) {
2799            ConnectionRecord cr = app.connections.valueAt(j);
2800            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2801                    && cr.binding.service.app != null
2802                    && cr.binding.service.app.lruSeq != mLruSeq
2803                    && !cr.binding.service.app.persistent) {
2804                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2805                        "service connection", cr, app);
2806            }
2807        }
2808        for (int j=app.conProviders.size()-1; j>=0; j--) {
2809            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2810            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2811                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2812                        "provider reference", cpr, app);
2813            }
2814        }
2815    }
2816
2817    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2818        if (uid == Process.SYSTEM_UID) {
2819            // The system gets to run in any process.  If there are multiple
2820            // processes with the same uid, just pick the first (this
2821            // should never happen).
2822            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2823            if (procs == null) return null;
2824            final int N = procs.size();
2825            for (int i = 0; i < N; i++) {
2826                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2827            }
2828        }
2829        ProcessRecord proc = mProcessNames.get(processName, uid);
2830        if (false && proc != null && !keepIfLarge
2831                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2832                && proc.lastCachedPss >= 4000) {
2833            // Turn this condition on to cause killing to happen regularly, for testing.
2834            if (proc.baseProcessTracker != null) {
2835                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2836            }
2837            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2838        } else if (proc != null && !keepIfLarge
2839                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2840                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2841            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2842            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2843                if (proc.baseProcessTracker != null) {
2844                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2845                }
2846                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2847            }
2848        }
2849        return proc;
2850    }
2851
2852    void ensurePackageDexOpt(String packageName) {
2853        IPackageManager pm = AppGlobals.getPackageManager();
2854        try {
2855            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2856                mDidDexOpt = true;
2857            }
2858        } catch (RemoteException e) {
2859        }
2860    }
2861
2862    boolean isNextTransitionForward() {
2863        int transit = mWindowManager.getPendingAppTransition();
2864        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2865                || transit == AppTransition.TRANSIT_TASK_OPEN
2866                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2867    }
2868
2869    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2870            String processName, String abiOverride, int uid, Runnable crashHandler) {
2871        synchronized(this) {
2872            ApplicationInfo info = new ApplicationInfo();
2873            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2874            // For isolated processes, the former contains the parent's uid and the latter the
2875            // actual uid of the isolated process.
2876            // In the special case introduced by this method (which is, starting an isolated
2877            // process directly from the SystemServer without an actual parent app process) the
2878            // closest thing to a parent's uid is SYSTEM_UID.
2879            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2880            // the |isolated| logic in the ProcessRecord constructor.
2881            info.uid = Process.SYSTEM_UID;
2882            info.processName = processName;
2883            info.className = entryPoint;
2884            info.packageName = "android";
2885            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2886                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2887                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2888                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2889                    crashHandler);
2890            return proc != null ? proc.pid : 0;
2891        }
2892    }
2893
2894    final ProcessRecord startProcessLocked(String processName,
2895            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2896            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2897            boolean isolated, boolean keepIfLarge) {
2898        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2899                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2900                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2901                null /* crashHandler */);
2902    }
2903
2904    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2905            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2906            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2907            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2908        long startTime = SystemClock.elapsedRealtime();
2909        ProcessRecord app;
2910        if (!isolated) {
2911            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2912            checkTime(startTime, "startProcess: after getProcessRecord");
2913        } else {
2914            // If this is an isolated process, it can't re-use an existing process.
2915            app = null;
2916        }
2917        // We don't have to do anything more if:
2918        // (1) There is an existing application record; and
2919        // (2) The caller doesn't think it is dead, OR there is no thread
2920        //     object attached to it so we know it couldn't have crashed; and
2921        // (3) There is a pid assigned to it, so it is either starting or
2922        //     already running.
2923        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2924                + " app=" + app + " knownToBeDead=" + knownToBeDead
2925                + " thread=" + (app != null ? app.thread : null)
2926                + " pid=" + (app != null ? app.pid : -1));
2927        if (app != null && app.pid > 0) {
2928            if (!knownToBeDead || app.thread == null) {
2929                // We already have the app running, or are waiting for it to
2930                // come up (we have a pid but not yet its thread), so keep it.
2931                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2932                // If this is a new package in the process, add the package to the list
2933                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2934                checkTime(startTime, "startProcess: done, added package to proc");
2935                return app;
2936            }
2937
2938            // An application record is attached to a previous process,
2939            // clean it up now.
2940            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2941            checkTime(startTime, "startProcess: bad proc running, killing");
2942            Process.killProcessGroup(app.info.uid, app.pid);
2943            handleAppDiedLocked(app, true, true);
2944            checkTime(startTime, "startProcess: done killing old proc");
2945        }
2946
2947        String hostingNameStr = hostingName != null
2948                ? hostingName.flattenToShortString() : null;
2949
2950        if (!isolated) {
2951            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2952                // If we are in the background, then check to see if this process
2953                // is bad.  If so, we will just silently fail.
2954                if (mBadProcesses.get(info.processName, info.uid) != null) {
2955                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2956                            + "/" + info.processName);
2957                    return null;
2958                }
2959            } else {
2960                // When the user is explicitly starting a process, then clear its
2961                // crash count so that we won't make it bad until they see at
2962                // least one crash dialog again, and make the process good again
2963                // if it had been bad.
2964                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2965                        + "/" + info.processName);
2966                mProcessCrashTimes.remove(info.processName, info.uid);
2967                if (mBadProcesses.get(info.processName, info.uid) != null) {
2968                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2969                            UserHandle.getUserId(info.uid), info.uid,
2970                            info.processName);
2971                    mBadProcesses.remove(info.processName, info.uid);
2972                    if (app != null) {
2973                        app.bad = false;
2974                    }
2975                }
2976            }
2977        }
2978
2979        if (app == null) {
2980            checkTime(startTime, "startProcess: creating new process record");
2981            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2982            app.crashHandler = crashHandler;
2983            if (app == null) {
2984                Slog.w(TAG, "Failed making new process record for "
2985                        + processName + "/" + info.uid + " isolated=" + isolated);
2986                return null;
2987            }
2988            mProcessNames.put(processName, app.uid, app);
2989            if (isolated) {
2990                mIsolatedProcesses.put(app.uid, app);
2991            }
2992            checkTime(startTime, "startProcess: done creating new process record");
2993        } else {
2994            // If this is a new package in the process, add the package to the list
2995            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2996            checkTime(startTime, "startProcess: added package to existing proc");
2997        }
2998
2999        // If the system is not ready yet, then hold off on starting this
3000        // process until it is.
3001        if (!mProcessesReady
3002                && !isAllowedWhileBooting(info)
3003                && !allowWhileBooting) {
3004            if (!mProcessesOnHold.contains(app)) {
3005                mProcessesOnHold.add(app);
3006            }
3007            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3008            checkTime(startTime, "startProcess: returning with proc on hold");
3009            return app;
3010        }
3011
3012        checkTime(startTime, "startProcess: stepping in to startProcess");
3013        startProcessLocked(
3014                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3015        checkTime(startTime, "startProcess: done starting proc!");
3016        return (app.pid != 0) ? app : null;
3017    }
3018
3019    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3020        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3021    }
3022
3023    private final void startProcessLocked(ProcessRecord app,
3024            String hostingType, String hostingNameStr) {
3025        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3026                null /* entryPoint */, null /* entryPointArgs */);
3027    }
3028
3029    private final void startProcessLocked(ProcessRecord app, String hostingType,
3030            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3031        long startTime = SystemClock.elapsedRealtime();
3032        if (app.pid > 0 && app.pid != MY_PID) {
3033            checkTime(startTime, "startProcess: removing from pids map");
3034            synchronized (mPidsSelfLocked) {
3035                mPidsSelfLocked.remove(app.pid);
3036                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3037            }
3038            checkTime(startTime, "startProcess: done removing from pids map");
3039            app.setPid(0);
3040        }
3041
3042        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3043                "startProcessLocked removing on hold: " + app);
3044        mProcessesOnHold.remove(app);
3045
3046        checkTime(startTime, "startProcess: starting to update cpu stats");
3047        updateCpuStats();
3048        checkTime(startTime, "startProcess: done updating cpu stats");
3049
3050        try {
3051            int uid = app.uid;
3052
3053            int[] gids = null;
3054            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3055            if (!app.isolated) {
3056                int[] permGids = null;
3057                try {
3058                    checkTime(startTime, "startProcess: getting gids from package manager");
3059                    final PackageManager pm = mContext.getPackageManager();
3060                    permGids = pm.getPackageGids(app.info.packageName);
3061
3062                    if (Environment.isExternalStorageEmulated()) {
3063                        checkTime(startTime, "startProcess: checking external storage perm");
3064                        if (pm.checkPermission(
3065                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3066                                app.info.packageName) == PERMISSION_GRANTED) {
3067                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3068                        } else {
3069                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3070                        }
3071                    }
3072                } catch (PackageManager.NameNotFoundException e) {
3073                    Slog.w(TAG, "Unable to retrieve gids", e);
3074                }
3075
3076                /*
3077                 * Add shared application and profile GIDs so applications can share some
3078                 * resources like shared libraries and access user-wide resources
3079                 */
3080                if (permGids == null) {
3081                    gids = new int[2];
3082                } else {
3083                    gids = new int[permGids.length + 2];
3084                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3085                }
3086                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3087                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3088            }
3089            checkTime(startTime, "startProcess: building args");
3090            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3091                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3092                        && mTopComponent != null
3093                        && app.processName.equals(mTopComponent.getPackageName())) {
3094                    uid = 0;
3095                }
3096                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3097                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3098                    uid = 0;
3099                }
3100            }
3101            int debugFlags = 0;
3102            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3103                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3104                // Also turn on CheckJNI for debuggable apps. It's quite
3105                // awkward to turn on otherwise.
3106                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3107            }
3108            // Run the app in safe mode if its manifest requests so or the
3109            // system is booted in safe mode.
3110            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3111                mSafeMode == true) {
3112                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3113            }
3114            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3115                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3116            }
3117            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3118                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3119            }
3120            if ("1".equals(SystemProperties.get("debug.assert"))) {
3121                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3122            }
3123
3124            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3125            if (requiredAbi == null) {
3126                requiredAbi = Build.SUPPORTED_ABIS[0];
3127            }
3128
3129            String instructionSet = null;
3130            if (app.info.primaryCpuAbi != null) {
3131                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3132            }
3133
3134            // Start the process.  It will either succeed and return a result containing
3135            // the PID of the new process, or else throw a RuntimeException.
3136            boolean isActivityProcess = (entryPoint == null);
3137            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3138            checkTime(startTime, "startProcess: asking zygote to start proc");
3139            Process.ProcessStartResult startResult = Process.start(entryPoint,
3140                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3141                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3142                    entryPointArgs);
3143            checkTime(startTime, "startProcess: returned from zygote!");
3144
3145            if (app.isolated) {
3146                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3147            }
3148            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3149            checkTime(startTime, "startProcess: done updating battery stats");
3150
3151            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3152                    UserHandle.getUserId(uid), startResult.pid, uid,
3153                    app.processName, hostingType,
3154                    hostingNameStr != null ? hostingNameStr : "");
3155
3156            if (app.persistent) {
3157                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3158            }
3159
3160            checkTime(startTime, "startProcess: building log message");
3161            StringBuilder buf = mStringBuilder;
3162            buf.setLength(0);
3163            buf.append("Start proc ");
3164            buf.append(app.processName);
3165            if (!isActivityProcess) {
3166                buf.append(" [");
3167                buf.append(entryPoint);
3168                buf.append("]");
3169            }
3170            buf.append(" for ");
3171            buf.append(hostingType);
3172            if (hostingNameStr != null) {
3173                buf.append(" ");
3174                buf.append(hostingNameStr);
3175            }
3176            buf.append(": pid=");
3177            buf.append(startResult.pid);
3178            buf.append(" uid=");
3179            buf.append(uid);
3180            buf.append(" gids={");
3181            if (gids != null) {
3182                for (int gi=0; gi<gids.length; gi++) {
3183                    if (gi != 0) buf.append(", ");
3184                    buf.append(gids[gi]);
3185
3186                }
3187            }
3188            buf.append("}");
3189            if (requiredAbi != null) {
3190                buf.append(" abi=");
3191                buf.append(requiredAbi);
3192            }
3193            Slog.i(TAG, buf.toString());
3194            app.setPid(startResult.pid);
3195            app.usingWrapper = startResult.usingWrapper;
3196            app.removed = false;
3197            app.killedByAm = false;
3198            checkTime(startTime, "startProcess: starting to update pids map");
3199            synchronized (mPidsSelfLocked) {
3200                this.mPidsSelfLocked.put(startResult.pid, app);
3201                if (isActivityProcess) {
3202                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3203                    msg.obj = app;
3204                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3205                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3206                }
3207            }
3208            checkTime(startTime, "startProcess: done updating pids map");
3209        } catch (RuntimeException e) {
3210            // XXX do better error recovery.
3211            app.setPid(0);
3212            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3213            if (app.isolated) {
3214                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3215            }
3216            Slog.e(TAG, "Failure starting process " + app.processName, e);
3217        }
3218    }
3219
3220    void updateUsageStats(ActivityRecord component, boolean resumed) {
3221        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3222        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3223        if (resumed) {
3224            if (mUsageStatsService != null) {
3225                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3226                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3227            }
3228            synchronized (stats) {
3229                stats.noteActivityResumedLocked(component.app.uid);
3230            }
3231        } else {
3232            if (mUsageStatsService != null) {
3233                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3234                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3235            }
3236            synchronized (stats) {
3237                stats.noteActivityPausedLocked(component.app.uid);
3238            }
3239        }
3240    }
3241
3242    Intent getHomeIntent() {
3243        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3244        intent.setComponent(mTopComponent);
3245        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3246            intent.addCategory(Intent.CATEGORY_HOME);
3247        }
3248        return intent;
3249    }
3250
3251    boolean startHomeActivityLocked(int userId) {
3252        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3253                && mTopAction == null) {
3254            // We are running in factory test mode, but unable to find
3255            // the factory test app, so just sit around displaying the
3256            // error message and don't try to start anything.
3257            return false;
3258        }
3259        Intent intent = getHomeIntent();
3260        ActivityInfo aInfo =
3261            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3262        if (aInfo != null) {
3263            intent.setComponent(new ComponentName(
3264                    aInfo.applicationInfo.packageName, aInfo.name));
3265            // Don't do this if the home app is currently being
3266            // instrumented.
3267            aInfo = new ActivityInfo(aInfo);
3268            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3269            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3270                    aInfo.applicationInfo.uid, true);
3271            if (app == null || app.instrumentationClass == null) {
3272                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3273                mStackSupervisor.startHomeActivity(intent, aInfo);
3274            }
3275        }
3276
3277        return true;
3278    }
3279
3280    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3281        ActivityInfo ai = null;
3282        ComponentName comp = intent.getComponent();
3283        try {
3284            if (comp != null) {
3285                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3286            } else {
3287                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3288                        intent,
3289                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3290                            flags, userId);
3291
3292                if (info != null) {
3293                    ai = info.activityInfo;
3294                }
3295            }
3296        } catch (RemoteException e) {
3297            // ignore
3298        }
3299
3300        return ai;
3301    }
3302
3303    /**
3304     * Starts the "new version setup screen" if appropriate.
3305     */
3306    void startSetupActivityLocked() {
3307        // Only do this once per boot.
3308        if (mCheckedForSetup) {
3309            return;
3310        }
3311
3312        // We will show this screen if the current one is a different
3313        // version than the last one shown, and we are not running in
3314        // low-level factory test mode.
3315        final ContentResolver resolver = mContext.getContentResolver();
3316        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3317                Settings.Global.getInt(resolver,
3318                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3319            mCheckedForSetup = true;
3320
3321            // See if we should be showing the platform update setup UI.
3322            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3323            List<ResolveInfo> ris = mContext.getPackageManager()
3324                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3325
3326            // We don't allow third party apps to replace this.
3327            ResolveInfo ri = null;
3328            for (int i=0; ris != null && i<ris.size(); i++) {
3329                if ((ris.get(i).activityInfo.applicationInfo.flags
3330                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3331                    ri = ris.get(i);
3332                    break;
3333                }
3334            }
3335
3336            if (ri != null) {
3337                String vers = ri.activityInfo.metaData != null
3338                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3339                        : null;
3340                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3341                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3342                            Intent.METADATA_SETUP_VERSION);
3343                }
3344                String lastVers = Settings.Secure.getString(
3345                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3346                if (vers != null && !vers.equals(lastVers)) {
3347                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3348                    intent.setComponent(new ComponentName(
3349                            ri.activityInfo.packageName, ri.activityInfo.name));
3350                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3351                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3352                            null);
3353                }
3354            }
3355        }
3356    }
3357
3358    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3359        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3360    }
3361
3362    void enforceNotIsolatedCaller(String caller) {
3363        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3364            throw new SecurityException("Isolated process not allowed to call " + caller);
3365        }
3366    }
3367
3368    void enforceShellRestriction(String restriction, int userHandle) {
3369        if (Binder.getCallingUid() == Process.SHELL_UID) {
3370            if (userHandle < 0
3371                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3372                throw new SecurityException("Shell does not have permission to access user "
3373                        + userHandle);
3374            }
3375        }
3376    }
3377
3378    @Override
3379    public int getFrontActivityScreenCompatMode() {
3380        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3381        synchronized (this) {
3382            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3383        }
3384    }
3385
3386    @Override
3387    public void setFrontActivityScreenCompatMode(int mode) {
3388        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3389                "setFrontActivityScreenCompatMode");
3390        synchronized (this) {
3391            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3392        }
3393    }
3394
3395    @Override
3396    public int getPackageScreenCompatMode(String packageName) {
3397        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3398        synchronized (this) {
3399            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3400        }
3401    }
3402
3403    @Override
3404    public void setPackageScreenCompatMode(String packageName, int mode) {
3405        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3406                "setPackageScreenCompatMode");
3407        synchronized (this) {
3408            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3409        }
3410    }
3411
3412    @Override
3413    public boolean getPackageAskScreenCompat(String packageName) {
3414        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3415        synchronized (this) {
3416            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3417        }
3418    }
3419
3420    @Override
3421    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3422        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3423                "setPackageAskScreenCompat");
3424        synchronized (this) {
3425            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3426        }
3427    }
3428
3429    private void dispatchProcessesChanged() {
3430        int N;
3431        synchronized (this) {
3432            N = mPendingProcessChanges.size();
3433            if (mActiveProcessChanges.length < N) {
3434                mActiveProcessChanges = new ProcessChangeItem[N];
3435            }
3436            mPendingProcessChanges.toArray(mActiveProcessChanges);
3437            mAvailProcessChanges.addAll(mPendingProcessChanges);
3438            mPendingProcessChanges.clear();
3439            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3440        }
3441
3442        int i = mProcessObservers.beginBroadcast();
3443        while (i > 0) {
3444            i--;
3445            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3446            if (observer != null) {
3447                try {
3448                    for (int j=0; j<N; j++) {
3449                        ProcessChangeItem item = mActiveProcessChanges[j];
3450                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3451                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3452                                    + item.pid + " uid=" + item.uid + ": "
3453                                    + item.foregroundActivities);
3454                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3455                                    item.foregroundActivities);
3456                        }
3457                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3458                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3459                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3460                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3461                        }
3462                    }
3463                } catch (RemoteException e) {
3464                }
3465            }
3466        }
3467        mProcessObservers.finishBroadcast();
3468    }
3469
3470    private void dispatchProcessDied(int pid, int uid) {
3471        int i = mProcessObservers.beginBroadcast();
3472        while (i > 0) {
3473            i--;
3474            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3475            if (observer != null) {
3476                try {
3477                    observer.onProcessDied(pid, uid);
3478                } catch (RemoteException e) {
3479                }
3480            }
3481        }
3482        mProcessObservers.finishBroadcast();
3483    }
3484
3485    @Override
3486    public final int startActivity(IApplicationThread caller, String callingPackage,
3487            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3488            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3489        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3490            resultWho, requestCode, startFlags, profilerInfo, options,
3491            UserHandle.getCallingUserId());
3492    }
3493
3494    @Override
3495    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3496            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3497            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3498        enforceNotIsolatedCaller("startActivity");
3499        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3500                false, ALLOW_FULL_ONLY, "startActivity", null);
3501        // TODO: Switch to user app stacks here.
3502        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3503                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3504                profilerInfo, null, null, options, userId, null, null);
3505    }
3506
3507    @Override
3508    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3509            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3510            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3511
3512        // This is very dangerous -- it allows you to perform a start activity (including
3513        // permission grants) as any app that may launch one of your own activities.  So
3514        // we will only allow this to be done from activities that are part of the core framework,
3515        // and then only when they are running as the system.
3516        final ActivityRecord sourceRecord;
3517        final int targetUid;
3518        final String targetPackage;
3519        synchronized (this) {
3520            if (resultTo == null) {
3521                throw new SecurityException("Must be called from an activity");
3522            }
3523            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3524            if (sourceRecord == null) {
3525                throw new SecurityException("Called with bad activity token: " + resultTo);
3526            }
3527            if (!sourceRecord.info.packageName.equals("android")) {
3528                throw new SecurityException(
3529                        "Must be called from an activity that is declared in the android package");
3530            }
3531            if (sourceRecord.app == null) {
3532                throw new SecurityException("Called without a process attached to activity");
3533            }
3534            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3535                // This is still okay, as long as this activity is running under the
3536                // uid of the original calling activity.
3537                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3538                    throw new SecurityException(
3539                            "Calling activity in uid " + sourceRecord.app.uid
3540                                    + " must be system uid or original calling uid "
3541                                    + sourceRecord.launchedFromUid);
3542                }
3543            }
3544            targetUid = sourceRecord.launchedFromUid;
3545            targetPackage = sourceRecord.launchedFromPackage;
3546        }
3547
3548        // TODO: Switch to user app stacks here.
3549        try {
3550            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3551                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3552                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3553            return ret;
3554        } catch (SecurityException e) {
3555            // XXX need to figure out how to propagate to original app.
3556            // A SecurityException here is generally actually a fault of the original
3557            // calling activity (such as a fairly granting permissions), so propagate it
3558            // back to them.
3559            /*
3560            StringBuilder msg = new StringBuilder();
3561            msg.append("While launching");
3562            msg.append(intent.toString());
3563            msg.append(": ");
3564            msg.append(e.getMessage());
3565            */
3566            throw e;
3567        }
3568    }
3569
3570    @Override
3571    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3572            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3573            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3574        enforceNotIsolatedCaller("startActivityAndWait");
3575        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3576                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3577        WaitResult res = new WaitResult();
3578        // TODO: Switch to user app stacks here.
3579        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3580                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3581                options, userId, null, null);
3582        return res;
3583    }
3584
3585    @Override
3586    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3587            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3588            int startFlags, Configuration config, Bundle options, int userId) {
3589        enforceNotIsolatedCaller("startActivityWithConfig");
3590        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3591                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3592        // TODO: Switch to user app stacks here.
3593        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3594                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3595                null, null, config, options, userId, null, null);
3596        return ret;
3597    }
3598
3599    @Override
3600    public int startActivityIntentSender(IApplicationThread caller,
3601            IntentSender intent, Intent fillInIntent, String resolvedType,
3602            IBinder resultTo, String resultWho, int requestCode,
3603            int flagsMask, int flagsValues, Bundle options) {
3604        enforceNotIsolatedCaller("startActivityIntentSender");
3605        // Refuse possible leaked file descriptors
3606        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3607            throw new IllegalArgumentException("File descriptors passed in Intent");
3608        }
3609
3610        IIntentSender sender = intent.getTarget();
3611        if (!(sender instanceof PendingIntentRecord)) {
3612            throw new IllegalArgumentException("Bad PendingIntent object");
3613        }
3614
3615        PendingIntentRecord pir = (PendingIntentRecord)sender;
3616
3617        synchronized (this) {
3618            // If this is coming from the currently resumed activity, it is
3619            // effectively saying that app switches are allowed at this point.
3620            final ActivityStack stack = getFocusedStack();
3621            if (stack.mResumedActivity != null &&
3622                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3623                mAppSwitchesAllowedTime = 0;
3624            }
3625        }
3626        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3627                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3628        return ret;
3629    }
3630
3631    @Override
3632    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3633            Intent intent, String resolvedType, IVoiceInteractionSession session,
3634            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3635            Bundle options, int userId) {
3636        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3637                != PackageManager.PERMISSION_GRANTED) {
3638            String msg = "Permission Denial: startVoiceActivity() from pid="
3639                    + Binder.getCallingPid()
3640                    + ", uid=" + Binder.getCallingUid()
3641                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3642            Slog.w(TAG, msg);
3643            throw new SecurityException(msg);
3644        }
3645        if (session == null || interactor == null) {
3646            throw new NullPointerException("null session or interactor");
3647        }
3648        userId = handleIncomingUser(callingPid, callingUid, userId,
3649                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3650        // TODO: Switch to user app stacks here.
3651        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3652                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3653                null, options, userId, null, null);
3654    }
3655
3656    @Override
3657    public boolean startNextMatchingActivity(IBinder callingActivity,
3658            Intent intent, Bundle options) {
3659        // Refuse possible leaked file descriptors
3660        if (intent != null && intent.hasFileDescriptors() == true) {
3661            throw new IllegalArgumentException("File descriptors passed in Intent");
3662        }
3663
3664        synchronized (this) {
3665            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3666            if (r == null) {
3667                ActivityOptions.abort(options);
3668                return false;
3669            }
3670            if (r.app == null || r.app.thread == null) {
3671                // The caller is not running...  d'oh!
3672                ActivityOptions.abort(options);
3673                return false;
3674            }
3675            intent = new Intent(intent);
3676            // The caller is not allowed to change the data.
3677            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3678            // And we are resetting to find the next component...
3679            intent.setComponent(null);
3680
3681            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3682
3683            ActivityInfo aInfo = null;
3684            try {
3685                List<ResolveInfo> resolves =
3686                    AppGlobals.getPackageManager().queryIntentActivities(
3687                            intent, r.resolvedType,
3688                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3689                            UserHandle.getCallingUserId());
3690
3691                // Look for the original activity in the list...
3692                final int N = resolves != null ? resolves.size() : 0;
3693                for (int i=0; i<N; i++) {
3694                    ResolveInfo rInfo = resolves.get(i);
3695                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3696                            && rInfo.activityInfo.name.equals(r.info.name)) {
3697                        // We found the current one...  the next matching is
3698                        // after it.
3699                        i++;
3700                        if (i<N) {
3701                            aInfo = resolves.get(i).activityInfo;
3702                        }
3703                        if (debug) {
3704                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3705                                    + "/" + r.info.name);
3706                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3707                                    + "/" + aInfo.name);
3708                        }
3709                        break;
3710                    }
3711                }
3712            } catch (RemoteException e) {
3713            }
3714
3715            if (aInfo == null) {
3716                // Nobody who is next!
3717                ActivityOptions.abort(options);
3718                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3719                return false;
3720            }
3721
3722            intent.setComponent(new ComponentName(
3723                    aInfo.applicationInfo.packageName, aInfo.name));
3724            intent.setFlags(intent.getFlags()&~(
3725                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3726                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3727                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3728                    Intent.FLAG_ACTIVITY_NEW_TASK));
3729
3730            // Okay now we need to start the new activity, replacing the
3731            // currently running activity.  This is a little tricky because
3732            // we want to start the new one as if the current one is finished,
3733            // but not finish the current one first so that there is no flicker.
3734            // And thus...
3735            final boolean wasFinishing = r.finishing;
3736            r.finishing = true;
3737
3738            // Propagate reply information over to the new activity.
3739            final ActivityRecord resultTo = r.resultTo;
3740            final String resultWho = r.resultWho;
3741            final int requestCode = r.requestCode;
3742            r.resultTo = null;
3743            if (resultTo != null) {
3744                resultTo.removeResultsLocked(r, resultWho, requestCode);
3745            }
3746
3747            final long origId = Binder.clearCallingIdentity();
3748            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3749                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3750                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3751                    options, false, null, null, null);
3752            Binder.restoreCallingIdentity(origId);
3753
3754            r.finishing = wasFinishing;
3755            if (res != ActivityManager.START_SUCCESS) {
3756                return false;
3757            }
3758            return true;
3759        }
3760    }
3761
3762    @Override
3763    public final int startActivityFromRecents(int taskId, Bundle options) {
3764        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3765            String msg = "Permission Denial: startActivityFromRecents called without " +
3766                    START_TASKS_FROM_RECENTS;
3767            Slog.w(TAG, msg);
3768            throw new SecurityException(msg);
3769        }
3770        return startActivityFromRecentsInner(taskId, options);
3771    }
3772
3773    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3774        final TaskRecord task;
3775        final int callingUid;
3776        final String callingPackage;
3777        final Intent intent;
3778        final int userId;
3779        synchronized (this) {
3780            task = recentTaskForIdLocked(taskId);
3781            if (task == null) {
3782                throw new IllegalArgumentException("Task " + taskId + " not found.");
3783            }
3784            callingUid = task.mCallingUid;
3785            callingPackage = task.mCallingPackage;
3786            intent = task.intent;
3787            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3788            userId = task.userId;
3789        }
3790        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3791                options, userId, null, task);
3792    }
3793
3794    final int startActivityInPackage(int uid, String callingPackage,
3795            Intent intent, String resolvedType, IBinder resultTo,
3796            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3797            IActivityContainer container, TaskRecord inTask) {
3798
3799        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3800                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3801
3802        // TODO: Switch to user app stacks here.
3803        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3804                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3805                null, null, null, options, userId, container, inTask);
3806        return ret;
3807    }
3808
3809    @Override
3810    public final int startActivities(IApplicationThread caller, String callingPackage,
3811            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3812            int userId) {
3813        enforceNotIsolatedCaller("startActivities");
3814        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3815                false, ALLOW_FULL_ONLY, "startActivity", null);
3816        // TODO: Switch to user app stacks here.
3817        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3818                resolvedTypes, resultTo, options, userId);
3819        return ret;
3820    }
3821
3822    final int startActivitiesInPackage(int uid, String callingPackage,
3823            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3824            Bundle options, int userId) {
3825
3826        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3827                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3828        // TODO: Switch to user app stacks here.
3829        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3830                resultTo, options, userId);
3831        return ret;
3832    }
3833
3834    //explicitly remove thd old information in mRecentTasks when removing existing user.
3835    private void removeRecentTasksForUserLocked(int userId) {
3836        if(userId <= 0) {
3837            Slog.i(TAG, "Can't remove recent task on user " + userId);
3838            return;
3839        }
3840
3841        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3842            TaskRecord tr = mRecentTasks.get(i);
3843            if (tr.userId == userId) {
3844                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3845                        + " when finishing user" + userId);
3846                mRecentTasks.remove(i);
3847                tr.removedFromRecents(mTaskPersister);
3848            }
3849        }
3850
3851        // Remove tasks from persistent storage.
3852        mTaskPersister.wakeup(null, true);
3853    }
3854
3855    /**
3856     * Update the recent tasks lists: make sure tasks should still be here (their
3857     * applications / activities still exist), update their availability, fixup ordering
3858     * of affiliations.
3859     */
3860    void cleanupRecentTasksLocked(int userId) {
3861        if (mRecentTasks == null) {
3862            // Happens when called from the packagemanager broadcast before boot.
3863            return;
3864        }
3865
3866        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3867        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3868        final IPackageManager pm = AppGlobals.getPackageManager();
3869        final ActivityInfo dummyAct = new ActivityInfo();
3870        final ApplicationInfo dummyApp = new ApplicationInfo();
3871
3872        int N = mRecentTasks.size();
3873
3874        int[] users = userId == UserHandle.USER_ALL
3875                ? getUsersLocked() : new int[] { userId };
3876        for (int user : users) {
3877            for (int i = 0; i < N; i++) {
3878                TaskRecord task = mRecentTasks.get(i);
3879                if (task.userId != user) {
3880                    // Only look at tasks for the user ID of interest.
3881                    continue;
3882                }
3883                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3884                    // This situation is broken, and we should just get rid of it now.
3885                    mRecentTasks.remove(i);
3886                    task.removedFromRecents(mTaskPersister);
3887                    i--;
3888                    N--;
3889                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3890                    continue;
3891                }
3892                // Check whether this activity is currently available.
3893                if (task.realActivity != null) {
3894                    ActivityInfo ai = availActCache.get(task.realActivity);
3895                    if (ai == null) {
3896                        try {
3897                            ai = pm.getActivityInfo(task.realActivity,
3898                                    PackageManager.GET_UNINSTALLED_PACKAGES
3899                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3900                        } catch (RemoteException e) {
3901                            // Will never happen.
3902                            continue;
3903                        }
3904                        if (ai == null) {
3905                            ai = dummyAct;
3906                        }
3907                        availActCache.put(task.realActivity, ai);
3908                    }
3909                    if (ai == dummyAct) {
3910                        // This could be either because the activity no longer exists, or the
3911                        // app is temporarily gone.  For the former we want to remove the recents
3912                        // entry; for the latter we want to mark it as unavailable.
3913                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3914                        if (app == null) {
3915                            try {
3916                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3917                                        PackageManager.GET_UNINSTALLED_PACKAGES
3918                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3919                            } catch (RemoteException e) {
3920                                // Will never happen.
3921                                continue;
3922                            }
3923                            if (app == null) {
3924                                app = dummyApp;
3925                            }
3926                            availAppCache.put(task.realActivity.getPackageName(), app);
3927                        }
3928                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3929                            // Doesn't exist any more!  Good-bye.
3930                            mRecentTasks.remove(i);
3931                            task.removedFromRecents(mTaskPersister);
3932                            i--;
3933                            N--;
3934                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3935                            continue;
3936                        } else {
3937                            // Otherwise just not available for now.
3938                            if (task.isAvailable) {
3939                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3940                                        + task);
3941                            }
3942                            task.isAvailable = false;
3943                        }
3944                    } else {
3945                        if (!ai.enabled || !ai.applicationInfo.enabled
3946                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3947                            if (task.isAvailable) {
3948                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3949                                        + task + " (enabled=" + ai.enabled + "/"
3950                                        + ai.applicationInfo.enabled +  " flags="
3951                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3952                            }
3953                            task.isAvailable = false;
3954                        } else {
3955                            if (!task.isAvailable) {
3956                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3957                                        + task);
3958                            }
3959                            task.isAvailable = true;
3960                        }
3961                    }
3962                }
3963            }
3964        }
3965
3966        // Verify the affiliate chain for each task.
3967        for (int i = 0; i < N; ) {
3968            TaskRecord task = mRecentTasks.remove(i);
3969            if (mTmpRecents.contains(task)) {
3970                continue;
3971            }
3972            int affiliatedTaskId = task.mAffiliatedTaskId;
3973            while (true) {
3974                TaskRecord next = task.mNextAffiliate;
3975                if (next == null) {
3976                    break;
3977                }
3978                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3979                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3980                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3981                    task.setNextAffiliate(null);
3982                    if (next.mPrevAffiliate == task) {
3983                        next.setPrevAffiliate(null);
3984                    }
3985                    break;
3986                }
3987                if (next.mPrevAffiliate != task) {
3988                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3989                            next.mPrevAffiliate + " task=" + task);
3990                    next.setPrevAffiliate(null);
3991                    task.setNextAffiliate(null);
3992                    break;
3993                }
3994                if (!mRecentTasks.contains(next)) {
3995                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3996                    task.setNextAffiliate(null);
3997                    // We know that next.mPrevAffiliate is always task, from above, so clear
3998                    // its previous affiliate.
3999                    next.setPrevAffiliate(null);
4000                    break;
4001                }
4002                task = next;
4003            }
4004            // task is now the end of the list
4005            do {
4006                mRecentTasks.remove(task);
4007                mRecentTasks.add(i++, task);
4008                mTmpRecents.add(task);
4009                task.inRecents = true;
4010            } while ((task = task.mPrevAffiliate) != null);
4011        }
4012        mTmpRecents.clear();
4013        // mRecentTasks is now in sorted, affiliated order.
4014    }
4015
4016    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4017        int N = mRecentTasks.size();
4018        TaskRecord top = task;
4019        int topIndex = taskIndex;
4020        while (top.mNextAffiliate != null && topIndex > 0) {
4021            top = top.mNextAffiliate;
4022            topIndex--;
4023        }
4024        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4025                + topIndex + " from intial " + taskIndex);
4026        // Find the end of the chain, doing a sanity check along the way.
4027        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4028        int endIndex = topIndex;
4029        TaskRecord prev = top;
4030        while (endIndex < N) {
4031            TaskRecord cur = mRecentTasks.get(endIndex);
4032            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4033                    + endIndex + " " + cur);
4034            if (cur == top) {
4035                // Verify start of the chain.
4036                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4037                    Slog.wtf(TAG, "Bad chain @" + endIndex
4038                            + ": first task has next affiliate: " + prev);
4039                    sane = false;
4040                    break;
4041                }
4042            } else {
4043                // Verify middle of the chain's next points back to the one before.
4044                if (cur.mNextAffiliate != prev
4045                        || cur.mNextAffiliateTaskId != prev.taskId) {
4046                    Slog.wtf(TAG, "Bad chain @" + endIndex
4047                            + ": middle task " + cur + " @" + endIndex
4048                            + " has bad next affiliate "
4049                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4050                            + ", expected " + prev);
4051                    sane = false;
4052                    break;
4053                }
4054            }
4055            if (cur.mPrevAffiliateTaskId == -1) {
4056                // Chain ends here.
4057                if (cur.mPrevAffiliate != null) {
4058                    Slog.wtf(TAG, "Bad chain @" + endIndex
4059                            + ": last task " + cur + " has previous affiliate "
4060                            + cur.mPrevAffiliate);
4061                    sane = false;
4062                }
4063                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4064                break;
4065            } else {
4066                // Verify middle of the chain's prev points to a valid item.
4067                if (cur.mPrevAffiliate == null) {
4068                    Slog.wtf(TAG, "Bad chain @" + endIndex
4069                            + ": task " + cur + " has previous affiliate "
4070                            + cur.mPrevAffiliate + " but should be id "
4071                            + cur.mPrevAffiliate);
4072                    sane = false;
4073                    break;
4074                }
4075            }
4076            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4077                Slog.wtf(TAG, "Bad chain @" + endIndex
4078                        + ": task " + cur + " has affiliated id "
4079                        + cur.mAffiliatedTaskId + " but should be "
4080                        + task.mAffiliatedTaskId);
4081                sane = false;
4082                break;
4083            }
4084            prev = cur;
4085            endIndex++;
4086            if (endIndex >= N) {
4087                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4088                        + ": last task " + prev);
4089                sane = false;
4090                break;
4091            }
4092        }
4093        if (sane) {
4094            if (endIndex < taskIndex) {
4095                Slog.wtf(TAG, "Bad chain @" + endIndex
4096                        + ": did not extend to task " + task + " @" + taskIndex);
4097                sane = false;
4098            }
4099        }
4100        if (sane) {
4101            // All looks good, we can just move all of the affiliated tasks
4102            // to the top.
4103            for (int i=topIndex; i<=endIndex; i++) {
4104                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4105                        + " from " + i + " to " + (i-topIndex));
4106                TaskRecord cur = mRecentTasks.remove(i);
4107                mRecentTasks.add(i-topIndex, cur);
4108            }
4109            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4110                    + " to " + endIndex);
4111            return true;
4112        }
4113
4114        // Whoops, couldn't do it.
4115        return false;
4116    }
4117
4118    final void addRecentTaskLocked(TaskRecord task) {
4119        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4120                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4121
4122        int N = mRecentTasks.size();
4123        // Quick case: check if the top-most recent task is the same.
4124        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4125            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4126            return;
4127        }
4128        // Another quick case: check if this is part of a set of affiliated
4129        // tasks that are at the top.
4130        if (isAffiliated && N > 0 && task.inRecents
4131                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4132            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4133                    + " at top when adding " + task);
4134            return;
4135        }
4136        // Another quick case: never add voice sessions.
4137        if (task.voiceSession != null) {
4138            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4139            return;
4140        }
4141
4142        boolean needAffiliationFix = false;
4143
4144        // Slightly less quick case: the task is already in recents, so all we need
4145        // to do is move it.
4146        if (task.inRecents) {
4147            int taskIndex = mRecentTasks.indexOf(task);
4148            if (taskIndex >= 0) {
4149                if (!isAffiliated) {
4150                    // Simple case: this is not an affiliated task, so we just move it to the front.
4151                    mRecentTasks.remove(taskIndex);
4152                    mRecentTasks.add(0, task);
4153                    notifyTaskPersisterLocked(task, false);
4154                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4155                            + " from " + taskIndex);
4156                    return;
4157                } else {
4158                    // More complicated: need to keep all affiliated tasks together.
4159                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4160                        // All went well.
4161                        return;
4162                    }
4163
4164                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4165                    // everything and then go through our general path of adding a new task.
4166                    needAffiliationFix = true;
4167                }
4168            } else {
4169                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4170                needAffiliationFix = true;
4171            }
4172        }
4173
4174        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4175        trimRecentsForTask(task, true);
4176
4177        N = mRecentTasks.size();
4178        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4179            final TaskRecord tr = mRecentTasks.remove(N - 1);
4180            tr.removedFromRecents(mTaskPersister);
4181            N--;
4182        }
4183        task.inRecents = true;
4184        if (!isAffiliated || needAffiliationFix) {
4185            // If this is a simple non-affiliated task, or we had some failure trying to
4186            // handle it as part of an affilated task, then just place it at the top.
4187            mRecentTasks.add(0, task);
4188        } else if (isAffiliated) {
4189            // If this is a new affiliated task, then move all of the affiliated tasks
4190            // to the front and insert this new one.
4191            TaskRecord other = task.mNextAffiliate;
4192            if (other == null) {
4193                other = task.mPrevAffiliate;
4194            }
4195            if (other != null) {
4196                int otherIndex = mRecentTasks.indexOf(other);
4197                if (otherIndex >= 0) {
4198                    // Insert new task at appropriate location.
4199                    int taskIndex;
4200                    if (other == task.mNextAffiliate) {
4201                        // We found the index of our next affiliation, which is who is
4202                        // before us in the list, so add after that point.
4203                        taskIndex = otherIndex+1;
4204                    } else {
4205                        // We found the index of our previous affiliation, which is who is
4206                        // after us in the list, so add at their position.
4207                        taskIndex = otherIndex;
4208                    }
4209                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4210                            + taskIndex + ": " + task);
4211                    mRecentTasks.add(taskIndex, task);
4212
4213                    // Now move everything to the front.
4214                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4215                        // All went well.
4216                        return;
4217                    }
4218
4219                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4220                    // everything and then go through our general path of adding a new task.
4221                    needAffiliationFix = true;
4222                } else {
4223                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4224                            + other);
4225                    needAffiliationFix = true;
4226                }
4227            } else {
4228                if (DEBUG_RECENTS) Slog.d(TAG,
4229                        "addRecent: adding affiliated task without next/prev:" + task);
4230                needAffiliationFix = true;
4231            }
4232        }
4233        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4234
4235        if (needAffiliationFix) {
4236            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4237            cleanupRecentTasksLocked(task.userId);
4238        }
4239    }
4240
4241    /**
4242     * If needed, remove oldest existing entries in recents that are for the same kind
4243     * of task as the given one.
4244     */
4245    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4246        int N = mRecentTasks.size();
4247        final Intent intent = task.intent;
4248        final boolean document = intent != null && intent.isDocument();
4249
4250        int maxRecents = task.maxRecents - 1;
4251        for (int i=0; i<N; i++) {
4252            final TaskRecord tr = mRecentTasks.get(i);
4253            if (task != tr) {
4254                if (task.userId != tr.userId) {
4255                    continue;
4256                }
4257                if (i > MAX_RECENT_BITMAPS) {
4258                    tr.freeLastThumbnail();
4259                }
4260                final Intent trIntent = tr.intent;
4261                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4262                    (intent == null || !intent.filterEquals(trIntent))) {
4263                    continue;
4264                }
4265                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4266                if (document && trIsDocument) {
4267                    // These are the same document activity (not necessarily the same doc).
4268                    if (maxRecents > 0) {
4269                        --maxRecents;
4270                        continue;
4271                    }
4272                    // Hit the maximum number of documents for this task. Fall through
4273                    // and remove this document from recents.
4274                } else if (document || trIsDocument) {
4275                    // Only one of these is a document. Not the droid we're looking for.
4276                    continue;
4277                }
4278            }
4279
4280            if (!doTrim) {
4281                // If the caller is not actually asking for a trim, just tell them we reached
4282                // a point where the trim would happen.
4283                return i;
4284            }
4285
4286            // Either task and tr are the same or, their affinities match or their intents match
4287            // and neither of them is a document, or they are documents using the same activity
4288            // and their maxRecents has been reached.
4289            tr.disposeThumbnail();
4290            mRecentTasks.remove(i);
4291            if (task != tr) {
4292                tr.removedFromRecents(mTaskPersister);
4293            }
4294            i--;
4295            N--;
4296            if (task.intent == null) {
4297                // If the new recent task we are adding is not fully
4298                // specified, then replace it with the existing recent task.
4299                task = tr;
4300            }
4301            notifyTaskPersisterLocked(tr, false);
4302        }
4303
4304        return -1;
4305    }
4306
4307    @Override
4308    public void reportActivityFullyDrawn(IBinder token) {
4309        synchronized (this) {
4310            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4311            if (r == null) {
4312                return;
4313            }
4314            r.reportFullyDrawnLocked();
4315        }
4316    }
4317
4318    @Override
4319    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4320        synchronized (this) {
4321            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4322            if (r == null) {
4323                return;
4324            }
4325            final long origId = Binder.clearCallingIdentity();
4326            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4327            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4328                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4329            if (config != null) {
4330                r.frozenBeforeDestroy = true;
4331                if (!updateConfigurationLocked(config, r, false, false)) {
4332                    mStackSupervisor.resumeTopActivitiesLocked();
4333                }
4334            }
4335            Binder.restoreCallingIdentity(origId);
4336        }
4337    }
4338
4339    @Override
4340    public int getRequestedOrientation(IBinder token) {
4341        synchronized (this) {
4342            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4343            if (r == null) {
4344                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4345            }
4346            return mWindowManager.getAppOrientation(r.appToken);
4347        }
4348    }
4349
4350    /**
4351     * This is the internal entry point for handling Activity.finish().
4352     *
4353     * @param token The Binder token referencing the Activity we want to finish.
4354     * @param resultCode Result code, if any, from this Activity.
4355     * @param resultData Result data (Intent), if any, from this Activity.
4356     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4357     *            the root Activity in the task.
4358     *
4359     * @return Returns true if the activity successfully finished, or false if it is still running.
4360     */
4361    @Override
4362    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4363            boolean finishTask) {
4364        // Refuse possible leaked file descriptors
4365        if (resultData != null && resultData.hasFileDescriptors() == true) {
4366            throw new IllegalArgumentException("File descriptors passed in Intent");
4367        }
4368
4369        synchronized(this) {
4370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4371            if (r == null) {
4372                return true;
4373            }
4374            // Keep track of the root activity of the task before we finish it
4375            TaskRecord tr = r.task;
4376            ActivityRecord rootR = tr.getRootActivity();
4377            // Do not allow task to finish in Lock Task mode.
4378            if (tr == mStackSupervisor.mLockTaskModeTask) {
4379                if (rootR == r) {
4380                    mStackSupervisor.showLockTaskToast();
4381                    return false;
4382                }
4383            }
4384            if (mController != null) {
4385                // Find the first activity that is not finishing.
4386                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4387                if (next != null) {
4388                    // ask watcher if this is allowed
4389                    boolean resumeOK = true;
4390                    try {
4391                        resumeOK = mController.activityResuming(next.packageName);
4392                    } catch (RemoteException e) {
4393                        mController = null;
4394                        Watchdog.getInstance().setActivityController(null);
4395                    }
4396
4397                    if (!resumeOK) {
4398                        return false;
4399                    }
4400                }
4401            }
4402            final long origId = Binder.clearCallingIdentity();
4403            try {
4404                boolean res;
4405                if (finishTask && r == rootR) {
4406                    // If requested, remove the task that is associated to this activity only if it
4407                    // was the root activity in the task.  The result code and data is ignored because
4408                    // we don't support returning them across task boundaries.
4409                    res = removeTaskByIdLocked(tr.taskId, 0);
4410                } else {
4411                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4412                            resultData, "app-request", true);
4413                }
4414                return res;
4415            } finally {
4416                Binder.restoreCallingIdentity(origId);
4417            }
4418        }
4419    }
4420
4421    @Override
4422    public final void finishHeavyWeightApp() {
4423        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4424                != PackageManager.PERMISSION_GRANTED) {
4425            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4426                    + Binder.getCallingPid()
4427                    + ", uid=" + Binder.getCallingUid()
4428                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4429            Slog.w(TAG, msg);
4430            throw new SecurityException(msg);
4431        }
4432
4433        synchronized(this) {
4434            if (mHeavyWeightProcess == null) {
4435                return;
4436            }
4437
4438            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4439                    mHeavyWeightProcess.activities);
4440            for (int i=0; i<activities.size(); i++) {
4441                ActivityRecord r = activities.get(i);
4442                if (!r.finishing) {
4443                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4444                            null, "finish-heavy", true);
4445                }
4446            }
4447
4448            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4449                    mHeavyWeightProcess.userId, 0));
4450            mHeavyWeightProcess = null;
4451        }
4452    }
4453
4454    @Override
4455    public void crashApplication(int uid, int initialPid, String packageName,
4456            String message) {
4457        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4458                != PackageManager.PERMISSION_GRANTED) {
4459            String msg = "Permission Denial: crashApplication() from pid="
4460                    + Binder.getCallingPid()
4461                    + ", uid=" + Binder.getCallingUid()
4462                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4463            Slog.w(TAG, msg);
4464            throw new SecurityException(msg);
4465        }
4466
4467        synchronized(this) {
4468            ProcessRecord proc = null;
4469
4470            // Figure out which process to kill.  We don't trust that initialPid
4471            // still has any relation to current pids, so must scan through the
4472            // list.
4473            synchronized (mPidsSelfLocked) {
4474                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4475                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4476                    if (p.uid != uid) {
4477                        continue;
4478                    }
4479                    if (p.pid == initialPid) {
4480                        proc = p;
4481                        break;
4482                    }
4483                    if (p.pkgList.containsKey(packageName)) {
4484                        proc = p;
4485                    }
4486                }
4487            }
4488
4489            if (proc == null) {
4490                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4491                        + " initialPid=" + initialPid
4492                        + " packageName=" + packageName);
4493                return;
4494            }
4495
4496            if (proc.thread != null) {
4497                if (proc.pid == Process.myPid()) {
4498                    Log.w(TAG, "crashApplication: trying to crash self!");
4499                    return;
4500                }
4501                long ident = Binder.clearCallingIdentity();
4502                try {
4503                    proc.thread.scheduleCrash(message);
4504                } catch (RemoteException e) {
4505                }
4506                Binder.restoreCallingIdentity(ident);
4507            }
4508        }
4509    }
4510
4511    @Override
4512    public final void finishSubActivity(IBinder token, String resultWho,
4513            int requestCode) {
4514        synchronized(this) {
4515            final long origId = Binder.clearCallingIdentity();
4516            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4517            if (r != null) {
4518                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4519            }
4520            Binder.restoreCallingIdentity(origId);
4521        }
4522    }
4523
4524    @Override
4525    public boolean finishActivityAffinity(IBinder token) {
4526        synchronized(this) {
4527            final long origId = Binder.clearCallingIdentity();
4528            try {
4529                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4530
4531                ActivityRecord rootR = r.task.getRootActivity();
4532                // Do not allow task to finish in Lock Task mode.
4533                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4534                    if (rootR == r) {
4535                        mStackSupervisor.showLockTaskToast();
4536                        return false;
4537                    }
4538                }
4539                boolean res = false;
4540                if (r != null) {
4541                    res = r.task.stack.finishActivityAffinityLocked(r);
4542                }
4543                return res;
4544            } finally {
4545                Binder.restoreCallingIdentity(origId);
4546            }
4547        }
4548    }
4549
4550    @Override
4551    public void finishVoiceTask(IVoiceInteractionSession session) {
4552        synchronized(this) {
4553            final long origId = Binder.clearCallingIdentity();
4554            try {
4555                mStackSupervisor.finishVoiceTask(session);
4556            } finally {
4557                Binder.restoreCallingIdentity(origId);
4558            }
4559        }
4560
4561    }
4562
4563    @Override
4564    public boolean releaseActivityInstance(IBinder token) {
4565        synchronized(this) {
4566            final long origId = Binder.clearCallingIdentity();
4567            try {
4568                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4569                if (r.task == null || r.task.stack == null) {
4570                    return false;
4571                }
4572                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4573            } finally {
4574                Binder.restoreCallingIdentity(origId);
4575            }
4576        }
4577    }
4578
4579    @Override
4580    public void releaseSomeActivities(IApplicationThread appInt) {
4581        synchronized(this) {
4582            final long origId = Binder.clearCallingIdentity();
4583            try {
4584                ProcessRecord app = getRecordForAppLocked(appInt);
4585                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4586            } finally {
4587                Binder.restoreCallingIdentity(origId);
4588            }
4589        }
4590    }
4591
4592    @Override
4593    public boolean willActivityBeVisible(IBinder token) {
4594        synchronized(this) {
4595            ActivityStack stack = ActivityRecord.getStackLocked(token);
4596            if (stack != null) {
4597                return stack.willActivityBeVisibleLocked(token);
4598            }
4599            return false;
4600        }
4601    }
4602
4603    @Override
4604    public void overridePendingTransition(IBinder token, String packageName,
4605            int enterAnim, int exitAnim) {
4606        synchronized(this) {
4607            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4608            if (self == null) {
4609                return;
4610            }
4611
4612            final long origId = Binder.clearCallingIdentity();
4613
4614            if (self.state == ActivityState.RESUMED
4615                    || self.state == ActivityState.PAUSING) {
4616                mWindowManager.overridePendingAppTransition(packageName,
4617                        enterAnim, exitAnim, null);
4618            }
4619
4620            Binder.restoreCallingIdentity(origId);
4621        }
4622    }
4623
4624    /**
4625     * Main function for removing an existing process from the activity manager
4626     * as a result of that process going away.  Clears out all connections
4627     * to the process.
4628     */
4629    private final void handleAppDiedLocked(ProcessRecord app,
4630            boolean restarting, boolean allowRestart) {
4631        int pid = app.pid;
4632        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4633        if (!restarting) {
4634            removeLruProcessLocked(app);
4635            if (pid > 0) {
4636                ProcessList.remove(pid);
4637            }
4638        }
4639
4640        if (mProfileProc == app) {
4641            clearProfilerLocked();
4642        }
4643
4644        // Remove this application's activities from active lists.
4645        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4646
4647        app.activities.clear();
4648
4649        if (app.instrumentationClass != null) {
4650            Slog.w(TAG, "Crash of app " + app.processName
4651                  + " running instrumentation " + app.instrumentationClass);
4652            Bundle info = new Bundle();
4653            info.putString("shortMsg", "Process crashed.");
4654            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4655        }
4656
4657        if (!restarting) {
4658            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4659                // If there was nothing to resume, and we are not already
4660                // restarting this process, but there is a visible activity that
4661                // is hosted by the process...  then make sure all visible
4662                // activities are running, taking care of restarting this
4663                // process.
4664                if (hasVisibleActivities) {
4665                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4666                }
4667            }
4668        }
4669    }
4670
4671    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4672        IBinder threadBinder = thread.asBinder();
4673        // Find the application record.
4674        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4675            ProcessRecord rec = mLruProcesses.get(i);
4676            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4677                return i;
4678            }
4679        }
4680        return -1;
4681    }
4682
4683    final ProcessRecord getRecordForAppLocked(
4684            IApplicationThread thread) {
4685        if (thread == null) {
4686            return null;
4687        }
4688
4689        int appIndex = getLRURecordIndexForAppLocked(thread);
4690        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4691    }
4692
4693    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4694        // If there are no longer any background processes running,
4695        // and the app that died was not running instrumentation,
4696        // then tell everyone we are now low on memory.
4697        boolean haveBg = false;
4698        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4699            ProcessRecord rec = mLruProcesses.get(i);
4700            if (rec.thread != null
4701                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4702                haveBg = true;
4703                break;
4704            }
4705        }
4706
4707        if (!haveBg) {
4708            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4709            if (doReport) {
4710                long now = SystemClock.uptimeMillis();
4711                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4712                    doReport = false;
4713                } else {
4714                    mLastMemUsageReportTime = now;
4715                }
4716            }
4717            final ArrayList<ProcessMemInfo> memInfos
4718                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4719            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4720            long now = SystemClock.uptimeMillis();
4721            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4722                ProcessRecord rec = mLruProcesses.get(i);
4723                if (rec == dyingProc || rec.thread == null) {
4724                    continue;
4725                }
4726                if (doReport) {
4727                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4728                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4729                }
4730                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4731                    // The low memory report is overriding any current
4732                    // state for a GC request.  Make sure to do
4733                    // heavy/important/visible/foreground processes first.
4734                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4735                        rec.lastRequestedGc = 0;
4736                    } else {
4737                        rec.lastRequestedGc = rec.lastLowMemory;
4738                    }
4739                    rec.reportLowMemory = true;
4740                    rec.lastLowMemory = now;
4741                    mProcessesToGc.remove(rec);
4742                    addProcessToGcListLocked(rec);
4743                }
4744            }
4745            if (doReport) {
4746                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4747                mHandler.sendMessage(msg);
4748            }
4749            scheduleAppGcsLocked();
4750        }
4751    }
4752
4753    final void appDiedLocked(ProcessRecord app) {
4754       appDiedLocked(app, app.pid, app.thread);
4755    }
4756
4757    final void appDiedLocked(ProcessRecord app, int pid,
4758            IApplicationThread thread) {
4759
4760        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4761        synchronized (stats) {
4762            stats.noteProcessDiedLocked(app.info.uid, pid);
4763        }
4764
4765        Process.killProcessGroup(app.info.uid, pid);
4766
4767        // Clean up already done if the process has been re-started.
4768        if (app.pid == pid && app.thread != null &&
4769                app.thread.asBinder() == thread.asBinder()) {
4770            boolean doLowMem = app.instrumentationClass == null;
4771            boolean doOomAdj = doLowMem;
4772            if (!app.killedByAm) {
4773                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4774                        + ") has died.");
4775                mAllowLowerMemLevel = true;
4776            } else {
4777                // Note that we always want to do oom adj to update our state with the
4778                // new number of procs.
4779                mAllowLowerMemLevel = false;
4780                doLowMem = false;
4781            }
4782            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4783            if (DEBUG_CLEANUP) Slog.v(
4784                TAG, "Dying app: " + app + ", pid: " + pid
4785                + ", thread: " + thread.asBinder());
4786            handleAppDiedLocked(app, false, true);
4787
4788            if (doOomAdj) {
4789                updateOomAdjLocked();
4790            }
4791            if (doLowMem) {
4792                doLowMemReportIfNeededLocked(app);
4793            }
4794        } else if (app.pid != pid) {
4795            // A new process has already been started.
4796            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4797                    + ") has died and restarted (pid " + app.pid + ").");
4798            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4799        } else if (DEBUG_PROCESSES) {
4800            Slog.d(TAG, "Received spurious death notification for thread "
4801                    + thread.asBinder());
4802        }
4803    }
4804
4805    /**
4806     * If a stack trace dump file is configured, dump process stack traces.
4807     * @param clearTraces causes the dump file to be erased prior to the new
4808     *    traces being written, if true; when false, the new traces will be
4809     *    appended to any existing file content.
4810     * @param firstPids of dalvik VM processes to dump stack traces for first
4811     * @param lastPids of dalvik VM processes to dump stack traces for last
4812     * @param nativeProcs optional list of native process names to dump stack crawls
4813     * @return file containing stack traces, or null if no dump file is configured
4814     */
4815    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4816            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4817        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818        if (tracesPath == null || tracesPath.length() == 0) {
4819            return null;
4820        }
4821
4822        File tracesFile = new File(tracesPath);
4823        try {
4824            File tracesDir = tracesFile.getParentFile();
4825            if (!tracesDir.exists()) {
4826                tracesFile.mkdirs();
4827                if (!SELinux.restorecon(tracesDir)) {
4828                    return null;
4829                }
4830            }
4831            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4832
4833            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4834            tracesFile.createNewFile();
4835            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4836        } catch (IOException e) {
4837            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4838            return null;
4839        }
4840
4841        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4842        return tracesFile;
4843    }
4844
4845    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4846            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4847        // Use a FileObserver to detect when traces finish writing.
4848        // The order of traces is considered important to maintain for legibility.
4849        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4850            @Override
4851            public synchronized void onEvent(int event, String path) { notify(); }
4852        };
4853
4854        try {
4855            observer.startWatching();
4856
4857            // First collect all of the stacks of the most important pids.
4858            if (firstPids != null) {
4859                try {
4860                    int num = firstPids.size();
4861                    for (int i = 0; i < num; i++) {
4862                        synchronized (observer) {
4863                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4864                            observer.wait(200);  // Wait for write-close, give up after 200msec
4865                        }
4866                    }
4867                } catch (InterruptedException e) {
4868                    Log.wtf(TAG, e);
4869                }
4870            }
4871
4872            // Next collect the stacks of the native pids
4873            if (nativeProcs != null) {
4874                int[] pids = Process.getPidsForCommands(nativeProcs);
4875                if (pids != null) {
4876                    for (int pid : pids) {
4877                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4878                    }
4879                }
4880            }
4881
4882            // Lastly, measure CPU usage.
4883            if (processCpuTracker != null) {
4884                processCpuTracker.init();
4885                System.gc();
4886                processCpuTracker.update();
4887                try {
4888                    synchronized (processCpuTracker) {
4889                        processCpuTracker.wait(500); // measure over 1/2 second.
4890                    }
4891                } catch (InterruptedException e) {
4892                }
4893                processCpuTracker.update();
4894
4895                // We'll take the stack crawls of just the top apps using CPU.
4896                final int N = processCpuTracker.countWorkingStats();
4897                int numProcs = 0;
4898                for (int i=0; i<N && numProcs<5; i++) {
4899                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4900                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4901                        numProcs++;
4902                        try {
4903                            synchronized (observer) {
4904                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4905                                observer.wait(200);  // Wait for write-close, give up after 200msec
4906                            }
4907                        } catch (InterruptedException e) {
4908                            Log.wtf(TAG, e);
4909                        }
4910
4911                    }
4912                }
4913            }
4914        } finally {
4915            observer.stopWatching();
4916        }
4917    }
4918
4919    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4920        if (true || IS_USER_BUILD) {
4921            return;
4922        }
4923        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4924        if (tracesPath == null || tracesPath.length() == 0) {
4925            return;
4926        }
4927
4928        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4929        StrictMode.allowThreadDiskWrites();
4930        try {
4931            final File tracesFile = new File(tracesPath);
4932            final File tracesDir = tracesFile.getParentFile();
4933            final File tracesTmp = new File(tracesDir, "__tmp__");
4934            try {
4935                if (!tracesDir.exists()) {
4936                    tracesFile.mkdirs();
4937                    if (!SELinux.restorecon(tracesDir.getPath())) {
4938                        return;
4939                    }
4940                }
4941                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4942
4943                if (tracesFile.exists()) {
4944                    tracesTmp.delete();
4945                    tracesFile.renameTo(tracesTmp);
4946                }
4947                StringBuilder sb = new StringBuilder();
4948                Time tobj = new Time();
4949                tobj.set(System.currentTimeMillis());
4950                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4951                sb.append(": ");
4952                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4953                sb.append(" since ");
4954                sb.append(msg);
4955                FileOutputStream fos = new FileOutputStream(tracesFile);
4956                fos.write(sb.toString().getBytes());
4957                if (app == null) {
4958                    fos.write("\n*** No application process!".getBytes());
4959                }
4960                fos.close();
4961                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4962            } catch (IOException e) {
4963                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4964                return;
4965            }
4966
4967            if (app != null) {
4968                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4969                firstPids.add(app.pid);
4970                dumpStackTraces(tracesPath, firstPids, null, null, null);
4971            }
4972
4973            File lastTracesFile = null;
4974            File curTracesFile = null;
4975            for (int i=9; i>=0; i--) {
4976                String name = String.format(Locale.US, "slow%02d.txt", i);
4977                curTracesFile = new File(tracesDir, name);
4978                if (curTracesFile.exists()) {
4979                    if (lastTracesFile != null) {
4980                        curTracesFile.renameTo(lastTracesFile);
4981                    } else {
4982                        curTracesFile.delete();
4983                    }
4984                }
4985                lastTracesFile = curTracesFile;
4986            }
4987            tracesFile.renameTo(curTracesFile);
4988            if (tracesTmp.exists()) {
4989                tracesTmp.renameTo(tracesFile);
4990            }
4991        } finally {
4992            StrictMode.setThreadPolicy(oldPolicy);
4993        }
4994    }
4995
4996    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4997            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4998        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4999        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5000
5001        if (mController != null) {
5002            try {
5003                // 0 == continue, -1 = kill process immediately
5004                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5005                if (res < 0 && app.pid != MY_PID) {
5006                    app.kill("anr", true);
5007                }
5008            } catch (RemoteException e) {
5009                mController = null;
5010                Watchdog.getInstance().setActivityController(null);
5011            }
5012        }
5013
5014        long anrTime = SystemClock.uptimeMillis();
5015        if (MONITOR_CPU_USAGE) {
5016            updateCpuStatsNow();
5017        }
5018
5019        synchronized (this) {
5020            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5021            if (mShuttingDown) {
5022                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5023                return;
5024            } else if (app.notResponding) {
5025                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5026                return;
5027            } else if (app.crashing) {
5028                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5029                return;
5030            }
5031
5032            // In case we come through here for the same app before completing
5033            // this one, mark as anring now so we will bail out.
5034            app.notResponding = true;
5035
5036            // Log the ANR to the event log.
5037            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5038                    app.processName, app.info.flags, annotation);
5039
5040            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5041            firstPids.add(app.pid);
5042
5043            int parentPid = app.pid;
5044            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5045            if (parentPid != app.pid) firstPids.add(parentPid);
5046
5047            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5048
5049            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5050                ProcessRecord r = mLruProcesses.get(i);
5051                if (r != null && r.thread != null) {
5052                    int pid = r.pid;
5053                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5054                        if (r.persistent) {
5055                            firstPids.add(pid);
5056                        } else {
5057                            lastPids.put(pid, Boolean.TRUE);
5058                        }
5059                    }
5060                }
5061            }
5062        }
5063
5064        // Log the ANR to the main log.
5065        StringBuilder info = new StringBuilder();
5066        info.setLength(0);
5067        info.append("ANR in ").append(app.processName);
5068        if (activity != null && activity.shortComponentName != null) {
5069            info.append(" (").append(activity.shortComponentName).append(")");
5070        }
5071        info.append("\n");
5072        info.append("PID: ").append(app.pid).append("\n");
5073        if (annotation != null) {
5074            info.append("Reason: ").append(annotation).append("\n");
5075        }
5076        if (parent != null && parent != activity) {
5077            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5078        }
5079
5080        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5081
5082        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5083                NATIVE_STACKS_OF_INTEREST);
5084
5085        String cpuInfo = null;
5086        if (MONITOR_CPU_USAGE) {
5087            updateCpuStatsNow();
5088            synchronized (mProcessCpuThread) {
5089                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5090            }
5091            info.append(processCpuTracker.printCurrentLoad());
5092            info.append(cpuInfo);
5093        }
5094
5095        info.append(processCpuTracker.printCurrentState(anrTime));
5096
5097        Slog.e(TAG, info.toString());
5098        if (tracesFile == null) {
5099            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5100            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5101        }
5102
5103        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5104                cpuInfo, tracesFile, null);
5105
5106        if (mController != null) {
5107            try {
5108                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5109                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5110                if (res != 0) {
5111                    if (res < 0 && app.pid != MY_PID) {
5112                        app.kill("anr", true);
5113                    } else {
5114                        synchronized (this) {
5115                            mServices.scheduleServiceTimeoutLocked(app);
5116                        }
5117                    }
5118                    return;
5119                }
5120            } catch (RemoteException e) {
5121                mController = null;
5122                Watchdog.getInstance().setActivityController(null);
5123            }
5124        }
5125
5126        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5127        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5128                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5129
5130        synchronized (this) {
5131            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5132                app.kill("bg anr", true);
5133                return;
5134            }
5135
5136            // Set the app's notResponding state, and look up the errorReportReceiver
5137            makeAppNotRespondingLocked(app,
5138                    activity != null ? activity.shortComponentName : null,
5139                    annotation != null ? "ANR " + annotation : "ANR",
5140                    info.toString());
5141
5142            // Bring up the infamous App Not Responding dialog
5143            Message msg = Message.obtain();
5144            HashMap<String, Object> map = new HashMap<String, Object>();
5145            msg.what = SHOW_NOT_RESPONDING_MSG;
5146            msg.obj = map;
5147            msg.arg1 = aboveSystem ? 1 : 0;
5148            map.put("app", app);
5149            if (activity != null) {
5150                map.put("activity", activity);
5151            }
5152
5153            mHandler.sendMessage(msg);
5154        }
5155    }
5156
5157    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5158        if (!mLaunchWarningShown) {
5159            mLaunchWarningShown = true;
5160            mHandler.post(new Runnable() {
5161                @Override
5162                public void run() {
5163                    synchronized (ActivityManagerService.this) {
5164                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5165                        d.show();
5166                        mHandler.postDelayed(new Runnable() {
5167                            @Override
5168                            public void run() {
5169                                synchronized (ActivityManagerService.this) {
5170                                    d.dismiss();
5171                                    mLaunchWarningShown = false;
5172                                }
5173                            }
5174                        }, 4000);
5175                    }
5176                }
5177            });
5178        }
5179    }
5180
5181    @Override
5182    public boolean clearApplicationUserData(final String packageName,
5183            final IPackageDataObserver observer, int userId) {
5184        enforceNotIsolatedCaller("clearApplicationUserData");
5185        int uid = Binder.getCallingUid();
5186        int pid = Binder.getCallingPid();
5187        userId = handleIncomingUser(pid, uid,
5188                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5189        long callingId = Binder.clearCallingIdentity();
5190        try {
5191            IPackageManager pm = AppGlobals.getPackageManager();
5192            int pkgUid = -1;
5193            synchronized(this) {
5194                try {
5195                    pkgUid = pm.getPackageUid(packageName, userId);
5196                } catch (RemoteException e) {
5197                }
5198                if (pkgUid == -1) {
5199                    Slog.w(TAG, "Invalid packageName: " + packageName);
5200                    if (observer != null) {
5201                        try {
5202                            observer.onRemoveCompleted(packageName, false);
5203                        } catch (RemoteException e) {
5204                            Slog.i(TAG, "Observer no longer exists.");
5205                        }
5206                    }
5207                    return false;
5208                }
5209                if (uid == pkgUid || checkComponentPermission(
5210                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5211                        pid, uid, -1, true)
5212                        == PackageManager.PERMISSION_GRANTED) {
5213                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5214                } else {
5215                    throw new SecurityException("PID " + pid + " does not have permission "
5216                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5217                                    + " of package " + packageName);
5218                }
5219
5220                // Remove all tasks match the cleared application package and user
5221                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5222                    final TaskRecord tr = mRecentTasks.get(i);
5223                    final String taskPackageName =
5224                            tr.getBaseIntent().getComponent().getPackageName();
5225                    if (tr.userId != userId) continue;
5226                    if (!taskPackageName.equals(packageName)) continue;
5227                    removeTaskByIdLocked(tr.taskId, 0);
5228                }
5229            }
5230
5231            try {
5232                // Clear application user data
5233                pm.clearApplicationUserData(packageName, observer, userId);
5234
5235                synchronized(this) {
5236                    // Remove all permissions granted from/to this package
5237                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5238                }
5239
5240                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5241                        Uri.fromParts("package", packageName, null));
5242                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5243                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5244                        null, null, 0, null, null, null, false, false, userId);
5245            } catch (RemoteException e) {
5246            }
5247        } finally {
5248            Binder.restoreCallingIdentity(callingId);
5249        }
5250        return true;
5251    }
5252
5253    @Override
5254    public void killBackgroundProcesses(final String packageName, int userId) {
5255        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5256                != PackageManager.PERMISSION_GRANTED &&
5257                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5258                        != PackageManager.PERMISSION_GRANTED) {
5259            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5260                    + Binder.getCallingPid()
5261                    + ", uid=" + Binder.getCallingUid()
5262                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5263            Slog.w(TAG, msg);
5264            throw new SecurityException(msg);
5265        }
5266
5267        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5268                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5269        long callingId = Binder.clearCallingIdentity();
5270        try {
5271            IPackageManager pm = AppGlobals.getPackageManager();
5272            synchronized(this) {
5273                int appId = -1;
5274                try {
5275                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5276                } catch (RemoteException e) {
5277                }
5278                if (appId == -1) {
5279                    Slog.w(TAG, "Invalid packageName: " + packageName);
5280                    return;
5281                }
5282                killPackageProcessesLocked(packageName, appId, userId,
5283                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5284            }
5285        } finally {
5286            Binder.restoreCallingIdentity(callingId);
5287        }
5288    }
5289
5290    @Override
5291    public void killAllBackgroundProcesses() {
5292        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5293                != PackageManager.PERMISSION_GRANTED) {
5294            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5295                    + Binder.getCallingPid()
5296                    + ", uid=" + Binder.getCallingUid()
5297                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5298            Slog.w(TAG, msg);
5299            throw new SecurityException(msg);
5300        }
5301
5302        long callingId = Binder.clearCallingIdentity();
5303        try {
5304            synchronized(this) {
5305                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5306                final int NP = mProcessNames.getMap().size();
5307                for (int ip=0; ip<NP; ip++) {
5308                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5309                    final int NA = apps.size();
5310                    for (int ia=0; ia<NA; ia++) {
5311                        ProcessRecord app = apps.valueAt(ia);
5312                        if (app.persistent) {
5313                            // we don't kill persistent processes
5314                            continue;
5315                        }
5316                        if (app.removed) {
5317                            procs.add(app);
5318                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5319                            app.removed = true;
5320                            procs.add(app);
5321                        }
5322                    }
5323                }
5324
5325                int N = procs.size();
5326                for (int i=0; i<N; i++) {
5327                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5328                }
5329                mAllowLowerMemLevel = true;
5330                updateOomAdjLocked();
5331                doLowMemReportIfNeededLocked(null);
5332            }
5333        } finally {
5334            Binder.restoreCallingIdentity(callingId);
5335        }
5336    }
5337
5338    @Override
5339    public void forceStopPackage(final String packageName, int userId) {
5340        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5341                != PackageManager.PERMISSION_GRANTED) {
5342            String msg = "Permission Denial: forceStopPackage() from pid="
5343                    + Binder.getCallingPid()
5344                    + ", uid=" + Binder.getCallingUid()
5345                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5346            Slog.w(TAG, msg);
5347            throw new SecurityException(msg);
5348        }
5349        final int callingPid = Binder.getCallingPid();
5350        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5351                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5352        long callingId = Binder.clearCallingIdentity();
5353        try {
5354            IPackageManager pm = AppGlobals.getPackageManager();
5355            synchronized(this) {
5356                int[] users = userId == UserHandle.USER_ALL
5357                        ? getUsersLocked() : new int[] { userId };
5358                for (int user : users) {
5359                    int pkgUid = -1;
5360                    try {
5361                        pkgUid = pm.getPackageUid(packageName, user);
5362                    } catch (RemoteException e) {
5363                    }
5364                    if (pkgUid == -1) {
5365                        Slog.w(TAG, "Invalid packageName: " + packageName);
5366                        continue;
5367                    }
5368                    try {
5369                        pm.setPackageStoppedState(packageName, true, user);
5370                    } catch (RemoteException e) {
5371                    } catch (IllegalArgumentException e) {
5372                        Slog.w(TAG, "Failed trying to unstop package "
5373                                + packageName + ": " + e);
5374                    }
5375                    if (isUserRunningLocked(user, false)) {
5376                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5377                    }
5378                }
5379            }
5380        } finally {
5381            Binder.restoreCallingIdentity(callingId);
5382        }
5383    }
5384
5385    @Override
5386    public void addPackageDependency(String packageName) {
5387        synchronized (this) {
5388            int callingPid = Binder.getCallingPid();
5389            if (callingPid == Process.myPid()) {
5390                //  Yeah, um, no.
5391                Slog.w(TAG, "Can't addPackageDependency on system process");
5392                return;
5393            }
5394            ProcessRecord proc;
5395            synchronized (mPidsSelfLocked) {
5396                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5397            }
5398            if (proc != null) {
5399                if (proc.pkgDeps == null) {
5400                    proc.pkgDeps = new ArraySet<String>(1);
5401                }
5402                proc.pkgDeps.add(packageName);
5403            }
5404        }
5405    }
5406
5407    /*
5408     * The pkg name and app id have to be specified.
5409     */
5410    @Override
5411    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5412        if (pkg == null) {
5413            return;
5414        }
5415        // Make sure the uid is valid.
5416        if (appid < 0) {
5417            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5418            return;
5419        }
5420        int callerUid = Binder.getCallingUid();
5421        // Only the system server can kill an application
5422        if (callerUid == Process.SYSTEM_UID) {
5423            // Post an aysnc message to kill the application
5424            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5425            msg.arg1 = appid;
5426            msg.arg2 = 0;
5427            Bundle bundle = new Bundle();
5428            bundle.putString("pkg", pkg);
5429            bundle.putString("reason", reason);
5430            msg.obj = bundle;
5431            mHandler.sendMessage(msg);
5432        } else {
5433            throw new SecurityException(callerUid + " cannot kill pkg: " +
5434                    pkg);
5435        }
5436    }
5437
5438    @Override
5439    public void closeSystemDialogs(String reason) {
5440        enforceNotIsolatedCaller("closeSystemDialogs");
5441
5442        final int pid = Binder.getCallingPid();
5443        final int uid = Binder.getCallingUid();
5444        final long origId = Binder.clearCallingIdentity();
5445        try {
5446            synchronized (this) {
5447                // Only allow this from foreground processes, so that background
5448                // applications can't abuse it to prevent system UI from being shown.
5449                if (uid >= Process.FIRST_APPLICATION_UID) {
5450                    ProcessRecord proc;
5451                    synchronized (mPidsSelfLocked) {
5452                        proc = mPidsSelfLocked.get(pid);
5453                    }
5454                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5455                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5456                                + " from background process " + proc);
5457                        return;
5458                    }
5459                }
5460                closeSystemDialogsLocked(reason);
5461            }
5462        } finally {
5463            Binder.restoreCallingIdentity(origId);
5464        }
5465    }
5466
5467    void closeSystemDialogsLocked(String reason) {
5468        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5469        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5470                | Intent.FLAG_RECEIVER_FOREGROUND);
5471        if (reason != null) {
5472            intent.putExtra("reason", reason);
5473        }
5474        mWindowManager.closeSystemDialogs(reason);
5475
5476        mStackSupervisor.closeSystemDialogsLocked();
5477
5478        broadcastIntentLocked(null, null, intent, null,
5479                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5480                Process.SYSTEM_UID, UserHandle.USER_ALL);
5481    }
5482
5483    @Override
5484    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5485        enforceNotIsolatedCaller("getProcessMemoryInfo");
5486        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5487        for (int i=pids.length-1; i>=0; i--) {
5488            ProcessRecord proc;
5489            int oomAdj;
5490            synchronized (this) {
5491                synchronized (mPidsSelfLocked) {
5492                    proc = mPidsSelfLocked.get(pids[i]);
5493                    oomAdj = proc != null ? proc.setAdj : 0;
5494                }
5495            }
5496            infos[i] = new Debug.MemoryInfo();
5497            Debug.getMemoryInfo(pids[i], infos[i]);
5498            if (proc != null) {
5499                synchronized (this) {
5500                    if (proc.thread != null && proc.setAdj == oomAdj) {
5501                        // Record this for posterity if the process has been stable.
5502                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5503                                infos[i].getTotalUss(), false, proc.pkgList);
5504                    }
5505                }
5506            }
5507        }
5508        return infos;
5509    }
5510
5511    @Override
5512    public long[] getProcessPss(int[] pids) {
5513        enforceNotIsolatedCaller("getProcessPss");
5514        long[] pss = new long[pids.length];
5515        for (int i=pids.length-1; i>=0; i--) {
5516            ProcessRecord proc;
5517            int oomAdj;
5518            synchronized (this) {
5519                synchronized (mPidsSelfLocked) {
5520                    proc = mPidsSelfLocked.get(pids[i]);
5521                    oomAdj = proc != null ? proc.setAdj : 0;
5522                }
5523            }
5524            long[] tmpUss = new long[1];
5525            pss[i] = Debug.getPss(pids[i], tmpUss);
5526            if (proc != null) {
5527                synchronized (this) {
5528                    if (proc.thread != null && proc.setAdj == oomAdj) {
5529                        // Record this for posterity if the process has been stable.
5530                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5531                    }
5532                }
5533            }
5534        }
5535        return pss;
5536    }
5537
5538    @Override
5539    public void killApplicationProcess(String processName, int uid) {
5540        if (processName == null) {
5541            return;
5542        }
5543
5544        int callerUid = Binder.getCallingUid();
5545        // Only the system server can kill an application
5546        if (callerUid == Process.SYSTEM_UID) {
5547            synchronized (this) {
5548                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5549                if (app != null && app.thread != null) {
5550                    try {
5551                        app.thread.scheduleSuicide();
5552                    } catch (RemoteException e) {
5553                        // If the other end already died, then our work here is done.
5554                    }
5555                } else {
5556                    Slog.w(TAG, "Process/uid not found attempting kill of "
5557                            + processName + " / " + uid);
5558                }
5559            }
5560        } else {
5561            throw new SecurityException(callerUid + " cannot kill app process: " +
5562                    processName);
5563        }
5564    }
5565
5566    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5567        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5568                false, true, false, false, UserHandle.getUserId(uid), reason);
5569        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5570                Uri.fromParts("package", packageName, null));
5571        if (!mProcessesReady) {
5572            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5573                    | Intent.FLAG_RECEIVER_FOREGROUND);
5574        }
5575        intent.putExtra(Intent.EXTRA_UID, uid);
5576        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5577        broadcastIntentLocked(null, null, intent,
5578                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5579                false, false,
5580                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5581    }
5582
5583    private void forceStopUserLocked(int userId, String reason) {
5584        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5585        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5586        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5587                | Intent.FLAG_RECEIVER_FOREGROUND);
5588        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5589        broadcastIntentLocked(null, null, intent,
5590                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5591                false, false,
5592                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5593    }
5594
5595    private final boolean killPackageProcessesLocked(String packageName, int appId,
5596            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5597            boolean doit, boolean evenPersistent, String reason) {
5598        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5599
5600        // Remove all processes this package may have touched: all with the
5601        // same UID (except for the system or root user), and all whose name
5602        // matches the package name.
5603        final int NP = mProcessNames.getMap().size();
5604        for (int ip=0; ip<NP; ip++) {
5605            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5606            final int NA = apps.size();
5607            for (int ia=0; ia<NA; ia++) {
5608                ProcessRecord app = apps.valueAt(ia);
5609                if (app.persistent && !evenPersistent) {
5610                    // we don't kill persistent processes
5611                    continue;
5612                }
5613                if (app.removed) {
5614                    if (doit) {
5615                        procs.add(app);
5616                    }
5617                    continue;
5618                }
5619
5620                // Skip process if it doesn't meet our oom adj requirement.
5621                if (app.setAdj < minOomAdj) {
5622                    continue;
5623                }
5624
5625                // If no package is specified, we call all processes under the
5626                // give user id.
5627                if (packageName == null) {
5628                    if (app.userId != userId) {
5629                        continue;
5630                    }
5631                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5632                        continue;
5633                    }
5634                // Package has been specified, we want to hit all processes
5635                // that match it.  We need to qualify this by the processes
5636                // that are running under the specified app and user ID.
5637                } else {
5638                    final boolean isDep = app.pkgDeps != null
5639                            && app.pkgDeps.contains(packageName);
5640                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5641                        continue;
5642                    }
5643                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5644                        continue;
5645                    }
5646                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5647                        continue;
5648                    }
5649                }
5650
5651                // Process has passed all conditions, kill it!
5652                if (!doit) {
5653                    return true;
5654                }
5655                app.removed = true;
5656                procs.add(app);
5657            }
5658        }
5659
5660        int N = procs.size();
5661        for (int i=0; i<N; i++) {
5662            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5663        }
5664        updateOomAdjLocked();
5665        return N > 0;
5666    }
5667
5668    private final boolean forceStopPackageLocked(String name, int appId,
5669            boolean callerWillRestart, boolean purgeCache, boolean doit,
5670            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5671        int i;
5672        int N;
5673
5674        if (userId == UserHandle.USER_ALL && name == null) {
5675            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5676        }
5677
5678        if (appId < 0 && name != null) {
5679            try {
5680                appId = UserHandle.getAppId(
5681                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5682            } catch (RemoteException e) {
5683            }
5684        }
5685
5686        if (doit) {
5687            if (name != null) {
5688                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5689                        + " user=" + userId + ": " + reason);
5690            } else {
5691                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5692            }
5693
5694            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5695            for (int ip=pmap.size()-1; ip>=0; ip--) {
5696                SparseArray<Long> ba = pmap.valueAt(ip);
5697                for (i=ba.size()-1; i>=0; i--) {
5698                    boolean remove = false;
5699                    final int entUid = ba.keyAt(i);
5700                    if (name != null) {
5701                        if (userId == UserHandle.USER_ALL) {
5702                            if (UserHandle.getAppId(entUid) == appId) {
5703                                remove = true;
5704                            }
5705                        } else {
5706                            if (entUid == UserHandle.getUid(userId, appId)) {
5707                                remove = true;
5708                            }
5709                        }
5710                    } else if (UserHandle.getUserId(entUid) == userId) {
5711                        remove = true;
5712                    }
5713                    if (remove) {
5714                        ba.removeAt(i);
5715                    }
5716                }
5717                if (ba.size() == 0) {
5718                    pmap.removeAt(ip);
5719                }
5720            }
5721        }
5722
5723        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5724                -100, callerWillRestart, true, doit, evenPersistent,
5725                name == null ? ("stop user " + userId) : ("stop " + name));
5726
5727        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5728            if (!doit) {
5729                return true;
5730            }
5731            didSomething = true;
5732        }
5733
5734        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5735            if (!doit) {
5736                return true;
5737            }
5738            didSomething = true;
5739        }
5740
5741        if (name == null) {
5742            // Remove all sticky broadcasts from this user.
5743            mStickyBroadcasts.remove(userId);
5744        }
5745
5746        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5747        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5748                userId, providers)) {
5749            if (!doit) {
5750                return true;
5751            }
5752            didSomething = true;
5753        }
5754        N = providers.size();
5755        for (i=0; i<N; i++) {
5756            removeDyingProviderLocked(null, providers.get(i), true);
5757        }
5758
5759        // Remove transient permissions granted from/to this package/user
5760        removeUriPermissionsForPackageLocked(name, userId, false);
5761
5762        if (name == null || uninstalling) {
5763            // Remove pending intents.  For now we only do this when force
5764            // stopping users, because we have some problems when doing this
5765            // for packages -- app widgets are not currently cleaned up for
5766            // such packages, so they can be left with bad pending intents.
5767            if (mIntentSenderRecords.size() > 0) {
5768                Iterator<WeakReference<PendingIntentRecord>> it
5769                        = mIntentSenderRecords.values().iterator();
5770                while (it.hasNext()) {
5771                    WeakReference<PendingIntentRecord> wpir = it.next();
5772                    if (wpir == null) {
5773                        it.remove();
5774                        continue;
5775                    }
5776                    PendingIntentRecord pir = wpir.get();
5777                    if (pir == null) {
5778                        it.remove();
5779                        continue;
5780                    }
5781                    if (name == null) {
5782                        // Stopping user, remove all objects for the user.
5783                        if (pir.key.userId != userId) {
5784                            // Not the same user, skip it.
5785                            continue;
5786                        }
5787                    } else {
5788                        if (UserHandle.getAppId(pir.uid) != appId) {
5789                            // Different app id, skip it.
5790                            continue;
5791                        }
5792                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5793                            // Different user, skip it.
5794                            continue;
5795                        }
5796                        if (!pir.key.packageName.equals(name)) {
5797                            // Different package, skip it.
5798                            continue;
5799                        }
5800                    }
5801                    if (!doit) {
5802                        return true;
5803                    }
5804                    didSomething = true;
5805                    it.remove();
5806                    pir.canceled = true;
5807                    if (pir.key.activity != null) {
5808                        pir.key.activity.pendingResults.remove(pir.ref);
5809                    }
5810                }
5811            }
5812        }
5813
5814        if (doit) {
5815            if (purgeCache && name != null) {
5816                AttributeCache ac = AttributeCache.instance();
5817                if (ac != null) {
5818                    ac.removePackage(name);
5819                }
5820            }
5821            if (mBooted) {
5822                mStackSupervisor.resumeTopActivitiesLocked();
5823                mStackSupervisor.scheduleIdleLocked();
5824            }
5825        }
5826
5827        return didSomething;
5828    }
5829
5830    private final boolean removeProcessLocked(ProcessRecord app,
5831            boolean callerWillRestart, boolean allowRestart, String reason) {
5832        final String name = app.processName;
5833        final int uid = app.uid;
5834        if (DEBUG_PROCESSES) Slog.d(
5835            TAG, "Force removing proc " + app.toShortString() + " (" + name
5836            + "/" + uid + ")");
5837
5838        mProcessNames.remove(name, uid);
5839        mIsolatedProcesses.remove(app.uid);
5840        if (mHeavyWeightProcess == app) {
5841            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5842                    mHeavyWeightProcess.userId, 0));
5843            mHeavyWeightProcess = null;
5844        }
5845        boolean needRestart = false;
5846        if (app.pid > 0 && app.pid != MY_PID) {
5847            int pid = app.pid;
5848            synchronized (mPidsSelfLocked) {
5849                mPidsSelfLocked.remove(pid);
5850                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5851            }
5852            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5853            if (app.isolated) {
5854                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5855            }
5856            app.kill(reason, true);
5857            handleAppDiedLocked(app, true, allowRestart);
5858            removeLruProcessLocked(app);
5859
5860            if (app.persistent && !app.isolated) {
5861                if (!callerWillRestart) {
5862                    addAppLocked(app.info, false, null /* ABI override */);
5863                } else {
5864                    needRestart = true;
5865                }
5866            }
5867        } else {
5868            mRemovedProcesses.add(app);
5869        }
5870
5871        return needRestart;
5872    }
5873
5874    private final void processStartTimedOutLocked(ProcessRecord app) {
5875        final int pid = app.pid;
5876        boolean gone = false;
5877        synchronized (mPidsSelfLocked) {
5878            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5879            if (knownApp != null && knownApp.thread == null) {
5880                mPidsSelfLocked.remove(pid);
5881                gone = true;
5882            }
5883        }
5884
5885        if (gone) {
5886            Slog.w(TAG, "Process " + app + " failed to attach");
5887            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5888                    pid, app.uid, app.processName);
5889            mProcessNames.remove(app.processName, app.uid);
5890            mIsolatedProcesses.remove(app.uid);
5891            if (mHeavyWeightProcess == app) {
5892                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5893                        mHeavyWeightProcess.userId, 0));
5894                mHeavyWeightProcess = null;
5895            }
5896            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5897            if (app.isolated) {
5898                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5899            }
5900            // Take care of any launching providers waiting for this process.
5901            checkAppInLaunchingProvidersLocked(app, true);
5902            // Take care of any services that are waiting for the process.
5903            mServices.processStartTimedOutLocked(app);
5904            app.kill("start timeout", true);
5905            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5906                Slog.w(TAG, "Unattached app died before backup, skipping");
5907                try {
5908                    IBackupManager bm = IBackupManager.Stub.asInterface(
5909                            ServiceManager.getService(Context.BACKUP_SERVICE));
5910                    bm.agentDisconnected(app.info.packageName);
5911                } catch (RemoteException e) {
5912                    // Can't happen; the backup manager is local
5913                }
5914            }
5915            if (isPendingBroadcastProcessLocked(pid)) {
5916                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5917                skipPendingBroadcastLocked(pid);
5918            }
5919        } else {
5920            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5921        }
5922    }
5923
5924    private final boolean attachApplicationLocked(IApplicationThread thread,
5925            int pid) {
5926
5927        // Find the application record that is being attached...  either via
5928        // the pid if we are running in multiple processes, or just pull the
5929        // next app record if we are emulating process with anonymous threads.
5930        ProcessRecord app;
5931        if (pid != MY_PID && pid >= 0) {
5932            synchronized (mPidsSelfLocked) {
5933                app = mPidsSelfLocked.get(pid);
5934            }
5935        } else {
5936            app = null;
5937        }
5938
5939        if (app == null) {
5940            Slog.w(TAG, "No pending application record for pid " + pid
5941                    + " (IApplicationThread " + thread + "); dropping process");
5942            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5943            if (pid > 0 && pid != MY_PID) {
5944                Process.killProcessQuiet(pid);
5945                //TODO: Process.killProcessGroup(app.info.uid, pid);
5946            } else {
5947                try {
5948                    thread.scheduleExit();
5949                } catch (Exception e) {
5950                    // Ignore exceptions.
5951                }
5952            }
5953            return false;
5954        }
5955
5956        // If this application record is still attached to a previous
5957        // process, clean it up now.
5958        if (app.thread != null) {
5959            handleAppDiedLocked(app, true, true);
5960        }
5961
5962        // Tell the process all about itself.
5963
5964        if (localLOGV) Slog.v(
5965                TAG, "Binding process pid " + pid + " to record " + app);
5966
5967        final String processName = app.processName;
5968        try {
5969            AppDeathRecipient adr = new AppDeathRecipient(
5970                    app, pid, thread);
5971            thread.asBinder().linkToDeath(adr, 0);
5972            app.deathRecipient = adr;
5973        } catch (RemoteException e) {
5974            app.resetPackageList(mProcessStats);
5975            startProcessLocked(app, "link fail", processName);
5976            return false;
5977        }
5978
5979        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5980
5981        app.makeActive(thread, mProcessStats);
5982        app.curAdj = app.setAdj = -100;
5983        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5984        app.forcingToForeground = null;
5985        updateProcessForegroundLocked(app, false, false);
5986        app.hasShownUi = false;
5987        app.debugging = false;
5988        app.cached = false;
5989
5990        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5991
5992        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5993        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5994
5995        if (!normalMode) {
5996            Slog.i(TAG, "Launching preboot mode app: " + app);
5997        }
5998
5999        if (localLOGV) Slog.v(
6000            TAG, "New app record " + app
6001            + " thread=" + thread.asBinder() + " pid=" + pid);
6002        try {
6003            int testMode = IApplicationThread.DEBUG_OFF;
6004            if (mDebugApp != null && mDebugApp.equals(processName)) {
6005                testMode = mWaitForDebugger
6006                    ? IApplicationThread.DEBUG_WAIT
6007                    : IApplicationThread.DEBUG_ON;
6008                app.debugging = true;
6009                if (mDebugTransient) {
6010                    mDebugApp = mOrigDebugApp;
6011                    mWaitForDebugger = mOrigWaitForDebugger;
6012                }
6013            }
6014            String profileFile = app.instrumentationProfileFile;
6015            ParcelFileDescriptor profileFd = null;
6016            int samplingInterval = 0;
6017            boolean profileAutoStop = false;
6018            if (mProfileApp != null && mProfileApp.equals(processName)) {
6019                mProfileProc = app;
6020                profileFile = mProfileFile;
6021                profileFd = mProfileFd;
6022                samplingInterval = mSamplingInterval;
6023                profileAutoStop = mAutoStopProfiler;
6024            }
6025            boolean enableOpenGlTrace = false;
6026            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6027                enableOpenGlTrace = true;
6028                mOpenGlTraceApp = null;
6029            }
6030
6031            // If the app is being launched for restore or full backup, set it up specially
6032            boolean isRestrictedBackupMode = false;
6033            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6034                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6035                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6036                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6037            }
6038
6039            ensurePackageDexOpt(app.instrumentationInfo != null
6040                    ? app.instrumentationInfo.packageName
6041                    : app.info.packageName);
6042            if (app.instrumentationClass != null) {
6043                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6044            }
6045            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6046                    + processName + " with config " + mConfiguration);
6047            ApplicationInfo appInfo = app.instrumentationInfo != null
6048                    ? app.instrumentationInfo : app.info;
6049            app.compat = compatibilityInfoForPackageLocked(appInfo);
6050            if (profileFd != null) {
6051                profileFd = profileFd.dup();
6052            }
6053            ProfilerInfo profilerInfo = profileFile == null ? null
6054                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6055            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6056                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6057                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6058                    isRestrictedBackupMode || !normalMode, app.persistent,
6059                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6060                    mCoreSettingsObserver.getCoreSettingsLocked());
6061            updateLruProcessLocked(app, false, null);
6062            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6063        } catch (Exception e) {
6064            // todo: Yikes!  What should we do?  For now we will try to
6065            // start another process, but that could easily get us in
6066            // an infinite loop of restarting processes...
6067            Slog.w(TAG, "Exception thrown during bind!", e);
6068
6069            app.resetPackageList(mProcessStats);
6070            app.unlinkDeathRecipient();
6071            startProcessLocked(app, "bind fail", processName);
6072            return false;
6073        }
6074
6075        // Remove this record from the list of starting applications.
6076        mPersistentStartingProcesses.remove(app);
6077        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6078                "Attach application locked removing on hold: " + app);
6079        mProcessesOnHold.remove(app);
6080
6081        boolean badApp = false;
6082        boolean didSomething = false;
6083
6084        // See if the top visible activity is waiting to run in this process...
6085        if (normalMode) {
6086            try {
6087                if (mStackSupervisor.attachApplicationLocked(app)) {
6088                    didSomething = true;
6089                }
6090            } catch (Exception e) {
6091                badApp = true;
6092            }
6093        }
6094
6095        // Find any services that should be running in this process...
6096        if (!badApp) {
6097            try {
6098                didSomething |= mServices.attachApplicationLocked(app, processName);
6099            } catch (Exception e) {
6100                badApp = true;
6101            }
6102        }
6103
6104        // Check if a next-broadcast receiver is in this process...
6105        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6106            try {
6107                didSomething |= sendPendingBroadcastsLocked(app);
6108            } catch (Exception e) {
6109                // If the app died trying to launch the receiver we declare it 'bad'
6110                badApp = true;
6111            }
6112        }
6113
6114        // Check whether the next backup agent is in this process...
6115        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6116            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6117            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6118            try {
6119                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6120                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6121                        mBackupTarget.backupMode);
6122            } catch (Exception e) {
6123                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6124                e.printStackTrace();
6125            }
6126        }
6127
6128        if (badApp) {
6129            // todo: Also need to kill application to deal with all
6130            // kinds of exceptions.
6131            handleAppDiedLocked(app, false, true);
6132            return false;
6133        }
6134
6135        if (!didSomething) {
6136            updateOomAdjLocked();
6137        }
6138
6139        return true;
6140    }
6141
6142    @Override
6143    public final void attachApplication(IApplicationThread thread) {
6144        synchronized (this) {
6145            int callingPid = Binder.getCallingPid();
6146            final long origId = Binder.clearCallingIdentity();
6147            attachApplicationLocked(thread, callingPid);
6148            Binder.restoreCallingIdentity(origId);
6149        }
6150    }
6151
6152    @Override
6153    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6154        final long origId = Binder.clearCallingIdentity();
6155        synchronized (this) {
6156            ActivityStack stack = ActivityRecord.getStackLocked(token);
6157            if (stack != null) {
6158                ActivityRecord r =
6159                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6160                if (stopProfiling) {
6161                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6162                        try {
6163                            mProfileFd.close();
6164                        } catch (IOException e) {
6165                        }
6166                        clearProfilerLocked();
6167                    }
6168                }
6169            }
6170        }
6171        Binder.restoreCallingIdentity(origId);
6172    }
6173
6174    void postEnableScreenAfterBootLocked() {
6175        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6176    }
6177
6178    void enableScreenAfterBoot() {
6179        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6180                SystemClock.uptimeMillis());
6181        mWindowManager.enableScreenAfterBoot();
6182
6183        synchronized (this) {
6184            updateEventDispatchingLocked();
6185        }
6186    }
6187
6188    @Override
6189    public void showBootMessage(final CharSequence msg, final boolean always) {
6190        enforceNotIsolatedCaller("showBootMessage");
6191        mWindowManager.showBootMessage(msg, always);
6192    }
6193
6194    @Override
6195    public void keyguardWaitingForActivityDrawn() {
6196        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6197        final long token = Binder.clearCallingIdentity();
6198        try {
6199            synchronized (this) {
6200                if (DEBUG_LOCKSCREEN) logLockScreen("");
6201                mWindowManager.keyguardWaitingForActivityDrawn();
6202            }
6203        } finally {
6204            Binder.restoreCallingIdentity(token);
6205        }
6206    }
6207
6208    final void finishBooting() {
6209        // Register receivers to handle package update events
6210        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6211
6212        // Let system services know.
6213        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6214
6215        synchronized (this) {
6216            // Ensure that any processes we had put on hold are now started
6217            // up.
6218            final int NP = mProcessesOnHold.size();
6219            if (NP > 0) {
6220                ArrayList<ProcessRecord> procs =
6221                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6222                for (int ip=0; ip<NP; ip++) {
6223                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6224                            + procs.get(ip));
6225                    startProcessLocked(procs.get(ip), "on-hold", null);
6226                }
6227            }
6228
6229            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6230                // Start looking for apps that are abusing wake locks.
6231                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6232                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6233                // Tell anyone interested that we are done booting!
6234                SystemProperties.set("sys.boot_completed", "1");
6235                SystemProperties.set("dev.bootcomplete", "1");
6236                for (int i=0; i<mStartedUsers.size(); i++) {
6237                    UserStartedState uss = mStartedUsers.valueAt(i);
6238                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6239                        uss.mState = UserStartedState.STATE_RUNNING;
6240                        final int userId = mStartedUsers.keyAt(i);
6241                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6242                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6243                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6244                        broadcastIntentLocked(null, null, intent, null,
6245                                new IIntentReceiver.Stub() {
6246                                    @Override
6247                                    public void performReceive(Intent intent, int resultCode,
6248                                            String data, Bundle extras, boolean ordered,
6249                                            boolean sticky, int sendingUser) {
6250                                        synchronized (ActivityManagerService.this) {
6251                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6252                                                    true, false);
6253                                        }
6254                                    }
6255                                },
6256                                0, null, null,
6257                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6258                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6259                                userId);
6260                    }
6261                }
6262                scheduleStartProfilesLocked();
6263            }
6264        }
6265    }
6266
6267    final void ensureBootCompleted() {
6268        boolean booting;
6269        boolean enableScreen;
6270        synchronized (this) {
6271            booting = mBooting;
6272            mBooting = false;
6273            enableScreen = !mBooted;
6274            mBooted = true;
6275        }
6276
6277        if (booting) {
6278            finishBooting();
6279        }
6280
6281        if (enableScreen) {
6282            enableScreenAfterBoot();
6283        }
6284    }
6285
6286    @Override
6287    public final void activityResumed(IBinder token) {
6288        final long origId = Binder.clearCallingIdentity();
6289        synchronized(this) {
6290            ActivityStack stack = ActivityRecord.getStackLocked(token);
6291            if (stack != null) {
6292                ActivityRecord.activityResumedLocked(token);
6293            }
6294        }
6295        Binder.restoreCallingIdentity(origId);
6296    }
6297
6298    @Override
6299    public final void activityPaused(IBinder token) {
6300        final long origId = Binder.clearCallingIdentity();
6301        synchronized(this) {
6302            ActivityStack stack = ActivityRecord.getStackLocked(token);
6303            if (stack != null) {
6304                stack.activityPausedLocked(token, false);
6305            }
6306        }
6307        Binder.restoreCallingIdentity(origId);
6308    }
6309
6310    @Override
6311    public final void activityStopped(IBinder token, Bundle icicle,
6312            PersistableBundle persistentState, CharSequence description) {
6313        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6314
6315        // Refuse possible leaked file descriptors
6316        if (icicle != null && icicle.hasFileDescriptors()) {
6317            throw new IllegalArgumentException("File descriptors passed in Bundle");
6318        }
6319
6320        final long origId = Binder.clearCallingIdentity();
6321
6322        synchronized (this) {
6323            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6324            if (r != null) {
6325                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6326            }
6327        }
6328
6329        trimApplications();
6330
6331        Binder.restoreCallingIdentity(origId);
6332    }
6333
6334    @Override
6335    public final void activityDestroyed(IBinder token) {
6336        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6337        synchronized (this) {
6338            ActivityStack stack = ActivityRecord.getStackLocked(token);
6339            if (stack != null) {
6340                stack.activityDestroyedLocked(token);
6341            }
6342        }
6343    }
6344
6345    @Override
6346    public final void backgroundResourcesReleased(IBinder token) {
6347        final long origId = Binder.clearCallingIdentity();
6348        try {
6349            synchronized (this) {
6350                ActivityStack stack = ActivityRecord.getStackLocked(token);
6351                if (stack != null) {
6352                    stack.backgroundResourcesReleased(token);
6353                }
6354            }
6355        } finally {
6356            Binder.restoreCallingIdentity(origId);
6357        }
6358    }
6359
6360    @Override
6361    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6362        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6363    }
6364
6365    @Override
6366    public final void notifyEnterAnimationComplete(IBinder token) {
6367        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6368    }
6369
6370    @Override
6371    public String getCallingPackage(IBinder token) {
6372        synchronized (this) {
6373            ActivityRecord r = getCallingRecordLocked(token);
6374            return r != null ? r.info.packageName : null;
6375        }
6376    }
6377
6378    @Override
6379    public ComponentName getCallingActivity(IBinder token) {
6380        synchronized (this) {
6381            ActivityRecord r = getCallingRecordLocked(token);
6382            return r != null ? r.intent.getComponent() : null;
6383        }
6384    }
6385
6386    private ActivityRecord getCallingRecordLocked(IBinder token) {
6387        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6388        if (r == null) {
6389            return null;
6390        }
6391        return r.resultTo;
6392    }
6393
6394    @Override
6395    public ComponentName getActivityClassForToken(IBinder token) {
6396        synchronized(this) {
6397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6398            if (r == null) {
6399                return null;
6400            }
6401            return r.intent.getComponent();
6402        }
6403    }
6404
6405    @Override
6406    public String getPackageForToken(IBinder token) {
6407        synchronized(this) {
6408            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6409            if (r == null) {
6410                return null;
6411            }
6412            return r.packageName;
6413        }
6414    }
6415
6416    @Override
6417    public IIntentSender getIntentSender(int type,
6418            String packageName, IBinder token, String resultWho,
6419            int requestCode, Intent[] intents, String[] resolvedTypes,
6420            int flags, Bundle options, int userId) {
6421        enforceNotIsolatedCaller("getIntentSender");
6422        // Refuse possible leaked file descriptors
6423        if (intents != null) {
6424            if (intents.length < 1) {
6425                throw new IllegalArgumentException("Intents array length must be >= 1");
6426            }
6427            for (int i=0; i<intents.length; i++) {
6428                Intent intent = intents[i];
6429                if (intent != null) {
6430                    if (intent.hasFileDescriptors()) {
6431                        throw new IllegalArgumentException("File descriptors passed in Intent");
6432                    }
6433                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6434                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6435                        throw new IllegalArgumentException(
6436                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6437                    }
6438                    intents[i] = new Intent(intent);
6439                }
6440            }
6441            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6442                throw new IllegalArgumentException(
6443                        "Intent array length does not match resolvedTypes length");
6444            }
6445        }
6446        if (options != null) {
6447            if (options.hasFileDescriptors()) {
6448                throw new IllegalArgumentException("File descriptors passed in options");
6449            }
6450        }
6451
6452        synchronized(this) {
6453            int callingUid = Binder.getCallingUid();
6454            int origUserId = userId;
6455            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6456                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6457                    ALLOW_NON_FULL, "getIntentSender", null);
6458            if (origUserId == UserHandle.USER_CURRENT) {
6459                // We don't want to evaluate this until the pending intent is
6460                // actually executed.  However, we do want to always do the
6461                // security checking for it above.
6462                userId = UserHandle.USER_CURRENT;
6463            }
6464            try {
6465                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6466                    int uid = AppGlobals.getPackageManager()
6467                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6468                    if (!UserHandle.isSameApp(callingUid, uid)) {
6469                        String msg = "Permission Denial: getIntentSender() from pid="
6470                            + Binder.getCallingPid()
6471                            + ", uid=" + Binder.getCallingUid()
6472                            + ", (need uid=" + uid + ")"
6473                            + " is not allowed to send as package " + packageName;
6474                        Slog.w(TAG, msg);
6475                        throw new SecurityException(msg);
6476                    }
6477                }
6478
6479                return getIntentSenderLocked(type, packageName, callingUid, userId,
6480                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6481
6482            } catch (RemoteException e) {
6483                throw new SecurityException(e);
6484            }
6485        }
6486    }
6487
6488    IIntentSender getIntentSenderLocked(int type, String packageName,
6489            int callingUid, int userId, IBinder token, String resultWho,
6490            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6491            Bundle options) {
6492        if (DEBUG_MU)
6493            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6494        ActivityRecord activity = null;
6495        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6496            activity = ActivityRecord.isInStackLocked(token);
6497            if (activity == null) {
6498                return null;
6499            }
6500            if (activity.finishing) {
6501                return null;
6502            }
6503        }
6504
6505        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6506        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6507        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6508        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6509                |PendingIntent.FLAG_UPDATE_CURRENT);
6510
6511        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6512                type, packageName, activity, resultWho,
6513                requestCode, intents, resolvedTypes, flags, options, userId);
6514        WeakReference<PendingIntentRecord> ref;
6515        ref = mIntentSenderRecords.get(key);
6516        PendingIntentRecord rec = ref != null ? ref.get() : null;
6517        if (rec != null) {
6518            if (!cancelCurrent) {
6519                if (updateCurrent) {
6520                    if (rec.key.requestIntent != null) {
6521                        rec.key.requestIntent.replaceExtras(intents != null ?
6522                                intents[intents.length - 1] : null);
6523                    }
6524                    if (intents != null) {
6525                        intents[intents.length-1] = rec.key.requestIntent;
6526                        rec.key.allIntents = intents;
6527                        rec.key.allResolvedTypes = resolvedTypes;
6528                    } else {
6529                        rec.key.allIntents = null;
6530                        rec.key.allResolvedTypes = null;
6531                    }
6532                }
6533                return rec;
6534            }
6535            rec.canceled = true;
6536            mIntentSenderRecords.remove(key);
6537        }
6538        if (noCreate) {
6539            return rec;
6540        }
6541        rec = new PendingIntentRecord(this, key, callingUid);
6542        mIntentSenderRecords.put(key, rec.ref);
6543        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6544            if (activity.pendingResults == null) {
6545                activity.pendingResults
6546                        = new HashSet<WeakReference<PendingIntentRecord>>();
6547            }
6548            activity.pendingResults.add(rec.ref);
6549        }
6550        return rec;
6551    }
6552
6553    @Override
6554    public void cancelIntentSender(IIntentSender sender) {
6555        if (!(sender instanceof PendingIntentRecord)) {
6556            return;
6557        }
6558        synchronized(this) {
6559            PendingIntentRecord rec = (PendingIntentRecord)sender;
6560            try {
6561                int uid = AppGlobals.getPackageManager()
6562                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6563                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6564                    String msg = "Permission Denial: cancelIntentSender() from pid="
6565                        + Binder.getCallingPid()
6566                        + ", uid=" + Binder.getCallingUid()
6567                        + " is not allowed to cancel packges "
6568                        + rec.key.packageName;
6569                    Slog.w(TAG, msg);
6570                    throw new SecurityException(msg);
6571                }
6572            } catch (RemoteException e) {
6573                throw new SecurityException(e);
6574            }
6575            cancelIntentSenderLocked(rec, true);
6576        }
6577    }
6578
6579    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6580        rec.canceled = true;
6581        mIntentSenderRecords.remove(rec.key);
6582        if (cleanActivity && rec.key.activity != null) {
6583            rec.key.activity.pendingResults.remove(rec.ref);
6584        }
6585    }
6586
6587    @Override
6588    public String getPackageForIntentSender(IIntentSender pendingResult) {
6589        if (!(pendingResult instanceof PendingIntentRecord)) {
6590            return null;
6591        }
6592        try {
6593            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6594            return res.key.packageName;
6595        } catch (ClassCastException e) {
6596        }
6597        return null;
6598    }
6599
6600    @Override
6601    public int getUidForIntentSender(IIntentSender sender) {
6602        if (sender instanceof PendingIntentRecord) {
6603            try {
6604                PendingIntentRecord res = (PendingIntentRecord)sender;
6605                return res.uid;
6606            } catch (ClassCastException e) {
6607            }
6608        }
6609        return -1;
6610    }
6611
6612    @Override
6613    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6614        if (!(pendingResult instanceof PendingIntentRecord)) {
6615            return false;
6616        }
6617        try {
6618            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6619            if (res.key.allIntents == null) {
6620                return false;
6621            }
6622            for (int i=0; i<res.key.allIntents.length; i++) {
6623                Intent intent = res.key.allIntents[i];
6624                if (intent.getPackage() != null && intent.getComponent() != null) {
6625                    return false;
6626                }
6627            }
6628            return true;
6629        } catch (ClassCastException e) {
6630        }
6631        return false;
6632    }
6633
6634    @Override
6635    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6636        if (!(pendingResult instanceof PendingIntentRecord)) {
6637            return false;
6638        }
6639        try {
6640            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6641            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6642                return true;
6643            }
6644            return false;
6645        } catch (ClassCastException e) {
6646        }
6647        return false;
6648    }
6649
6650    @Override
6651    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6652        if (!(pendingResult instanceof PendingIntentRecord)) {
6653            return null;
6654        }
6655        try {
6656            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6657            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6658        } catch (ClassCastException e) {
6659        }
6660        return null;
6661    }
6662
6663    @Override
6664    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6665        if (!(pendingResult instanceof PendingIntentRecord)) {
6666            return null;
6667        }
6668        try {
6669            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6670            Intent intent = res.key.requestIntent;
6671            if (intent != null) {
6672                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6673                        || res.lastTagPrefix.equals(prefix))) {
6674                    return res.lastTag;
6675                }
6676                res.lastTagPrefix = prefix;
6677                StringBuilder sb = new StringBuilder(128);
6678                if (prefix != null) {
6679                    sb.append(prefix);
6680                }
6681                if (intent.getAction() != null) {
6682                    sb.append(intent.getAction());
6683                } else if (intent.getComponent() != null) {
6684                    intent.getComponent().appendShortString(sb);
6685                } else {
6686                    sb.append("?");
6687                }
6688                return res.lastTag = sb.toString();
6689            }
6690        } catch (ClassCastException e) {
6691        }
6692        return null;
6693    }
6694
6695    @Override
6696    public void setProcessLimit(int max) {
6697        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6698                "setProcessLimit()");
6699        synchronized (this) {
6700            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6701            mProcessLimitOverride = max;
6702        }
6703        trimApplications();
6704    }
6705
6706    @Override
6707    public int getProcessLimit() {
6708        synchronized (this) {
6709            return mProcessLimitOverride;
6710        }
6711    }
6712
6713    void foregroundTokenDied(ForegroundToken token) {
6714        synchronized (ActivityManagerService.this) {
6715            synchronized (mPidsSelfLocked) {
6716                ForegroundToken cur
6717                    = mForegroundProcesses.get(token.pid);
6718                if (cur != token) {
6719                    return;
6720                }
6721                mForegroundProcesses.remove(token.pid);
6722                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6723                if (pr == null) {
6724                    return;
6725                }
6726                pr.forcingToForeground = null;
6727                updateProcessForegroundLocked(pr, false, false);
6728            }
6729            updateOomAdjLocked();
6730        }
6731    }
6732
6733    @Override
6734    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6735        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6736                "setProcessForeground()");
6737        synchronized(this) {
6738            boolean changed = false;
6739
6740            synchronized (mPidsSelfLocked) {
6741                ProcessRecord pr = mPidsSelfLocked.get(pid);
6742                if (pr == null && isForeground) {
6743                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6744                    return;
6745                }
6746                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6747                if (oldToken != null) {
6748                    oldToken.token.unlinkToDeath(oldToken, 0);
6749                    mForegroundProcesses.remove(pid);
6750                    if (pr != null) {
6751                        pr.forcingToForeground = null;
6752                    }
6753                    changed = true;
6754                }
6755                if (isForeground && token != null) {
6756                    ForegroundToken newToken = new ForegroundToken() {
6757                        @Override
6758                        public void binderDied() {
6759                            foregroundTokenDied(this);
6760                        }
6761                    };
6762                    newToken.pid = pid;
6763                    newToken.token = token;
6764                    try {
6765                        token.linkToDeath(newToken, 0);
6766                        mForegroundProcesses.put(pid, newToken);
6767                        pr.forcingToForeground = token;
6768                        changed = true;
6769                    } catch (RemoteException e) {
6770                        // If the process died while doing this, we will later
6771                        // do the cleanup with the process death link.
6772                    }
6773                }
6774            }
6775
6776            if (changed) {
6777                updateOomAdjLocked();
6778            }
6779        }
6780    }
6781
6782    // =========================================================
6783    // PERMISSIONS
6784    // =========================================================
6785
6786    static class PermissionController extends IPermissionController.Stub {
6787        ActivityManagerService mActivityManagerService;
6788        PermissionController(ActivityManagerService activityManagerService) {
6789            mActivityManagerService = activityManagerService;
6790        }
6791
6792        @Override
6793        public boolean checkPermission(String permission, int pid, int uid) {
6794            return mActivityManagerService.checkPermission(permission, pid,
6795                    uid) == PackageManager.PERMISSION_GRANTED;
6796        }
6797    }
6798
6799    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6800        @Override
6801        public int checkComponentPermission(String permission, int pid, int uid,
6802                int owningUid, boolean exported) {
6803            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6804                    owningUid, exported);
6805        }
6806
6807        @Override
6808        public Object getAMSLock() {
6809            return ActivityManagerService.this;
6810        }
6811    }
6812
6813    /**
6814     * This can be called with or without the global lock held.
6815     */
6816    int checkComponentPermission(String permission, int pid, int uid,
6817            int owningUid, boolean exported) {
6818        // We might be performing an operation on behalf of an indirect binder
6819        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6820        // client identity accordingly before proceeding.
6821        Identity tlsIdentity = sCallerIdentity.get();
6822        if (tlsIdentity != null) {
6823            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6824                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6825            uid = tlsIdentity.uid;
6826            pid = tlsIdentity.pid;
6827        }
6828
6829        if (pid == MY_PID) {
6830            return PackageManager.PERMISSION_GRANTED;
6831        }
6832
6833        return ActivityManager.checkComponentPermission(permission, uid,
6834                owningUid, exported);
6835    }
6836
6837    /**
6838     * As the only public entry point for permissions checking, this method
6839     * can enforce the semantic that requesting a check on a null global
6840     * permission is automatically denied.  (Internally a null permission
6841     * string is used when calling {@link #checkComponentPermission} in cases
6842     * when only uid-based security is needed.)
6843     *
6844     * This can be called with or without the global lock held.
6845     */
6846    @Override
6847    public int checkPermission(String permission, int pid, int uid) {
6848        if (permission == null) {
6849            return PackageManager.PERMISSION_DENIED;
6850        }
6851        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6852    }
6853
6854    /**
6855     * Binder IPC calls go through the public entry point.
6856     * This can be called with or without the global lock held.
6857     */
6858    int checkCallingPermission(String permission) {
6859        return checkPermission(permission,
6860                Binder.getCallingPid(),
6861                UserHandle.getAppId(Binder.getCallingUid()));
6862    }
6863
6864    /**
6865     * This can be called with or without the global lock held.
6866     */
6867    void enforceCallingPermission(String permission, String func) {
6868        if (checkCallingPermission(permission)
6869                == PackageManager.PERMISSION_GRANTED) {
6870            return;
6871        }
6872
6873        String msg = "Permission Denial: " + func + " from pid="
6874                + Binder.getCallingPid()
6875                + ", uid=" + Binder.getCallingUid()
6876                + " requires " + permission;
6877        Slog.w(TAG, msg);
6878        throw new SecurityException(msg);
6879    }
6880
6881    /**
6882     * Determine if UID is holding permissions required to access {@link Uri} in
6883     * the given {@link ProviderInfo}. Final permission checking is always done
6884     * in {@link ContentProvider}.
6885     */
6886    private final boolean checkHoldingPermissionsLocked(
6887            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6888        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6889                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6890        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6891            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6892                    != PERMISSION_GRANTED) {
6893                return false;
6894            }
6895        }
6896        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6897    }
6898
6899    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6900            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6901        if (pi.applicationInfo.uid == uid) {
6902            return true;
6903        } else if (!pi.exported) {
6904            return false;
6905        }
6906
6907        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6908        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6909        try {
6910            // check if target holds top-level <provider> permissions
6911            if (!readMet && pi.readPermission != null && considerUidPermissions
6912                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6913                readMet = true;
6914            }
6915            if (!writeMet && pi.writePermission != null && considerUidPermissions
6916                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6917                writeMet = true;
6918            }
6919
6920            // track if unprotected read/write is allowed; any denied
6921            // <path-permission> below removes this ability
6922            boolean allowDefaultRead = pi.readPermission == null;
6923            boolean allowDefaultWrite = pi.writePermission == null;
6924
6925            // check if target holds any <path-permission> that match uri
6926            final PathPermission[] pps = pi.pathPermissions;
6927            if (pps != null) {
6928                final String path = grantUri.uri.getPath();
6929                int i = pps.length;
6930                while (i > 0 && (!readMet || !writeMet)) {
6931                    i--;
6932                    PathPermission pp = pps[i];
6933                    if (pp.match(path)) {
6934                        if (!readMet) {
6935                            final String pprperm = pp.getReadPermission();
6936                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6937                                    + pprperm + " for " + pp.getPath()
6938                                    + ": match=" + pp.match(path)
6939                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6940                            if (pprperm != null) {
6941                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6942                                        == PERMISSION_GRANTED) {
6943                                    readMet = true;
6944                                } else {
6945                                    allowDefaultRead = false;
6946                                }
6947                            }
6948                        }
6949                        if (!writeMet) {
6950                            final String ppwperm = pp.getWritePermission();
6951                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6952                                    + ppwperm + " for " + pp.getPath()
6953                                    + ": match=" + pp.match(path)
6954                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6955                            if (ppwperm != null) {
6956                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6957                                        == PERMISSION_GRANTED) {
6958                                    writeMet = true;
6959                                } else {
6960                                    allowDefaultWrite = false;
6961                                }
6962                            }
6963                        }
6964                    }
6965                }
6966            }
6967
6968            // grant unprotected <provider> read/write, if not blocked by
6969            // <path-permission> above
6970            if (allowDefaultRead) readMet = true;
6971            if (allowDefaultWrite) writeMet = true;
6972
6973        } catch (RemoteException e) {
6974            return false;
6975        }
6976
6977        return readMet && writeMet;
6978    }
6979
6980    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6981        ProviderInfo pi = null;
6982        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6983        if (cpr != null) {
6984            pi = cpr.info;
6985        } else {
6986            try {
6987                pi = AppGlobals.getPackageManager().resolveContentProvider(
6988                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6989            } catch (RemoteException ex) {
6990            }
6991        }
6992        return pi;
6993    }
6994
6995    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6996        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6997        if (targetUris != null) {
6998            return targetUris.get(grantUri);
6999        }
7000        return null;
7001    }
7002
7003    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7004            String targetPkg, int targetUid, GrantUri grantUri) {
7005        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7006        if (targetUris == null) {
7007            targetUris = Maps.newArrayMap();
7008            mGrantedUriPermissions.put(targetUid, targetUris);
7009        }
7010
7011        UriPermission perm = targetUris.get(grantUri);
7012        if (perm == null) {
7013            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7014            targetUris.put(grantUri, perm);
7015        }
7016
7017        return perm;
7018    }
7019
7020    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7021            final int modeFlags) {
7022        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7023        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7024                : UriPermission.STRENGTH_OWNED;
7025
7026        // Root gets to do everything.
7027        if (uid == 0) {
7028            return true;
7029        }
7030
7031        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7032        if (perms == null) return false;
7033
7034        // First look for exact match
7035        final UriPermission exactPerm = perms.get(grantUri);
7036        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7037            return true;
7038        }
7039
7040        // No exact match, look for prefixes
7041        final int N = perms.size();
7042        for (int i = 0; i < N; i++) {
7043            final UriPermission perm = perms.valueAt(i);
7044            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7045                    && perm.getStrength(modeFlags) >= minStrength) {
7046                return true;
7047            }
7048        }
7049
7050        return false;
7051    }
7052
7053    /**
7054     * @param uri This uri must NOT contain an embedded userId.
7055     * @param userId The userId in which the uri is to be resolved.
7056     */
7057    @Override
7058    public int checkUriPermission(Uri uri, int pid, int uid,
7059            final int modeFlags, int userId) {
7060        enforceNotIsolatedCaller("checkUriPermission");
7061
7062        // Another redirected-binder-call permissions check as in
7063        // {@link checkComponentPermission}.
7064        Identity tlsIdentity = sCallerIdentity.get();
7065        if (tlsIdentity != null) {
7066            uid = tlsIdentity.uid;
7067            pid = tlsIdentity.pid;
7068        }
7069
7070        // Our own process gets to do everything.
7071        if (pid == MY_PID) {
7072            return PackageManager.PERMISSION_GRANTED;
7073        }
7074        synchronized (this) {
7075            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7076                    ? PackageManager.PERMISSION_GRANTED
7077                    : PackageManager.PERMISSION_DENIED;
7078        }
7079    }
7080
7081    /**
7082     * Check if the targetPkg can be granted permission to access uri by
7083     * the callingUid using the given modeFlags.  Throws a security exception
7084     * if callingUid is not allowed to do this.  Returns the uid of the target
7085     * if the URI permission grant should be performed; returns -1 if it is not
7086     * needed (for example targetPkg already has permission to access the URI).
7087     * If you already know the uid of the target, you can supply it in
7088     * lastTargetUid else set that to -1.
7089     */
7090    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7091            final int modeFlags, int lastTargetUid) {
7092        if (!Intent.isAccessUriMode(modeFlags)) {
7093            return -1;
7094        }
7095
7096        if (targetPkg != null) {
7097            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7098                    "Checking grant " + targetPkg + " permission to " + grantUri);
7099        }
7100
7101        final IPackageManager pm = AppGlobals.getPackageManager();
7102
7103        // If this is not a content: uri, we can't do anything with it.
7104        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7105            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7106                    "Can't grant URI permission for non-content URI: " + grantUri);
7107            return -1;
7108        }
7109
7110        final String authority = grantUri.uri.getAuthority();
7111        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7112        if (pi == null) {
7113            Slog.w(TAG, "No content provider found for permission check: " +
7114                    grantUri.uri.toSafeString());
7115            return -1;
7116        }
7117
7118        int targetUid = lastTargetUid;
7119        if (targetUid < 0 && targetPkg != null) {
7120            try {
7121                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7122                if (targetUid < 0) {
7123                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7124                            "Can't grant URI permission no uid for: " + targetPkg);
7125                    return -1;
7126                }
7127            } catch (RemoteException ex) {
7128                return -1;
7129            }
7130        }
7131
7132        if (targetUid >= 0) {
7133            // First...  does the target actually need this permission?
7134            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7135                // No need to grant the target this permission.
7136                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7137                        "Target " + targetPkg + " already has full permission to " + grantUri);
7138                return -1;
7139            }
7140        } else {
7141            // First...  there is no target package, so can anyone access it?
7142            boolean allowed = pi.exported;
7143            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7144                if (pi.readPermission != null) {
7145                    allowed = false;
7146                }
7147            }
7148            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7149                if (pi.writePermission != null) {
7150                    allowed = false;
7151                }
7152            }
7153            if (allowed) {
7154                return -1;
7155            }
7156        }
7157
7158        /* There is a special cross user grant if:
7159         * - The target is on another user.
7160         * - Apps on the current user can access the uri without any uid permissions.
7161         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7162         * grant uri permissions.
7163         */
7164        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7165                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7166                modeFlags, false /*without considering the uid permissions*/);
7167
7168        // Second...  is the provider allowing granting of URI permissions?
7169        if (!specialCrossUserGrant) {
7170            if (!pi.grantUriPermissions) {
7171                throw new SecurityException("Provider " + pi.packageName
7172                        + "/" + pi.name
7173                        + " does not allow granting of Uri permissions (uri "
7174                        + grantUri + ")");
7175            }
7176            if (pi.uriPermissionPatterns != null) {
7177                final int N = pi.uriPermissionPatterns.length;
7178                boolean allowed = false;
7179                for (int i=0; i<N; i++) {
7180                    if (pi.uriPermissionPatterns[i] != null
7181                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7182                        allowed = true;
7183                        break;
7184                    }
7185                }
7186                if (!allowed) {
7187                    throw new SecurityException("Provider " + pi.packageName
7188                            + "/" + pi.name
7189                            + " does not allow granting of permission to path of Uri "
7190                            + grantUri);
7191                }
7192            }
7193        }
7194
7195        // Third...  does the caller itself have permission to access
7196        // this uri?
7197        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7198            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7199                // Require they hold a strong enough Uri permission
7200                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7201                    throw new SecurityException("Uid " + callingUid
7202                            + " does not have permission to uri " + grantUri);
7203                }
7204            }
7205        }
7206        return targetUid;
7207    }
7208
7209    /**
7210     * @param uri This uri must NOT contain an embedded userId.
7211     * @param userId The userId in which the uri is to be resolved.
7212     */
7213    @Override
7214    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7215            final int modeFlags, int userId) {
7216        enforceNotIsolatedCaller("checkGrantUriPermission");
7217        synchronized(this) {
7218            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7219                    new GrantUri(userId, uri, false), modeFlags, -1);
7220        }
7221    }
7222
7223    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7224            final int modeFlags, UriPermissionOwner owner) {
7225        if (!Intent.isAccessUriMode(modeFlags)) {
7226            return;
7227        }
7228
7229        // So here we are: the caller has the assumed permission
7230        // to the uri, and the target doesn't.  Let's now give this to
7231        // the target.
7232
7233        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7234                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7235
7236        final String authority = grantUri.uri.getAuthority();
7237        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7238        if (pi == null) {
7239            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7240            return;
7241        }
7242
7243        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7244            grantUri.prefix = true;
7245        }
7246        final UriPermission perm = findOrCreateUriPermissionLocked(
7247                pi.packageName, targetPkg, targetUid, grantUri);
7248        perm.grantModes(modeFlags, owner);
7249    }
7250
7251    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7252            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7253        if (targetPkg == null) {
7254            throw new NullPointerException("targetPkg");
7255        }
7256        int targetUid;
7257        final IPackageManager pm = AppGlobals.getPackageManager();
7258        try {
7259            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7260        } catch (RemoteException ex) {
7261            return;
7262        }
7263
7264        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7265                targetUid);
7266        if (targetUid < 0) {
7267            return;
7268        }
7269
7270        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7271                owner);
7272    }
7273
7274    static class NeededUriGrants extends ArrayList<GrantUri> {
7275        final String targetPkg;
7276        final int targetUid;
7277        final int flags;
7278
7279        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7280            this.targetPkg = targetPkg;
7281            this.targetUid = targetUid;
7282            this.flags = flags;
7283        }
7284    }
7285
7286    /**
7287     * Like checkGrantUriPermissionLocked, but takes an Intent.
7288     */
7289    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7290            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7291        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7292                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7293                + " clip=" + (intent != null ? intent.getClipData() : null)
7294                + " from " + intent + "; flags=0x"
7295                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7296
7297        if (targetPkg == null) {
7298            throw new NullPointerException("targetPkg");
7299        }
7300
7301        if (intent == null) {
7302            return null;
7303        }
7304        Uri data = intent.getData();
7305        ClipData clip = intent.getClipData();
7306        if (data == null && clip == null) {
7307            return null;
7308        }
7309        // Default userId for uris in the intent (if they don't specify it themselves)
7310        int contentUserHint = intent.getContentUserHint();
7311        if (contentUserHint == UserHandle.USER_CURRENT) {
7312            contentUserHint = UserHandle.getUserId(callingUid);
7313        }
7314        final IPackageManager pm = AppGlobals.getPackageManager();
7315        int targetUid;
7316        if (needed != null) {
7317            targetUid = needed.targetUid;
7318        } else {
7319            try {
7320                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7321            } catch (RemoteException ex) {
7322                return null;
7323            }
7324            if (targetUid < 0) {
7325                if (DEBUG_URI_PERMISSION) {
7326                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7327                            + " on user " + targetUserId);
7328                }
7329                return null;
7330            }
7331        }
7332        if (data != null) {
7333            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7334            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7335                    targetUid);
7336            if (targetUid > 0) {
7337                if (needed == null) {
7338                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7339                }
7340                needed.add(grantUri);
7341            }
7342        }
7343        if (clip != null) {
7344            for (int i=0; i<clip.getItemCount(); i++) {
7345                Uri uri = clip.getItemAt(i).getUri();
7346                if (uri != null) {
7347                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7348                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7349                            targetUid);
7350                    if (targetUid > 0) {
7351                        if (needed == null) {
7352                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7353                        }
7354                        needed.add(grantUri);
7355                    }
7356                } else {
7357                    Intent clipIntent = clip.getItemAt(i).getIntent();
7358                    if (clipIntent != null) {
7359                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7360                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7361                        if (newNeeded != null) {
7362                            needed = newNeeded;
7363                        }
7364                    }
7365                }
7366            }
7367        }
7368
7369        return needed;
7370    }
7371
7372    /**
7373     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7374     */
7375    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7376            UriPermissionOwner owner) {
7377        if (needed != null) {
7378            for (int i=0; i<needed.size(); i++) {
7379                GrantUri grantUri = needed.get(i);
7380                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7381                        grantUri, needed.flags, owner);
7382            }
7383        }
7384    }
7385
7386    void grantUriPermissionFromIntentLocked(int callingUid,
7387            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7388        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7389                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7390        if (needed == null) {
7391            return;
7392        }
7393
7394        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7395    }
7396
7397    /**
7398     * @param uri This uri must NOT contain an embedded userId.
7399     * @param userId The userId in which the uri is to be resolved.
7400     */
7401    @Override
7402    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7403            final int modeFlags, int userId) {
7404        enforceNotIsolatedCaller("grantUriPermission");
7405        GrantUri grantUri = new GrantUri(userId, uri, false);
7406        synchronized(this) {
7407            final ProcessRecord r = getRecordForAppLocked(caller);
7408            if (r == null) {
7409                throw new SecurityException("Unable to find app for caller "
7410                        + caller
7411                        + " when granting permission to uri " + grantUri);
7412            }
7413            if (targetPkg == null) {
7414                throw new IllegalArgumentException("null target");
7415            }
7416            if (grantUri == null) {
7417                throw new IllegalArgumentException("null uri");
7418            }
7419
7420            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7421                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7422                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7423                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7424
7425            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7426                    UserHandle.getUserId(r.uid));
7427        }
7428    }
7429
7430    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7431        if (perm.modeFlags == 0) {
7432            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7433                    perm.targetUid);
7434            if (perms != null) {
7435                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7436                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7437
7438                perms.remove(perm.uri);
7439                if (perms.isEmpty()) {
7440                    mGrantedUriPermissions.remove(perm.targetUid);
7441                }
7442            }
7443        }
7444    }
7445
7446    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7447        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7448
7449        final IPackageManager pm = AppGlobals.getPackageManager();
7450        final String authority = grantUri.uri.getAuthority();
7451        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7452        if (pi == null) {
7453            Slog.w(TAG, "No content provider found for permission revoke: "
7454                    + grantUri.toSafeString());
7455            return;
7456        }
7457
7458        // Does the caller have this permission on the URI?
7459        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7460            // Right now, if you are not the original owner of the permission,
7461            // you are not allowed to revoke it.
7462            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7463                throw new SecurityException("Uid " + callingUid
7464                        + " does not have permission to uri " + grantUri);
7465            //}
7466        }
7467
7468        boolean persistChanged = false;
7469
7470        // Go through all of the permissions and remove any that match.
7471        int N = mGrantedUriPermissions.size();
7472        for (int i = 0; i < N; i++) {
7473            final int targetUid = mGrantedUriPermissions.keyAt(i);
7474            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7475
7476            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7477                final UriPermission perm = it.next();
7478                if (perm.uri.sourceUserId == grantUri.sourceUserId
7479                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7480                    if (DEBUG_URI_PERMISSION)
7481                        Slog.v(TAG,
7482                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7483                    persistChanged |= perm.revokeModes(
7484                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7485                    if (perm.modeFlags == 0) {
7486                        it.remove();
7487                    }
7488                }
7489            }
7490
7491            if (perms.isEmpty()) {
7492                mGrantedUriPermissions.remove(targetUid);
7493                N--;
7494                i--;
7495            }
7496        }
7497
7498        if (persistChanged) {
7499            schedulePersistUriGrants();
7500        }
7501    }
7502
7503    /**
7504     * @param uri This uri must NOT contain an embedded userId.
7505     * @param userId The userId in which the uri is to be resolved.
7506     */
7507    @Override
7508    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7509            int userId) {
7510        enforceNotIsolatedCaller("revokeUriPermission");
7511        synchronized(this) {
7512            final ProcessRecord r = getRecordForAppLocked(caller);
7513            if (r == null) {
7514                throw new SecurityException("Unable to find app for caller "
7515                        + caller
7516                        + " when revoking permission to uri " + uri);
7517            }
7518            if (uri == null) {
7519                Slog.w(TAG, "revokeUriPermission: null uri");
7520                return;
7521            }
7522
7523            if (!Intent.isAccessUriMode(modeFlags)) {
7524                return;
7525            }
7526
7527            final IPackageManager pm = AppGlobals.getPackageManager();
7528            final String authority = uri.getAuthority();
7529            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7530            if (pi == null) {
7531                Slog.w(TAG, "No content provider found for permission revoke: "
7532                        + uri.toSafeString());
7533                return;
7534            }
7535
7536            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7537        }
7538    }
7539
7540    /**
7541     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7542     * given package.
7543     *
7544     * @param packageName Package name to match, or {@code null} to apply to all
7545     *            packages.
7546     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7547     *            to all users.
7548     * @param persistable If persistable grants should be removed.
7549     */
7550    private void removeUriPermissionsForPackageLocked(
7551            String packageName, int userHandle, boolean persistable) {
7552        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7553            throw new IllegalArgumentException("Must narrow by either package or user");
7554        }
7555
7556        boolean persistChanged = false;
7557
7558        int N = mGrantedUriPermissions.size();
7559        for (int i = 0; i < N; i++) {
7560            final int targetUid = mGrantedUriPermissions.keyAt(i);
7561            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7562
7563            // Only inspect grants matching user
7564            if (userHandle == UserHandle.USER_ALL
7565                    || userHandle == UserHandle.getUserId(targetUid)) {
7566                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7567                    final UriPermission perm = it.next();
7568
7569                    // Only inspect grants matching package
7570                    if (packageName == null || perm.sourcePkg.equals(packageName)
7571                            || perm.targetPkg.equals(packageName)) {
7572                        persistChanged |= perm.revokeModes(
7573                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7574
7575                        // Only remove when no modes remain; any persisted grants
7576                        // will keep this alive.
7577                        if (perm.modeFlags == 0) {
7578                            it.remove();
7579                        }
7580                    }
7581                }
7582
7583                if (perms.isEmpty()) {
7584                    mGrantedUriPermissions.remove(targetUid);
7585                    N--;
7586                    i--;
7587                }
7588            }
7589        }
7590
7591        if (persistChanged) {
7592            schedulePersistUriGrants();
7593        }
7594    }
7595
7596    @Override
7597    public IBinder newUriPermissionOwner(String name) {
7598        enforceNotIsolatedCaller("newUriPermissionOwner");
7599        synchronized(this) {
7600            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7601            return owner.getExternalTokenLocked();
7602        }
7603    }
7604
7605    /**
7606     * @param uri This uri must NOT contain an embedded userId.
7607     * @param sourceUserId The userId in which the uri is to be resolved.
7608     * @param targetUserId The userId of the app that receives the grant.
7609     */
7610    @Override
7611    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7612            final int modeFlags, int sourceUserId, int targetUserId) {
7613        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7614                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7615        synchronized(this) {
7616            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7617            if (owner == null) {
7618                throw new IllegalArgumentException("Unknown owner: " + token);
7619            }
7620            if (fromUid != Binder.getCallingUid()) {
7621                if (Binder.getCallingUid() != Process.myUid()) {
7622                    // Only system code can grant URI permissions on behalf
7623                    // of other users.
7624                    throw new SecurityException("nice try");
7625                }
7626            }
7627            if (targetPkg == null) {
7628                throw new IllegalArgumentException("null target");
7629            }
7630            if (uri == null) {
7631                throw new IllegalArgumentException("null uri");
7632            }
7633
7634            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7635                    modeFlags, owner, targetUserId);
7636        }
7637    }
7638
7639    /**
7640     * @param uri This uri must NOT contain an embedded userId.
7641     * @param userId The userId in which the uri is to be resolved.
7642     */
7643    @Override
7644    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7645        synchronized(this) {
7646            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7647            if (owner == null) {
7648                throw new IllegalArgumentException("Unknown owner: " + token);
7649            }
7650
7651            if (uri == null) {
7652                owner.removeUriPermissionsLocked(mode);
7653            } else {
7654                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7655            }
7656        }
7657    }
7658
7659    private void schedulePersistUriGrants() {
7660        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7661            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7662                    10 * DateUtils.SECOND_IN_MILLIS);
7663        }
7664    }
7665
7666    private void writeGrantedUriPermissions() {
7667        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7668
7669        // Snapshot permissions so we can persist without lock
7670        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7671        synchronized (this) {
7672            final int size = mGrantedUriPermissions.size();
7673            for (int i = 0; i < size; i++) {
7674                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7675                for (UriPermission perm : perms.values()) {
7676                    if (perm.persistedModeFlags != 0) {
7677                        persist.add(perm.snapshot());
7678                    }
7679                }
7680            }
7681        }
7682
7683        FileOutputStream fos = null;
7684        try {
7685            fos = mGrantFile.startWrite();
7686
7687            XmlSerializer out = new FastXmlSerializer();
7688            out.setOutput(fos, "utf-8");
7689            out.startDocument(null, true);
7690            out.startTag(null, TAG_URI_GRANTS);
7691            for (UriPermission.Snapshot perm : persist) {
7692                out.startTag(null, TAG_URI_GRANT);
7693                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7694                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7695                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7696                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7697                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7698                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7699                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7700                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7701                out.endTag(null, TAG_URI_GRANT);
7702            }
7703            out.endTag(null, TAG_URI_GRANTS);
7704            out.endDocument();
7705
7706            mGrantFile.finishWrite(fos);
7707        } catch (IOException e) {
7708            if (fos != null) {
7709                mGrantFile.failWrite(fos);
7710            }
7711        }
7712    }
7713
7714    private void readGrantedUriPermissionsLocked() {
7715        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7716
7717        final long now = System.currentTimeMillis();
7718
7719        FileInputStream fis = null;
7720        try {
7721            fis = mGrantFile.openRead();
7722            final XmlPullParser in = Xml.newPullParser();
7723            in.setInput(fis, null);
7724
7725            int type;
7726            while ((type = in.next()) != END_DOCUMENT) {
7727                final String tag = in.getName();
7728                if (type == START_TAG) {
7729                    if (TAG_URI_GRANT.equals(tag)) {
7730                        final int sourceUserId;
7731                        final int targetUserId;
7732                        final int userHandle = readIntAttribute(in,
7733                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7734                        if (userHandle != UserHandle.USER_NULL) {
7735                            // For backwards compatibility.
7736                            sourceUserId = userHandle;
7737                            targetUserId = userHandle;
7738                        } else {
7739                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7740                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7741                        }
7742                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7743                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7744                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7745                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7746                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7747                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7748
7749                        // Sanity check that provider still belongs to source package
7750                        final ProviderInfo pi = getProviderInfoLocked(
7751                                uri.getAuthority(), sourceUserId);
7752                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7753                            int targetUid = -1;
7754                            try {
7755                                targetUid = AppGlobals.getPackageManager()
7756                                        .getPackageUid(targetPkg, targetUserId);
7757                            } catch (RemoteException e) {
7758                            }
7759                            if (targetUid != -1) {
7760                                final UriPermission perm = findOrCreateUriPermissionLocked(
7761                                        sourcePkg, targetPkg, targetUid,
7762                                        new GrantUri(sourceUserId, uri, prefix));
7763                                perm.initPersistedModes(modeFlags, createdTime);
7764                            }
7765                        } else {
7766                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7767                                    + " but instead found " + pi);
7768                        }
7769                    }
7770                }
7771            }
7772        } catch (FileNotFoundException e) {
7773            // Missing grants is okay
7774        } catch (IOException e) {
7775            Log.wtf(TAG, "Failed reading Uri grants", e);
7776        } catch (XmlPullParserException e) {
7777            Log.wtf(TAG, "Failed reading Uri grants", e);
7778        } finally {
7779            IoUtils.closeQuietly(fis);
7780        }
7781    }
7782
7783    /**
7784     * @param uri This uri must NOT contain an embedded userId.
7785     * @param userId The userId in which the uri is to be resolved.
7786     */
7787    @Override
7788    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7789        enforceNotIsolatedCaller("takePersistableUriPermission");
7790
7791        Preconditions.checkFlagsArgument(modeFlags,
7792                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7793
7794        synchronized (this) {
7795            final int callingUid = Binder.getCallingUid();
7796            boolean persistChanged = false;
7797            GrantUri grantUri = new GrantUri(userId, uri, false);
7798
7799            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7800                    new GrantUri(userId, uri, false));
7801            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7802                    new GrantUri(userId, uri, true));
7803
7804            final boolean exactValid = (exactPerm != null)
7805                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7806            final boolean prefixValid = (prefixPerm != null)
7807                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7808
7809            if (!(exactValid || prefixValid)) {
7810                throw new SecurityException("No persistable permission grants found for UID "
7811                        + callingUid + " and Uri " + grantUri.toSafeString());
7812            }
7813
7814            if (exactValid) {
7815                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7816            }
7817            if (prefixValid) {
7818                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7819            }
7820
7821            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7822
7823            if (persistChanged) {
7824                schedulePersistUriGrants();
7825            }
7826        }
7827    }
7828
7829    /**
7830     * @param uri This uri must NOT contain an embedded userId.
7831     * @param userId The userId in which the uri is to be resolved.
7832     */
7833    @Override
7834    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7835        enforceNotIsolatedCaller("releasePersistableUriPermission");
7836
7837        Preconditions.checkFlagsArgument(modeFlags,
7838                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7839
7840        synchronized (this) {
7841            final int callingUid = Binder.getCallingUid();
7842            boolean persistChanged = false;
7843
7844            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7845                    new GrantUri(userId, uri, false));
7846            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7847                    new GrantUri(userId, uri, true));
7848            if (exactPerm == null && prefixPerm == null) {
7849                throw new SecurityException("No permission grants found for UID " + callingUid
7850                        + " and Uri " + uri.toSafeString());
7851            }
7852
7853            if (exactPerm != null) {
7854                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7855                removeUriPermissionIfNeededLocked(exactPerm);
7856            }
7857            if (prefixPerm != null) {
7858                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7859                removeUriPermissionIfNeededLocked(prefixPerm);
7860            }
7861
7862            if (persistChanged) {
7863                schedulePersistUriGrants();
7864            }
7865        }
7866    }
7867
7868    /**
7869     * Prune any older {@link UriPermission} for the given UID until outstanding
7870     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7871     *
7872     * @return if any mutations occured that require persisting.
7873     */
7874    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7875        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7876        if (perms == null) return false;
7877        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7878
7879        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7880        for (UriPermission perm : perms.values()) {
7881            if (perm.persistedModeFlags != 0) {
7882                persisted.add(perm);
7883            }
7884        }
7885
7886        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7887        if (trimCount <= 0) return false;
7888
7889        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7890        for (int i = 0; i < trimCount; i++) {
7891            final UriPermission perm = persisted.get(i);
7892
7893            if (DEBUG_URI_PERMISSION) {
7894                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7895            }
7896
7897            perm.releasePersistableModes(~0);
7898            removeUriPermissionIfNeededLocked(perm);
7899        }
7900
7901        return true;
7902    }
7903
7904    @Override
7905    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7906            String packageName, boolean incoming) {
7907        enforceNotIsolatedCaller("getPersistedUriPermissions");
7908        Preconditions.checkNotNull(packageName, "packageName");
7909
7910        final int callingUid = Binder.getCallingUid();
7911        final IPackageManager pm = AppGlobals.getPackageManager();
7912        try {
7913            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7914            if (packageUid != callingUid) {
7915                throw new SecurityException(
7916                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7917            }
7918        } catch (RemoteException e) {
7919            throw new SecurityException("Failed to verify package name ownership");
7920        }
7921
7922        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7923        synchronized (this) {
7924            if (incoming) {
7925                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7926                        callingUid);
7927                if (perms == null) {
7928                    Slog.w(TAG, "No permission grants found for " + packageName);
7929                } else {
7930                    for (UriPermission perm : perms.values()) {
7931                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7932                            result.add(perm.buildPersistedPublicApiObject());
7933                        }
7934                    }
7935                }
7936            } else {
7937                final int size = mGrantedUriPermissions.size();
7938                for (int i = 0; i < size; i++) {
7939                    final ArrayMap<GrantUri, UriPermission> perms =
7940                            mGrantedUriPermissions.valueAt(i);
7941                    for (UriPermission perm : perms.values()) {
7942                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7943                            result.add(perm.buildPersistedPublicApiObject());
7944                        }
7945                    }
7946                }
7947            }
7948        }
7949        return new ParceledListSlice<android.content.UriPermission>(result);
7950    }
7951
7952    @Override
7953    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7954        synchronized (this) {
7955            ProcessRecord app =
7956                who != null ? getRecordForAppLocked(who) : null;
7957            if (app == null) return;
7958
7959            Message msg = Message.obtain();
7960            msg.what = WAIT_FOR_DEBUGGER_MSG;
7961            msg.obj = app;
7962            msg.arg1 = waiting ? 1 : 0;
7963            mHandler.sendMessage(msg);
7964        }
7965    }
7966
7967    @Override
7968    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7969        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7970        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7971        outInfo.availMem = Process.getFreeMemory();
7972        outInfo.totalMem = Process.getTotalMemory();
7973        outInfo.threshold = homeAppMem;
7974        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7975        outInfo.hiddenAppThreshold = cachedAppMem;
7976        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7977                ProcessList.SERVICE_ADJ);
7978        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7979                ProcessList.VISIBLE_APP_ADJ);
7980        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7981                ProcessList.FOREGROUND_APP_ADJ);
7982    }
7983
7984    // =========================================================
7985    // TASK MANAGEMENT
7986    // =========================================================
7987
7988    @Override
7989    public List<IAppTask> getAppTasks(String callingPackage) {
7990        int callingUid = Binder.getCallingUid();
7991        long ident = Binder.clearCallingIdentity();
7992
7993        synchronized(this) {
7994            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7995            try {
7996                if (localLOGV) Slog.v(TAG, "getAppTasks");
7997
7998                final int N = mRecentTasks.size();
7999                for (int i = 0; i < N; i++) {
8000                    TaskRecord tr = mRecentTasks.get(i);
8001                    // Skip tasks that do not match the caller.  We don't need to verify
8002                    // callingPackage, because we are also limiting to callingUid and know
8003                    // that will limit to the correct security sandbox.
8004                    if (tr.effectiveUid != callingUid) {
8005                        continue;
8006                    }
8007                    Intent intent = tr.getBaseIntent();
8008                    if (intent == null ||
8009                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8010                        continue;
8011                    }
8012                    ActivityManager.RecentTaskInfo taskInfo =
8013                            createRecentTaskInfoFromTaskRecord(tr);
8014                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8015                    list.add(taskImpl);
8016                }
8017            } finally {
8018                Binder.restoreCallingIdentity(ident);
8019            }
8020            return list;
8021        }
8022    }
8023
8024    @Override
8025    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8026        final int callingUid = Binder.getCallingUid();
8027        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8028
8029        synchronized(this) {
8030            if (localLOGV) Slog.v(
8031                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8032
8033            final boolean allowed = checkCallingPermission(
8034                    android.Manifest.permission.GET_TASKS)
8035                    == PackageManager.PERMISSION_GRANTED;
8036            if (!allowed) {
8037                Slog.w(TAG, "getTasks: caller " + callingUid
8038                        + " does not hold GET_TASKS; limiting output");
8039            }
8040
8041            // TODO: Improve with MRU list from all ActivityStacks.
8042            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8043        }
8044
8045        return list;
8046    }
8047
8048    TaskRecord getMostRecentTask() {
8049        return mRecentTasks.get(0);
8050    }
8051
8052    /**
8053     * Creates a new RecentTaskInfo from a TaskRecord.
8054     */
8055    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8056        // Update the task description to reflect any changes in the task stack
8057        tr.updateTaskDescription();
8058
8059        // Compose the recent task info
8060        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8061        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8062        rti.persistentId = tr.taskId;
8063        rti.baseIntent = new Intent(tr.getBaseIntent());
8064        rti.origActivity = tr.origActivity;
8065        rti.description = tr.lastDescription;
8066        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8067        rti.userId = tr.userId;
8068        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8069        rti.firstActiveTime = tr.firstActiveTime;
8070        rti.lastActiveTime = tr.lastActiveTime;
8071        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8072        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8073        return rti;
8074    }
8075
8076    @Override
8077    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8078        final int callingUid = Binder.getCallingUid();
8079        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8080                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8081
8082        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8083        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8084        synchronized (this) {
8085            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8086                    == PackageManager.PERMISSION_GRANTED;
8087            if (!allowed) {
8088                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8089                        + " does not hold GET_TASKS; limiting output");
8090            }
8091            final boolean detailed = checkCallingPermission(
8092                    android.Manifest.permission.GET_DETAILED_TASKS)
8093                    == PackageManager.PERMISSION_GRANTED;
8094
8095            final int N = mRecentTasks.size();
8096            ArrayList<ActivityManager.RecentTaskInfo> res
8097                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8098                            maxNum < N ? maxNum : N);
8099
8100            final Set<Integer> includedUsers;
8101            if (includeProfiles) {
8102                includedUsers = getProfileIdsLocked(userId);
8103            } else {
8104                includedUsers = new HashSet<Integer>();
8105            }
8106            includedUsers.add(Integer.valueOf(userId));
8107
8108            for (int i=0; i<N && maxNum > 0; i++) {
8109                TaskRecord tr = mRecentTasks.get(i);
8110                // Only add calling user or related users recent tasks
8111                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8112                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8113                    continue;
8114                }
8115
8116                // Return the entry if desired by the caller.  We always return
8117                // the first entry, because callers always expect this to be the
8118                // foreground app.  We may filter others if the caller has
8119                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8120                // we should exclude the entry.
8121
8122                if (i == 0
8123                        || withExcluded
8124                        || (tr.intent == null)
8125                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8126                                == 0)) {
8127                    if (!allowed) {
8128                        // If the caller doesn't have the GET_TASKS permission, then only
8129                        // allow them to see a small subset of tasks -- their own and home.
8130                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8131                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8132                            continue;
8133                        }
8134                    }
8135                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8136                        if (tr.stack != null && tr.stack.isHomeStack()) {
8137                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8138                            continue;
8139                        }
8140                    }
8141                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8142                        // Don't include auto remove tasks that are finished or finishing.
8143                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8144                                + tr);
8145                        continue;
8146                    }
8147                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8148                            && !tr.isAvailable) {
8149                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8150                        continue;
8151                    }
8152
8153                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8154                    if (!detailed) {
8155                        rti.baseIntent.replaceExtras((Bundle)null);
8156                    }
8157
8158                    res.add(rti);
8159                    maxNum--;
8160                }
8161            }
8162            return res;
8163        }
8164    }
8165
8166    private TaskRecord recentTaskForIdLocked(int id) {
8167        final int N = mRecentTasks.size();
8168            for (int i=0; i<N; i++) {
8169                TaskRecord tr = mRecentTasks.get(i);
8170                if (tr.taskId == id) {
8171                    return tr;
8172                }
8173            }
8174            return null;
8175    }
8176
8177    @Override
8178    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8179        synchronized (this) {
8180            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8181                    "getTaskThumbnail()");
8182            TaskRecord tr = recentTaskForIdLocked(id);
8183            if (tr != null) {
8184                return tr.getTaskThumbnailLocked();
8185            }
8186        }
8187        return null;
8188    }
8189
8190    @Override
8191    public int addAppTask(IBinder activityToken, Intent intent,
8192            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8193        final int callingUid = Binder.getCallingUid();
8194        final long callingIdent = Binder.clearCallingIdentity();
8195
8196        try {
8197            synchronized (this) {
8198                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8199                if (r == null) {
8200                    throw new IllegalArgumentException("Activity does not exist; token="
8201                            + activityToken);
8202                }
8203                ComponentName comp = intent.getComponent();
8204                if (comp == null) {
8205                    throw new IllegalArgumentException("Intent " + intent
8206                            + " must specify explicit component");
8207                }
8208                if (thumbnail.getWidth() != mThumbnailWidth
8209                        || thumbnail.getHeight() != mThumbnailHeight) {
8210                    throw new IllegalArgumentException("Bad thumbnail size: got "
8211                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8212                            + mThumbnailWidth + "x" + mThumbnailHeight);
8213                }
8214                if (intent.getSelector() != null) {
8215                    intent.setSelector(null);
8216                }
8217                if (intent.getSourceBounds() != null) {
8218                    intent.setSourceBounds(null);
8219                }
8220                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8221                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8222                        // The caller has added this as an auto-remove task...  that makes no
8223                        // sense, so turn off auto-remove.
8224                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8225                    }
8226                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8227                    // Must be a new task.
8228                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8229                }
8230                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8231                    mLastAddedTaskActivity = null;
8232                }
8233                ActivityInfo ainfo = mLastAddedTaskActivity;
8234                if (ainfo == null) {
8235                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8236                            comp, 0, UserHandle.getUserId(callingUid));
8237                    if (ainfo.applicationInfo.uid != callingUid) {
8238                        throw new SecurityException(
8239                                "Can't add task for another application: target uid="
8240                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8241                    }
8242                }
8243
8244                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8245                        intent, description);
8246
8247                int trimIdx = trimRecentsForTask(task, false);
8248                if (trimIdx >= 0) {
8249                    // If this would have caused a trim, then we'll abort because that
8250                    // means it would be added at the end of the list but then just removed.
8251                    return -1;
8252                }
8253
8254                final int N = mRecentTasks.size();
8255                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8256                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8257                    tr.removedFromRecents(mTaskPersister);
8258                }
8259
8260                task.inRecents = true;
8261                mRecentTasks.add(task);
8262                r.task.stack.addTask(task, false, false);
8263
8264                task.setLastThumbnail(thumbnail);
8265                task.freeLastThumbnail();
8266
8267                return task.taskId;
8268            }
8269        } finally {
8270            Binder.restoreCallingIdentity(callingIdent);
8271        }
8272    }
8273
8274    @Override
8275    public Point getAppTaskThumbnailSize() {
8276        synchronized (this) {
8277            return new Point(mThumbnailWidth,  mThumbnailHeight);
8278        }
8279    }
8280
8281    @Override
8282    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8283        synchronized (this) {
8284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8285            if (r != null) {
8286                r.taskDescription = td;
8287                r.task.updateTaskDescription();
8288            }
8289        }
8290    }
8291
8292    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8293        mRecentTasks.remove(tr);
8294        tr.removedFromRecents(mTaskPersister);
8295        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8296        Intent baseIntent = new Intent(
8297                tr.intent != null ? tr.intent : tr.affinityIntent);
8298        ComponentName component = baseIntent.getComponent();
8299        if (component == null) {
8300            Slog.w(TAG, "Now component for base intent of task: " + tr);
8301            return;
8302        }
8303
8304        // Find any running services associated with this app.
8305        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8306
8307        if (killProcesses) {
8308            // Find any running processes associated with this app.
8309            final String pkg = component.getPackageName();
8310            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8311            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8312            for (int i=0; i<pmap.size(); i++) {
8313                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8314                for (int j=0; j<uids.size(); j++) {
8315                    ProcessRecord proc = uids.valueAt(j);
8316                    if (proc.userId != tr.userId) {
8317                        continue;
8318                    }
8319                    if (!proc.pkgList.containsKey(pkg)) {
8320                        continue;
8321                    }
8322                    procs.add(proc);
8323                }
8324            }
8325
8326            // Kill the running processes.
8327            for (int i=0; i<procs.size(); i++) {
8328                ProcessRecord pr = procs.get(i);
8329                if (pr == mHomeProcess) {
8330                    // Don't kill the home process along with tasks from the same package.
8331                    continue;
8332                }
8333                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8334                    pr.kill("remove task", true);
8335                } else {
8336                    pr.waitingToKill = "remove task";
8337                }
8338            }
8339        }
8340    }
8341
8342    /**
8343     * Removes the task with the specified task id.
8344     *
8345     * @param taskId Identifier of the task to be removed.
8346     * @param flags Additional operational flags.  May be 0 or
8347     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8348     * @return Returns true if the given task was found and removed.
8349     */
8350    private boolean removeTaskByIdLocked(int taskId, int flags) {
8351        TaskRecord tr = recentTaskForIdLocked(taskId);
8352        if (tr != null) {
8353            tr.removeTaskActivitiesLocked();
8354            cleanUpRemovedTaskLocked(tr, flags);
8355            if (tr.isPersistable) {
8356                notifyTaskPersisterLocked(null, true);
8357            }
8358            return true;
8359        }
8360        return false;
8361    }
8362
8363    @Override
8364    public boolean removeTask(int taskId, int flags) {
8365        synchronized (this) {
8366            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8367                    "removeTask()");
8368            long ident = Binder.clearCallingIdentity();
8369            try {
8370                return removeTaskByIdLocked(taskId, flags);
8371            } finally {
8372                Binder.restoreCallingIdentity(ident);
8373            }
8374        }
8375    }
8376
8377    /**
8378     * TODO: Add mController hook
8379     */
8380    @Override
8381    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8382        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8383                "moveTaskToFront()");
8384
8385        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8386        synchronized(this) {
8387            moveTaskToFrontLocked(taskId, flags, options);
8388        }
8389    }
8390
8391    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8392        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8393                Binder.getCallingUid(), "Task to front")) {
8394            ActivityOptions.abort(options);
8395            return;
8396        }
8397        final long origId = Binder.clearCallingIdentity();
8398        try {
8399            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8400            if (task == null) {
8401                return;
8402            }
8403            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8404                mStackSupervisor.showLockTaskToast();
8405                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8406                return;
8407            }
8408            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8409            if (prev != null && prev.isRecentsActivity()) {
8410                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8411            }
8412            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8413        } finally {
8414            Binder.restoreCallingIdentity(origId);
8415        }
8416        ActivityOptions.abort(options);
8417    }
8418
8419    @Override
8420    public void moveTaskToBack(int taskId) {
8421        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8422                "moveTaskToBack()");
8423
8424        synchronized(this) {
8425            TaskRecord tr = recentTaskForIdLocked(taskId);
8426            if (tr != null) {
8427                if (tr == mStackSupervisor.mLockTaskModeTask) {
8428                    mStackSupervisor.showLockTaskToast();
8429                    return;
8430                }
8431                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8432                ActivityStack stack = tr.stack;
8433                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8434                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8435                            Binder.getCallingUid(), "Task to back")) {
8436                        return;
8437                    }
8438                }
8439                final long origId = Binder.clearCallingIdentity();
8440                try {
8441                    stack.moveTaskToBackLocked(taskId, null);
8442                } finally {
8443                    Binder.restoreCallingIdentity(origId);
8444                }
8445            }
8446        }
8447    }
8448
8449    /**
8450     * Moves an activity, and all of the other activities within the same task, to the bottom
8451     * of the history stack.  The activity's order within the task is unchanged.
8452     *
8453     * @param token A reference to the activity we wish to move
8454     * @param nonRoot If false then this only works if the activity is the root
8455     *                of a task; if true it will work for any activity in a task.
8456     * @return Returns true if the move completed, false if not.
8457     */
8458    @Override
8459    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8460        enforceNotIsolatedCaller("moveActivityTaskToBack");
8461        synchronized(this) {
8462            final long origId = Binder.clearCallingIdentity();
8463            try {
8464                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8465                if (taskId >= 0) {
8466                    if ((mStackSupervisor.mLockTaskModeTask != null)
8467                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8468                        mStackSupervisor.showLockTaskToast();
8469                        return false;
8470                    }
8471                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8472                }
8473            } finally {
8474                Binder.restoreCallingIdentity(origId);
8475            }
8476        }
8477        return false;
8478    }
8479
8480    @Override
8481    public void moveTaskBackwards(int task) {
8482        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8483                "moveTaskBackwards()");
8484
8485        synchronized(this) {
8486            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8487                    Binder.getCallingUid(), "Task backwards")) {
8488                return;
8489            }
8490            final long origId = Binder.clearCallingIdentity();
8491            moveTaskBackwardsLocked(task);
8492            Binder.restoreCallingIdentity(origId);
8493        }
8494    }
8495
8496    private final void moveTaskBackwardsLocked(int task) {
8497        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8498    }
8499
8500    @Override
8501    public IBinder getHomeActivityToken() throws RemoteException {
8502        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8503                "getHomeActivityToken()");
8504        synchronized (this) {
8505            return mStackSupervisor.getHomeActivityToken();
8506        }
8507    }
8508
8509    @Override
8510    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8511            IActivityContainerCallback callback) throws RemoteException {
8512        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8513                "createActivityContainer()");
8514        synchronized (this) {
8515            if (parentActivityToken == null) {
8516                throw new IllegalArgumentException("parent token must not be null");
8517            }
8518            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8519            if (r == null) {
8520                return null;
8521            }
8522            if (callback == null) {
8523                throw new IllegalArgumentException("callback must not be null");
8524            }
8525            return mStackSupervisor.createActivityContainer(r, callback);
8526        }
8527    }
8528
8529    @Override
8530    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8531        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8532                "deleteActivityContainer()");
8533        synchronized (this) {
8534            mStackSupervisor.deleteActivityContainer(container);
8535        }
8536    }
8537
8538    @Override
8539    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8540            throws RemoteException {
8541        synchronized (this) {
8542            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8543            if (stack != null) {
8544                return stack.mActivityContainer;
8545            }
8546            return null;
8547        }
8548    }
8549
8550    @Override
8551    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8552        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8553                "moveTaskToStack()");
8554        if (stackId == HOME_STACK_ID) {
8555            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8556                    new RuntimeException("here").fillInStackTrace());
8557        }
8558        synchronized (this) {
8559            long ident = Binder.clearCallingIdentity();
8560            try {
8561                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8562                        + stackId + " toTop=" + toTop);
8563                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8564            } finally {
8565                Binder.restoreCallingIdentity(ident);
8566            }
8567        }
8568    }
8569
8570    @Override
8571    public void resizeStack(int stackBoxId, Rect bounds) {
8572        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8573                "resizeStackBox()");
8574        long ident = Binder.clearCallingIdentity();
8575        try {
8576            mWindowManager.resizeStack(stackBoxId, bounds);
8577        } finally {
8578            Binder.restoreCallingIdentity(ident);
8579        }
8580    }
8581
8582    @Override
8583    public List<StackInfo> getAllStackInfos() {
8584        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8585                "getAllStackInfos()");
8586        long ident = Binder.clearCallingIdentity();
8587        try {
8588            synchronized (this) {
8589                return mStackSupervisor.getAllStackInfosLocked();
8590            }
8591        } finally {
8592            Binder.restoreCallingIdentity(ident);
8593        }
8594    }
8595
8596    @Override
8597    public StackInfo getStackInfo(int stackId) {
8598        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8599                "getStackInfo()");
8600        long ident = Binder.clearCallingIdentity();
8601        try {
8602            synchronized (this) {
8603                return mStackSupervisor.getStackInfoLocked(stackId);
8604            }
8605        } finally {
8606            Binder.restoreCallingIdentity(ident);
8607        }
8608    }
8609
8610    @Override
8611    public boolean isInHomeStack(int taskId) {
8612        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8613                "getStackInfo()");
8614        long ident = Binder.clearCallingIdentity();
8615        try {
8616            synchronized (this) {
8617                TaskRecord tr = recentTaskForIdLocked(taskId);
8618                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8619            }
8620        } finally {
8621            Binder.restoreCallingIdentity(ident);
8622        }
8623    }
8624
8625    @Override
8626    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8627        synchronized(this) {
8628            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8629        }
8630    }
8631
8632    private boolean isLockTaskAuthorized(String pkg) {
8633        final DevicePolicyManager dpm = (DevicePolicyManager)
8634                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8635        try {
8636            int uid = mContext.getPackageManager().getPackageUid(pkg,
8637                    Binder.getCallingUserHandle().getIdentifier());
8638            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8639        } catch (NameNotFoundException e) {
8640            return false;
8641        }
8642    }
8643
8644    void startLockTaskMode(TaskRecord task) {
8645        final String pkg;
8646        synchronized (this) {
8647            pkg = task.intent.getComponent().getPackageName();
8648        }
8649        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8650        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8651            final TaskRecord taskRecord = task;
8652            mHandler.post(new Runnable() {
8653                @Override
8654                public void run() {
8655                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8656                }
8657            });
8658            return;
8659        }
8660        long ident = Binder.clearCallingIdentity();
8661        try {
8662            synchronized (this) {
8663                // Since we lost lock on task, make sure it is still there.
8664                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8665                if (task != null) {
8666                    if (!isSystemInitiated
8667                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8668                        throw new IllegalArgumentException("Invalid task, not in foreground");
8669                    }
8670                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8671                }
8672            }
8673        } finally {
8674            Binder.restoreCallingIdentity(ident);
8675        }
8676    }
8677
8678    @Override
8679    public void startLockTaskMode(int taskId) {
8680        final TaskRecord task;
8681        long ident = Binder.clearCallingIdentity();
8682        try {
8683            synchronized (this) {
8684                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8685            }
8686        } finally {
8687            Binder.restoreCallingIdentity(ident);
8688        }
8689        if (task != null) {
8690            startLockTaskMode(task);
8691        }
8692    }
8693
8694    @Override
8695    public void startLockTaskMode(IBinder token) {
8696        final TaskRecord task;
8697        long ident = Binder.clearCallingIdentity();
8698        try {
8699            synchronized (this) {
8700                final ActivityRecord r = ActivityRecord.forToken(token);
8701                if (r == null) {
8702                    return;
8703                }
8704                task = r.task;
8705            }
8706        } finally {
8707            Binder.restoreCallingIdentity(ident);
8708        }
8709        if (task != null) {
8710            startLockTaskMode(task);
8711        }
8712    }
8713
8714    @Override
8715    public void startLockTaskModeOnCurrent() throws RemoteException {
8716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8717                "startLockTaskModeOnCurrent");
8718        ActivityRecord r = null;
8719        synchronized (this) {
8720            r = mStackSupervisor.topRunningActivityLocked();
8721        }
8722        startLockTaskMode(r.task);
8723    }
8724
8725    @Override
8726    public void stopLockTaskMode() {
8727        // Verify that the user matches the package of the intent for the TaskRecord
8728        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8729        // and stopLockTaskMode.
8730        final int callingUid = Binder.getCallingUid();
8731        if (callingUid != Process.SYSTEM_UID) {
8732            try {
8733                String pkg =
8734                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8735                int uid = mContext.getPackageManager().getPackageUid(pkg,
8736                        Binder.getCallingUserHandle().getIdentifier());
8737                if (uid != callingUid) {
8738                    throw new SecurityException("Invalid uid, expected " + uid);
8739                }
8740            } catch (NameNotFoundException e) {
8741                Log.d(TAG, "stopLockTaskMode " + e);
8742                return;
8743            }
8744        }
8745        long ident = Binder.clearCallingIdentity();
8746        try {
8747            Log.d(TAG, "stopLockTaskMode");
8748            // Stop lock task
8749            synchronized (this) {
8750                mStackSupervisor.setLockTaskModeLocked(null, false);
8751            }
8752        } finally {
8753            Binder.restoreCallingIdentity(ident);
8754        }
8755    }
8756
8757    @Override
8758    public void stopLockTaskModeOnCurrent() throws RemoteException {
8759        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8760                "stopLockTaskModeOnCurrent");
8761        long ident = Binder.clearCallingIdentity();
8762        try {
8763            stopLockTaskMode();
8764        } finally {
8765            Binder.restoreCallingIdentity(ident);
8766        }
8767    }
8768
8769    @Override
8770    public boolean isInLockTaskMode() {
8771        synchronized (this) {
8772            return mStackSupervisor.isInLockTaskMode();
8773        }
8774    }
8775
8776    // =========================================================
8777    // CONTENT PROVIDERS
8778    // =========================================================
8779
8780    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8781        List<ProviderInfo> providers = null;
8782        try {
8783            providers = AppGlobals.getPackageManager().
8784                queryContentProviders(app.processName, app.uid,
8785                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8786        } catch (RemoteException ex) {
8787        }
8788        if (DEBUG_MU)
8789            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8790        int userId = app.userId;
8791        if (providers != null) {
8792            int N = providers.size();
8793            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8794            for (int i=0; i<N; i++) {
8795                ProviderInfo cpi =
8796                    (ProviderInfo)providers.get(i);
8797                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8798                        cpi.name, cpi.flags);
8799                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8800                    // This is a singleton provider, but a user besides the
8801                    // default user is asking to initialize a process it runs
8802                    // in...  well, no, it doesn't actually run in this process,
8803                    // it runs in the process of the default user.  Get rid of it.
8804                    providers.remove(i);
8805                    N--;
8806                    i--;
8807                    continue;
8808                }
8809
8810                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8811                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8812                if (cpr == null) {
8813                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8814                    mProviderMap.putProviderByClass(comp, cpr);
8815                }
8816                if (DEBUG_MU)
8817                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8818                app.pubProviders.put(cpi.name, cpr);
8819                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8820                    // Don't add this if it is a platform component that is marked
8821                    // to run in multiple processes, because this is actually
8822                    // part of the framework so doesn't make sense to track as a
8823                    // separate apk in the process.
8824                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8825                            mProcessStats);
8826                }
8827                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8828            }
8829        }
8830        return providers;
8831    }
8832
8833    /**
8834     * Check if {@link ProcessRecord} has a possible chance at accessing the
8835     * given {@link ProviderInfo}. Final permission checking is always done
8836     * in {@link ContentProvider}.
8837     */
8838    private final String checkContentProviderPermissionLocked(
8839            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8840        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8841        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8842        boolean checkedGrants = false;
8843        if (checkUser) {
8844            // Looking for cross-user grants before enforcing the typical cross-users permissions
8845            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8846            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8847                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8848                    return null;
8849                }
8850                checkedGrants = true;
8851            }
8852            userId = handleIncomingUser(callingPid, callingUid, userId,
8853                    false, ALLOW_NON_FULL,
8854                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8855            if (userId != tmpTargetUserId) {
8856                // When we actually went to determine the final targer user ID, this ended
8857                // up different than our initial check for the authority.  This is because
8858                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8859                // SELF.  So we need to re-check the grants again.
8860                checkedGrants = false;
8861            }
8862        }
8863        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8864                cpi.applicationInfo.uid, cpi.exported)
8865                == PackageManager.PERMISSION_GRANTED) {
8866            return null;
8867        }
8868        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8869                cpi.applicationInfo.uid, cpi.exported)
8870                == PackageManager.PERMISSION_GRANTED) {
8871            return null;
8872        }
8873
8874        PathPermission[] pps = cpi.pathPermissions;
8875        if (pps != null) {
8876            int i = pps.length;
8877            while (i > 0) {
8878                i--;
8879                PathPermission pp = pps[i];
8880                String pprperm = pp.getReadPermission();
8881                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8882                        cpi.applicationInfo.uid, cpi.exported)
8883                        == PackageManager.PERMISSION_GRANTED) {
8884                    return null;
8885                }
8886                String ppwperm = pp.getWritePermission();
8887                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8888                        cpi.applicationInfo.uid, cpi.exported)
8889                        == PackageManager.PERMISSION_GRANTED) {
8890                    return null;
8891                }
8892            }
8893        }
8894        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8895            return null;
8896        }
8897
8898        String msg;
8899        if (!cpi.exported) {
8900            msg = "Permission Denial: opening provider " + cpi.name
8901                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8902                    + ", uid=" + callingUid + ") that is not exported from uid "
8903                    + cpi.applicationInfo.uid;
8904        } else {
8905            msg = "Permission Denial: opening provider " + cpi.name
8906                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8907                    + ", uid=" + callingUid + ") requires "
8908                    + cpi.readPermission + " or " + cpi.writePermission;
8909        }
8910        Slog.w(TAG, msg);
8911        return msg;
8912    }
8913
8914    /**
8915     * Returns if the ContentProvider has granted a uri to callingUid
8916     */
8917    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8918        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8919        if (perms != null) {
8920            for (int i=perms.size()-1; i>=0; i--) {
8921                GrantUri grantUri = perms.keyAt(i);
8922                if (grantUri.sourceUserId == userId || !checkUser) {
8923                    if (matchesProvider(grantUri.uri, cpi)) {
8924                        return true;
8925                    }
8926                }
8927            }
8928        }
8929        return false;
8930    }
8931
8932    /**
8933     * Returns true if the uri authority is one of the authorities specified in the provider.
8934     */
8935    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8936        String uriAuth = uri.getAuthority();
8937        String cpiAuth = cpi.authority;
8938        if (cpiAuth.indexOf(';') == -1) {
8939            return cpiAuth.equals(uriAuth);
8940        }
8941        String[] cpiAuths = cpiAuth.split(";");
8942        int length = cpiAuths.length;
8943        for (int i = 0; i < length; i++) {
8944            if (cpiAuths[i].equals(uriAuth)) return true;
8945        }
8946        return false;
8947    }
8948
8949    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8950            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8951        if (r != null) {
8952            for (int i=0; i<r.conProviders.size(); i++) {
8953                ContentProviderConnection conn = r.conProviders.get(i);
8954                if (conn.provider == cpr) {
8955                    if (DEBUG_PROVIDER) Slog.v(TAG,
8956                            "Adding provider requested by "
8957                            + r.processName + " from process "
8958                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8959                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8960                    if (stable) {
8961                        conn.stableCount++;
8962                        conn.numStableIncs++;
8963                    } else {
8964                        conn.unstableCount++;
8965                        conn.numUnstableIncs++;
8966                    }
8967                    return conn;
8968                }
8969            }
8970            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8971            if (stable) {
8972                conn.stableCount = 1;
8973                conn.numStableIncs = 1;
8974            } else {
8975                conn.unstableCount = 1;
8976                conn.numUnstableIncs = 1;
8977            }
8978            cpr.connections.add(conn);
8979            r.conProviders.add(conn);
8980            return conn;
8981        }
8982        cpr.addExternalProcessHandleLocked(externalProcessToken);
8983        return null;
8984    }
8985
8986    boolean decProviderCountLocked(ContentProviderConnection conn,
8987            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8988        if (conn != null) {
8989            cpr = conn.provider;
8990            if (DEBUG_PROVIDER) Slog.v(TAG,
8991                    "Removing provider requested by "
8992                    + conn.client.processName + " from process "
8993                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8994                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8995            if (stable) {
8996                conn.stableCount--;
8997            } else {
8998                conn.unstableCount--;
8999            }
9000            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9001                cpr.connections.remove(conn);
9002                conn.client.conProviders.remove(conn);
9003                return true;
9004            }
9005            return false;
9006        }
9007        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9008        return false;
9009    }
9010
9011    private void checkTime(long startTime, String where) {
9012        long now = SystemClock.elapsedRealtime();
9013        if ((now-startTime) > 1000) {
9014            // If we are taking more than a second, log about it.
9015            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9016        }
9017    }
9018
9019    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9020            String name, IBinder token, boolean stable, int userId) {
9021        ContentProviderRecord cpr;
9022        ContentProviderConnection conn = null;
9023        ProviderInfo cpi = null;
9024
9025        synchronized(this) {
9026            long startTime = SystemClock.elapsedRealtime();
9027
9028            ProcessRecord r = null;
9029            if (caller != null) {
9030                r = getRecordForAppLocked(caller);
9031                if (r == null) {
9032                    throw new SecurityException(
9033                            "Unable to find app for caller " + caller
9034                          + " (pid=" + Binder.getCallingPid()
9035                          + ") when getting content provider " + name);
9036                }
9037            }
9038
9039            boolean checkCrossUser = true;
9040
9041            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9042
9043            // First check if this content provider has been published...
9044            cpr = mProviderMap.getProviderByName(name, userId);
9045            // If that didn't work, check if it exists for user 0 and then
9046            // verify that it's a singleton provider before using it.
9047            if (cpr == null && userId != UserHandle.USER_OWNER) {
9048                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9049                if (cpr != null) {
9050                    cpi = cpr.info;
9051                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9052                            cpi.name, cpi.flags)
9053                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9054                        userId = UserHandle.USER_OWNER;
9055                        checkCrossUser = false;
9056                    } else {
9057                        cpr = null;
9058                        cpi = null;
9059                    }
9060                }
9061            }
9062
9063            boolean providerRunning = cpr != null;
9064            if (providerRunning) {
9065                cpi = cpr.info;
9066                String msg;
9067                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9068                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9069                        != null) {
9070                    throw new SecurityException(msg);
9071                }
9072                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9073
9074                if (r != null && cpr.canRunHere(r)) {
9075                    // This provider has been published or is in the process
9076                    // of being published...  but it is also allowed to run
9077                    // in the caller's process, so don't make a connection
9078                    // and just let the caller instantiate its own instance.
9079                    ContentProviderHolder holder = cpr.newHolder(null);
9080                    // don't give caller the provider object, it needs
9081                    // to make its own.
9082                    holder.provider = null;
9083                    return holder;
9084                }
9085
9086                final long origId = Binder.clearCallingIdentity();
9087
9088                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9089
9090                // In this case the provider instance already exists, so we can
9091                // return it right away.
9092                conn = incProviderCountLocked(r, cpr, token, stable);
9093                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9094                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9095                        // If this is a perceptible app accessing the provider,
9096                        // make sure to count it as being accessed and thus
9097                        // back up on the LRU list.  This is good because
9098                        // content providers are often expensive to start.
9099                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9100                        updateLruProcessLocked(cpr.proc, false, null);
9101                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9102                    }
9103                }
9104
9105                if (cpr.proc != null) {
9106                    if (false) {
9107                        if (cpr.name.flattenToShortString().equals(
9108                                "com.android.providers.calendar/.CalendarProvider2")) {
9109                            Slog.v(TAG, "****************** KILLING "
9110                                + cpr.name.flattenToShortString());
9111                            Process.killProcess(cpr.proc.pid);
9112                        }
9113                    }
9114                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9115                    boolean success = updateOomAdjLocked(cpr.proc);
9116                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9117                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9118                    // NOTE: there is still a race here where a signal could be
9119                    // pending on the process even though we managed to update its
9120                    // adj level.  Not sure what to do about this, but at least
9121                    // the race is now smaller.
9122                    if (!success) {
9123                        // Uh oh...  it looks like the provider's process
9124                        // has been killed on us.  We need to wait for a new
9125                        // process to be started, and make sure its death
9126                        // doesn't kill our process.
9127                        Slog.i(TAG,
9128                                "Existing provider " + cpr.name.flattenToShortString()
9129                                + " is crashing; detaching " + r);
9130                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9131                        checkTime(startTime, "getContentProviderImpl: before appDied");
9132                        appDiedLocked(cpr.proc);
9133                        checkTime(startTime, "getContentProviderImpl: after appDied");
9134                        if (!lastRef) {
9135                            // This wasn't the last ref our process had on
9136                            // the provider...  we have now been killed, bail.
9137                            return null;
9138                        }
9139                        providerRunning = false;
9140                        conn = null;
9141                    }
9142                }
9143
9144                Binder.restoreCallingIdentity(origId);
9145            }
9146
9147            boolean singleton;
9148            if (!providerRunning) {
9149                try {
9150                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9151                    cpi = AppGlobals.getPackageManager().
9152                        resolveContentProvider(name,
9153                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9154                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9155                } catch (RemoteException ex) {
9156                }
9157                if (cpi == null) {
9158                    return null;
9159                }
9160                // If the provider is a singleton AND
9161                // (it's a call within the same user || the provider is a
9162                // privileged app)
9163                // Then allow connecting to the singleton provider
9164                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9165                        cpi.name, cpi.flags)
9166                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9167                if (singleton) {
9168                    userId = UserHandle.USER_OWNER;
9169                }
9170                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9171                checkTime(startTime, "getContentProviderImpl: got app info for user");
9172
9173                String msg;
9174                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9175                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9176                        != null) {
9177                    throw new SecurityException(msg);
9178                }
9179                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9180
9181                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9182                        && !cpi.processName.equals("system")) {
9183                    // If this content provider does not run in the system
9184                    // process, and the system is not yet ready to run other
9185                    // processes, then fail fast instead of hanging.
9186                    throw new IllegalArgumentException(
9187                            "Attempt to launch content provider before system ready");
9188                }
9189
9190                // Make sure that the user who owns this provider is started.  If not,
9191                // we don't want to allow it to run.
9192                if (mStartedUsers.get(userId) == null) {
9193                    Slog.w(TAG, "Unable to launch app "
9194                            + cpi.applicationInfo.packageName + "/"
9195                            + cpi.applicationInfo.uid + " for provider "
9196                            + name + ": user " + userId + " is stopped");
9197                    return null;
9198                }
9199
9200                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9201                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9202                cpr = mProviderMap.getProviderByClass(comp, userId);
9203                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9204                final boolean firstClass = cpr == null;
9205                if (firstClass) {
9206                    try {
9207                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9208                        ApplicationInfo ai =
9209                            AppGlobals.getPackageManager().
9210                                getApplicationInfo(
9211                                        cpi.applicationInfo.packageName,
9212                                        STOCK_PM_FLAGS, userId);
9213                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9214                        if (ai == null) {
9215                            Slog.w(TAG, "No package info for content provider "
9216                                    + cpi.name);
9217                            return null;
9218                        }
9219                        ai = getAppInfoForUser(ai, userId);
9220                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9221                    } catch (RemoteException ex) {
9222                        // pm is in same process, this will never happen.
9223                    }
9224                }
9225
9226                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9227
9228                if (r != null && cpr.canRunHere(r)) {
9229                    // If this is a multiprocess provider, then just return its
9230                    // info and allow the caller to instantiate it.  Only do
9231                    // this if the provider is the same user as the caller's
9232                    // process, or can run as root (so can be in any process).
9233                    return cpr.newHolder(null);
9234                }
9235
9236                if (DEBUG_PROVIDER) {
9237                    RuntimeException e = new RuntimeException("here");
9238                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9239                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9240                }
9241
9242                // This is single process, and our app is now connecting to it.
9243                // See if we are already in the process of launching this
9244                // provider.
9245                final int N = mLaunchingProviders.size();
9246                int i;
9247                for (i=0; i<N; i++) {
9248                    if (mLaunchingProviders.get(i) == cpr) {
9249                        break;
9250                    }
9251                }
9252
9253                // If the provider is not already being launched, then get it
9254                // started.
9255                if (i >= N) {
9256                    final long origId = Binder.clearCallingIdentity();
9257
9258                    try {
9259                        // Content provider is now in use, its package can't be stopped.
9260                        try {
9261                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9262                            AppGlobals.getPackageManager().setPackageStoppedState(
9263                                    cpr.appInfo.packageName, false, userId);
9264                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9265                        } catch (RemoteException e) {
9266                        } catch (IllegalArgumentException e) {
9267                            Slog.w(TAG, "Failed trying to unstop package "
9268                                    + cpr.appInfo.packageName + ": " + e);
9269                        }
9270
9271                        // Use existing process if already started
9272                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9273                        ProcessRecord proc = getProcessRecordLocked(
9274                                cpi.processName, cpr.appInfo.uid, false);
9275                        if (proc != null && proc.thread != null) {
9276                            if (DEBUG_PROVIDER) {
9277                                Slog.d(TAG, "Installing in existing process " + proc);
9278                            }
9279                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9280                            proc.pubProviders.put(cpi.name, cpr);
9281                            try {
9282                                proc.thread.scheduleInstallProvider(cpi);
9283                            } catch (RemoteException e) {
9284                            }
9285                        } else {
9286                            checkTime(startTime, "getContentProviderImpl: before start process");
9287                            proc = startProcessLocked(cpi.processName,
9288                                    cpr.appInfo, false, 0, "content provider",
9289                                    new ComponentName(cpi.applicationInfo.packageName,
9290                                            cpi.name), false, false, false);
9291                            checkTime(startTime, "getContentProviderImpl: after start process");
9292                            if (proc == null) {
9293                                Slog.w(TAG, "Unable to launch app "
9294                                        + cpi.applicationInfo.packageName + "/"
9295                                        + cpi.applicationInfo.uid + " for provider "
9296                                        + name + ": process is bad");
9297                                return null;
9298                            }
9299                        }
9300                        cpr.launchingApp = proc;
9301                        mLaunchingProviders.add(cpr);
9302                    } finally {
9303                        Binder.restoreCallingIdentity(origId);
9304                    }
9305                }
9306
9307                checkTime(startTime, "getContentProviderImpl: updating data structures");
9308
9309                // Make sure the provider is published (the same provider class
9310                // may be published under multiple names).
9311                if (firstClass) {
9312                    mProviderMap.putProviderByClass(comp, cpr);
9313                }
9314
9315                mProviderMap.putProviderByName(name, cpr);
9316                conn = incProviderCountLocked(r, cpr, token, stable);
9317                if (conn != null) {
9318                    conn.waiting = true;
9319                }
9320            }
9321            checkTime(startTime, "getContentProviderImpl: done!");
9322        }
9323
9324        // Wait for the provider to be published...
9325        synchronized (cpr) {
9326            while (cpr.provider == null) {
9327                if (cpr.launchingApp == null) {
9328                    Slog.w(TAG, "Unable to launch app "
9329                            + cpi.applicationInfo.packageName + "/"
9330                            + cpi.applicationInfo.uid + " for provider "
9331                            + name + ": launching app became null");
9332                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9333                            UserHandle.getUserId(cpi.applicationInfo.uid),
9334                            cpi.applicationInfo.packageName,
9335                            cpi.applicationInfo.uid, name);
9336                    return null;
9337                }
9338                try {
9339                    if (DEBUG_MU) {
9340                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9341                                + cpr.launchingApp);
9342                    }
9343                    if (conn != null) {
9344                        conn.waiting = true;
9345                    }
9346                    cpr.wait();
9347                } catch (InterruptedException ex) {
9348                } finally {
9349                    if (conn != null) {
9350                        conn.waiting = false;
9351                    }
9352                }
9353            }
9354        }
9355        return cpr != null ? cpr.newHolder(conn) : null;
9356    }
9357
9358    @Override
9359    public final ContentProviderHolder getContentProvider(
9360            IApplicationThread caller, String name, int userId, boolean stable) {
9361        enforceNotIsolatedCaller("getContentProvider");
9362        if (caller == null) {
9363            String msg = "null IApplicationThread when getting content provider "
9364                    + name;
9365            Slog.w(TAG, msg);
9366            throw new SecurityException(msg);
9367        }
9368        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9369        // with cross-user grant.
9370        return getContentProviderImpl(caller, name, null, stable, userId);
9371    }
9372
9373    public ContentProviderHolder getContentProviderExternal(
9374            String name, int userId, IBinder token) {
9375        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9376            "Do not have permission in call getContentProviderExternal()");
9377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9378                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9379        return getContentProviderExternalUnchecked(name, token, userId);
9380    }
9381
9382    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9383            IBinder token, int userId) {
9384        return getContentProviderImpl(null, name, token, true, userId);
9385    }
9386
9387    /**
9388     * Drop a content provider from a ProcessRecord's bookkeeping
9389     */
9390    public void removeContentProvider(IBinder connection, boolean stable) {
9391        enforceNotIsolatedCaller("removeContentProvider");
9392        long ident = Binder.clearCallingIdentity();
9393        try {
9394            synchronized (this) {
9395                ContentProviderConnection conn;
9396                try {
9397                    conn = (ContentProviderConnection)connection;
9398                } catch (ClassCastException e) {
9399                    String msg ="removeContentProvider: " + connection
9400                            + " not a ContentProviderConnection";
9401                    Slog.w(TAG, msg);
9402                    throw new IllegalArgumentException(msg);
9403                }
9404                if (conn == null) {
9405                    throw new NullPointerException("connection is null");
9406                }
9407                if (decProviderCountLocked(conn, null, null, stable)) {
9408                    updateOomAdjLocked();
9409                }
9410            }
9411        } finally {
9412            Binder.restoreCallingIdentity(ident);
9413        }
9414    }
9415
9416    public void removeContentProviderExternal(String name, IBinder token) {
9417        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9418            "Do not have permission in call removeContentProviderExternal()");
9419        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9420    }
9421
9422    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9423        synchronized (this) {
9424            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9425            if(cpr == null) {
9426                //remove from mProvidersByClass
9427                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9428                return;
9429            }
9430
9431            //update content provider record entry info
9432            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9433            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9434            if (localCpr.hasExternalProcessHandles()) {
9435                if (localCpr.removeExternalProcessHandleLocked(token)) {
9436                    updateOomAdjLocked();
9437                } else {
9438                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9439                            + " with no external reference for token: "
9440                            + token + ".");
9441                }
9442            } else {
9443                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9444                        + " with no external references.");
9445            }
9446        }
9447    }
9448
9449    public final void publishContentProviders(IApplicationThread caller,
9450            List<ContentProviderHolder> providers) {
9451        if (providers == null) {
9452            return;
9453        }
9454
9455        enforceNotIsolatedCaller("publishContentProviders");
9456        synchronized (this) {
9457            final ProcessRecord r = getRecordForAppLocked(caller);
9458            if (DEBUG_MU)
9459                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9460            if (r == null) {
9461                throw new SecurityException(
9462                        "Unable to find app for caller " + caller
9463                      + " (pid=" + Binder.getCallingPid()
9464                      + ") when publishing content providers");
9465            }
9466
9467            final long origId = Binder.clearCallingIdentity();
9468
9469            final int N = providers.size();
9470            for (int i=0; i<N; i++) {
9471                ContentProviderHolder src = providers.get(i);
9472                if (src == null || src.info == null || src.provider == null) {
9473                    continue;
9474                }
9475                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9476                if (DEBUG_MU)
9477                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9478                if (dst != null) {
9479                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9480                    mProviderMap.putProviderByClass(comp, dst);
9481                    String names[] = dst.info.authority.split(";");
9482                    for (int j = 0; j < names.length; j++) {
9483                        mProviderMap.putProviderByName(names[j], dst);
9484                    }
9485
9486                    int NL = mLaunchingProviders.size();
9487                    int j;
9488                    for (j=0; j<NL; j++) {
9489                        if (mLaunchingProviders.get(j) == dst) {
9490                            mLaunchingProviders.remove(j);
9491                            j--;
9492                            NL--;
9493                        }
9494                    }
9495                    synchronized (dst) {
9496                        dst.provider = src.provider;
9497                        dst.proc = r;
9498                        dst.notifyAll();
9499                    }
9500                    updateOomAdjLocked(r);
9501                }
9502            }
9503
9504            Binder.restoreCallingIdentity(origId);
9505        }
9506    }
9507
9508    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9509        ContentProviderConnection conn;
9510        try {
9511            conn = (ContentProviderConnection)connection;
9512        } catch (ClassCastException e) {
9513            String msg ="refContentProvider: " + connection
9514                    + " not a ContentProviderConnection";
9515            Slog.w(TAG, msg);
9516            throw new IllegalArgumentException(msg);
9517        }
9518        if (conn == null) {
9519            throw new NullPointerException("connection is null");
9520        }
9521
9522        synchronized (this) {
9523            if (stable > 0) {
9524                conn.numStableIncs += stable;
9525            }
9526            stable = conn.stableCount + stable;
9527            if (stable < 0) {
9528                throw new IllegalStateException("stableCount < 0: " + stable);
9529            }
9530
9531            if (unstable > 0) {
9532                conn.numUnstableIncs += unstable;
9533            }
9534            unstable = conn.unstableCount + unstable;
9535            if (unstable < 0) {
9536                throw new IllegalStateException("unstableCount < 0: " + unstable);
9537            }
9538
9539            if ((stable+unstable) <= 0) {
9540                throw new IllegalStateException("ref counts can't go to zero here: stable="
9541                        + stable + " unstable=" + unstable);
9542            }
9543            conn.stableCount = stable;
9544            conn.unstableCount = unstable;
9545            return !conn.dead;
9546        }
9547    }
9548
9549    public void unstableProviderDied(IBinder connection) {
9550        ContentProviderConnection conn;
9551        try {
9552            conn = (ContentProviderConnection)connection;
9553        } catch (ClassCastException e) {
9554            String msg ="refContentProvider: " + connection
9555                    + " not a ContentProviderConnection";
9556            Slog.w(TAG, msg);
9557            throw new IllegalArgumentException(msg);
9558        }
9559        if (conn == null) {
9560            throw new NullPointerException("connection is null");
9561        }
9562
9563        // Safely retrieve the content provider associated with the connection.
9564        IContentProvider provider;
9565        synchronized (this) {
9566            provider = conn.provider.provider;
9567        }
9568
9569        if (provider == null) {
9570            // Um, yeah, we're way ahead of you.
9571            return;
9572        }
9573
9574        // Make sure the caller is being honest with us.
9575        if (provider.asBinder().pingBinder()) {
9576            // Er, no, still looks good to us.
9577            synchronized (this) {
9578                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9579                        + " says " + conn + " died, but we don't agree");
9580                return;
9581            }
9582        }
9583
9584        // Well look at that!  It's dead!
9585        synchronized (this) {
9586            if (conn.provider.provider != provider) {
9587                // But something changed...  good enough.
9588                return;
9589            }
9590
9591            ProcessRecord proc = conn.provider.proc;
9592            if (proc == null || proc.thread == null) {
9593                // Seems like the process is already cleaned up.
9594                return;
9595            }
9596
9597            // As far as we're concerned, this is just like receiving a
9598            // death notification...  just a bit prematurely.
9599            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9600                    + ") early provider death");
9601            final long ident = Binder.clearCallingIdentity();
9602            try {
9603                appDiedLocked(proc);
9604            } finally {
9605                Binder.restoreCallingIdentity(ident);
9606            }
9607        }
9608    }
9609
9610    @Override
9611    public void appNotRespondingViaProvider(IBinder connection) {
9612        enforceCallingPermission(
9613                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9614
9615        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9616        if (conn == null) {
9617            Slog.w(TAG, "ContentProviderConnection is null");
9618            return;
9619        }
9620
9621        final ProcessRecord host = conn.provider.proc;
9622        if (host == null) {
9623            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9624            return;
9625        }
9626
9627        final long token = Binder.clearCallingIdentity();
9628        try {
9629            appNotResponding(host, null, null, false, "ContentProvider not responding");
9630        } finally {
9631            Binder.restoreCallingIdentity(token);
9632        }
9633    }
9634
9635    public final void installSystemProviders() {
9636        List<ProviderInfo> providers;
9637        synchronized (this) {
9638            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9639            providers = generateApplicationProvidersLocked(app);
9640            if (providers != null) {
9641                for (int i=providers.size()-1; i>=0; i--) {
9642                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9643                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9644                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9645                                + ": not system .apk");
9646                        providers.remove(i);
9647                    }
9648                }
9649            }
9650        }
9651        if (providers != null) {
9652            mSystemThread.installSystemProviders(providers);
9653        }
9654
9655        mCoreSettingsObserver = new CoreSettingsObserver(this);
9656
9657        //mUsageStatsService.monitorPackages();
9658    }
9659
9660    /**
9661     * Allows apps to retrieve the MIME type of a URI.
9662     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9663     * users, then it does not need permission to access the ContentProvider.
9664     * Either, it needs cross-user uri grants.
9665     *
9666     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9667     *
9668     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9669     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9670     */
9671    public String getProviderMimeType(Uri uri, int userId) {
9672        enforceNotIsolatedCaller("getProviderMimeType");
9673        final String name = uri.getAuthority();
9674        int callingUid = Binder.getCallingUid();
9675        int callingPid = Binder.getCallingPid();
9676        long ident = 0;
9677        boolean clearedIdentity = false;
9678        userId = unsafeConvertIncomingUser(userId);
9679        if (UserHandle.getUserId(callingUid) != userId) {
9680            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9681                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9682                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9683                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9684                clearedIdentity = true;
9685                ident = Binder.clearCallingIdentity();
9686            }
9687        }
9688        ContentProviderHolder holder = null;
9689        try {
9690            holder = getContentProviderExternalUnchecked(name, null, userId);
9691            if (holder != null) {
9692                return holder.provider.getType(uri);
9693            }
9694        } catch (RemoteException e) {
9695            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9696            return null;
9697        } finally {
9698            // We need to clear the identity to call removeContentProviderExternalUnchecked
9699            if (!clearedIdentity) {
9700                ident = Binder.clearCallingIdentity();
9701            }
9702            try {
9703                if (holder != null) {
9704                    removeContentProviderExternalUnchecked(name, null, userId);
9705                }
9706            } finally {
9707                Binder.restoreCallingIdentity(ident);
9708            }
9709        }
9710
9711        return null;
9712    }
9713
9714    // =========================================================
9715    // GLOBAL MANAGEMENT
9716    // =========================================================
9717
9718    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9719            boolean isolated, int isolatedUid) {
9720        String proc = customProcess != null ? customProcess : info.processName;
9721        BatteryStatsImpl.Uid.Proc ps = null;
9722        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9723        int uid = info.uid;
9724        if (isolated) {
9725            if (isolatedUid == 0) {
9726                int userId = UserHandle.getUserId(uid);
9727                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9728                while (true) {
9729                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9730                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9731                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9732                    }
9733                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9734                    mNextIsolatedProcessUid++;
9735                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9736                        // No process for this uid, use it.
9737                        break;
9738                    }
9739                    stepsLeft--;
9740                    if (stepsLeft <= 0) {
9741                        return null;
9742                    }
9743                }
9744            } else {
9745                // Special case for startIsolatedProcess (internal only), where
9746                // the uid of the isolated process is specified by the caller.
9747                uid = isolatedUid;
9748            }
9749        }
9750        return new ProcessRecord(stats, info, proc, uid);
9751    }
9752
9753    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9754            String abiOverride) {
9755        ProcessRecord app;
9756        if (!isolated) {
9757            app = getProcessRecordLocked(info.processName, info.uid, true);
9758        } else {
9759            app = null;
9760        }
9761
9762        if (app == null) {
9763            app = newProcessRecordLocked(info, null, isolated, 0);
9764            mProcessNames.put(info.processName, app.uid, app);
9765            if (isolated) {
9766                mIsolatedProcesses.put(app.uid, app);
9767            }
9768            updateLruProcessLocked(app, false, null);
9769            updateOomAdjLocked();
9770        }
9771
9772        // This package really, really can not be stopped.
9773        try {
9774            AppGlobals.getPackageManager().setPackageStoppedState(
9775                    info.packageName, false, UserHandle.getUserId(app.uid));
9776        } catch (RemoteException e) {
9777        } catch (IllegalArgumentException e) {
9778            Slog.w(TAG, "Failed trying to unstop package "
9779                    + info.packageName + ": " + e);
9780        }
9781
9782        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9783                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9784            app.persistent = true;
9785            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9786        }
9787        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9788            mPersistentStartingProcesses.add(app);
9789            startProcessLocked(app, "added application", app.processName, abiOverride,
9790                    null /* entryPoint */, null /* entryPointArgs */);
9791        }
9792
9793        return app;
9794    }
9795
9796    public void unhandledBack() {
9797        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9798                "unhandledBack()");
9799
9800        synchronized(this) {
9801            final long origId = Binder.clearCallingIdentity();
9802            try {
9803                getFocusedStack().unhandledBackLocked();
9804            } finally {
9805                Binder.restoreCallingIdentity(origId);
9806            }
9807        }
9808    }
9809
9810    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9811        enforceNotIsolatedCaller("openContentUri");
9812        final int userId = UserHandle.getCallingUserId();
9813        String name = uri.getAuthority();
9814        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9815        ParcelFileDescriptor pfd = null;
9816        if (cph != null) {
9817            // We record the binder invoker's uid in thread-local storage before
9818            // going to the content provider to open the file.  Later, in the code
9819            // that handles all permissions checks, we look for this uid and use
9820            // that rather than the Activity Manager's own uid.  The effect is that
9821            // we do the check against the caller's permissions even though it looks
9822            // to the content provider like the Activity Manager itself is making
9823            // the request.
9824            sCallerIdentity.set(new Identity(
9825                    Binder.getCallingPid(), Binder.getCallingUid()));
9826            try {
9827                pfd = cph.provider.openFile(null, uri, "r", null);
9828            } catch (FileNotFoundException e) {
9829                // do nothing; pfd will be returned null
9830            } finally {
9831                // Ensure that whatever happens, we clean up the identity state
9832                sCallerIdentity.remove();
9833            }
9834
9835            // We've got the fd now, so we're done with the provider.
9836            removeContentProviderExternalUnchecked(name, null, userId);
9837        } else {
9838            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9839        }
9840        return pfd;
9841    }
9842
9843    // Actually is sleeping or shutting down or whatever else in the future
9844    // is an inactive state.
9845    public boolean isSleepingOrShuttingDown() {
9846        return mSleeping || mShuttingDown;
9847    }
9848
9849    public boolean isSleeping() {
9850        return mSleeping;
9851    }
9852
9853    void goingToSleep() {
9854        synchronized(this) {
9855            mWentToSleep = true;
9856            updateEventDispatchingLocked();
9857            goToSleepIfNeededLocked();
9858        }
9859    }
9860
9861    void finishRunningVoiceLocked() {
9862        if (mRunningVoice) {
9863            mRunningVoice = false;
9864            goToSleepIfNeededLocked();
9865        }
9866    }
9867
9868    void goToSleepIfNeededLocked() {
9869        if (mWentToSleep && !mRunningVoice) {
9870            if (!mSleeping) {
9871                mSleeping = true;
9872                mStackSupervisor.goingToSleepLocked();
9873
9874                // Initialize the wake times of all processes.
9875                checkExcessivePowerUsageLocked(false);
9876                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9877                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9878                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9879            }
9880        }
9881    }
9882
9883    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9884        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9885            // Never persist the home stack.
9886            return;
9887        }
9888        mTaskPersister.wakeup(task, flush);
9889    }
9890
9891    @Override
9892    public boolean shutdown(int timeout) {
9893        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9894                != PackageManager.PERMISSION_GRANTED) {
9895            throw new SecurityException("Requires permission "
9896                    + android.Manifest.permission.SHUTDOWN);
9897        }
9898
9899        boolean timedout = false;
9900
9901        synchronized(this) {
9902            mShuttingDown = true;
9903            updateEventDispatchingLocked();
9904            timedout = mStackSupervisor.shutdownLocked(timeout);
9905        }
9906
9907        mAppOpsService.shutdown();
9908        if (mUsageStatsService != null) {
9909            mUsageStatsService.prepareShutdown();
9910        }
9911        mBatteryStatsService.shutdown();
9912        synchronized (this) {
9913            mProcessStats.shutdownLocked();
9914        }
9915        notifyTaskPersisterLocked(null, true);
9916
9917        return timedout;
9918    }
9919
9920    public final void activitySlept(IBinder token) {
9921        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9922
9923        final long origId = Binder.clearCallingIdentity();
9924
9925        synchronized (this) {
9926            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9927            if (r != null) {
9928                mStackSupervisor.activitySleptLocked(r);
9929            }
9930        }
9931
9932        Binder.restoreCallingIdentity(origId);
9933    }
9934
9935    void logLockScreen(String msg) {
9936        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9937                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9938                mWentToSleep + " mSleeping=" + mSleeping);
9939    }
9940
9941    private void comeOutOfSleepIfNeededLocked() {
9942        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9943            if (mSleeping) {
9944                mSleeping = false;
9945                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9946            }
9947        }
9948    }
9949
9950    void wakingUp() {
9951        synchronized(this) {
9952            mWentToSleep = false;
9953            updateEventDispatchingLocked();
9954            comeOutOfSleepIfNeededLocked();
9955        }
9956    }
9957
9958    void startRunningVoiceLocked() {
9959        if (!mRunningVoice) {
9960            mRunningVoice = true;
9961            comeOutOfSleepIfNeededLocked();
9962        }
9963    }
9964
9965    private void updateEventDispatchingLocked() {
9966        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9967    }
9968
9969    public void setLockScreenShown(boolean shown) {
9970        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9971                != PackageManager.PERMISSION_GRANTED) {
9972            throw new SecurityException("Requires permission "
9973                    + android.Manifest.permission.DEVICE_POWER);
9974        }
9975
9976        synchronized(this) {
9977            long ident = Binder.clearCallingIdentity();
9978            try {
9979                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9980                mLockScreenShown = shown;
9981                comeOutOfSleepIfNeededLocked();
9982            } finally {
9983                Binder.restoreCallingIdentity(ident);
9984            }
9985        }
9986    }
9987
9988    @Override
9989    public void stopAppSwitches() {
9990        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9991                != PackageManager.PERMISSION_GRANTED) {
9992            throw new SecurityException("Requires permission "
9993                    + android.Manifest.permission.STOP_APP_SWITCHES);
9994        }
9995
9996        synchronized(this) {
9997            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9998                    + APP_SWITCH_DELAY_TIME;
9999            mDidAppSwitch = false;
10000            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10001            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10002            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10003        }
10004    }
10005
10006    public void resumeAppSwitches() {
10007        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10008                != PackageManager.PERMISSION_GRANTED) {
10009            throw new SecurityException("Requires permission "
10010                    + android.Manifest.permission.STOP_APP_SWITCHES);
10011        }
10012
10013        synchronized(this) {
10014            // Note that we don't execute any pending app switches... we will
10015            // let those wait until either the timeout, or the next start
10016            // activity request.
10017            mAppSwitchesAllowedTime = 0;
10018        }
10019    }
10020
10021    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10022            String name) {
10023        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10024            return true;
10025        }
10026
10027        final int perm = checkComponentPermission(
10028                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10029                callingUid, -1, true);
10030        if (perm == PackageManager.PERMISSION_GRANTED) {
10031            return true;
10032        }
10033
10034        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10035        return false;
10036    }
10037
10038    public void setDebugApp(String packageName, boolean waitForDebugger,
10039            boolean persistent) {
10040        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10041                "setDebugApp()");
10042
10043        long ident = Binder.clearCallingIdentity();
10044        try {
10045            // Note that this is not really thread safe if there are multiple
10046            // callers into it at the same time, but that's not a situation we
10047            // care about.
10048            if (persistent) {
10049                final ContentResolver resolver = mContext.getContentResolver();
10050                Settings.Global.putString(
10051                    resolver, Settings.Global.DEBUG_APP,
10052                    packageName);
10053                Settings.Global.putInt(
10054                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10055                    waitForDebugger ? 1 : 0);
10056            }
10057
10058            synchronized (this) {
10059                if (!persistent) {
10060                    mOrigDebugApp = mDebugApp;
10061                    mOrigWaitForDebugger = mWaitForDebugger;
10062                }
10063                mDebugApp = packageName;
10064                mWaitForDebugger = waitForDebugger;
10065                mDebugTransient = !persistent;
10066                if (packageName != null) {
10067                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10068                            false, UserHandle.USER_ALL, "set debug app");
10069                }
10070            }
10071        } finally {
10072            Binder.restoreCallingIdentity(ident);
10073        }
10074    }
10075
10076    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10077        synchronized (this) {
10078            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10079            if (!isDebuggable) {
10080                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10081                    throw new SecurityException("Process not debuggable: " + app.packageName);
10082                }
10083            }
10084
10085            mOpenGlTraceApp = processName;
10086        }
10087    }
10088
10089    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10090        synchronized (this) {
10091            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10092            if (!isDebuggable) {
10093                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10094                    throw new SecurityException("Process not debuggable: " + app.packageName);
10095                }
10096            }
10097            mProfileApp = processName;
10098            mProfileFile = profilerInfo.profileFile;
10099            if (mProfileFd != null) {
10100                try {
10101                    mProfileFd.close();
10102                } catch (IOException e) {
10103                }
10104                mProfileFd = null;
10105            }
10106            mProfileFd = profilerInfo.profileFd;
10107            mSamplingInterval = profilerInfo.samplingInterval;
10108            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10109            mProfileType = 0;
10110        }
10111    }
10112
10113    @Override
10114    public void setAlwaysFinish(boolean enabled) {
10115        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10116                "setAlwaysFinish()");
10117
10118        Settings.Global.putInt(
10119                mContext.getContentResolver(),
10120                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10121
10122        synchronized (this) {
10123            mAlwaysFinishActivities = enabled;
10124        }
10125    }
10126
10127    @Override
10128    public void setActivityController(IActivityController controller) {
10129        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10130                "setActivityController()");
10131        synchronized (this) {
10132            mController = controller;
10133            Watchdog.getInstance().setActivityController(controller);
10134        }
10135    }
10136
10137    @Override
10138    public void setUserIsMonkey(boolean userIsMonkey) {
10139        synchronized (this) {
10140            synchronized (mPidsSelfLocked) {
10141                final int callingPid = Binder.getCallingPid();
10142                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10143                if (precessRecord == null) {
10144                    throw new SecurityException("Unknown process: " + callingPid);
10145                }
10146                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10147                    throw new SecurityException("Only an instrumentation process "
10148                            + "with a UiAutomation can call setUserIsMonkey");
10149                }
10150            }
10151            mUserIsMonkey = userIsMonkey;
10152        }
10153    }
10154
10155    @Override
10156    public boolean isUserAMonkey() {
10157        synchronized (this) {
10158            // If there is a controller also implies the user is a monkey.
10159            return (mUserIsMonkey || mController != null);
10160        }
10161    }
10162
10163    public void requestBugReport() {
10164        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10165        SystemProperties.set("ctl.start", "bugreport");
10166    }
10167
10168    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10169        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10170    }
10171
10172    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10173        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10174            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10175        }
10176        return KEY_DISPATCHING_TIMEOUT;
10177    }
10178
10179    @Override
10180    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10181        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10182                != PackageManager.PERMISSION_GRANTED) {
10183            throw new SecurityException("Requires permission "
10184                    + android.Manifest.permission.FILTER_EVENTS);
10185        }
10186        ProcessRecord proc;
10187        long timeout;
10188        synchronized (this) {
10189            synchronized (mPidsSelfLocked) {
10190                proc = mPidsSelfLocked.get(pid);
10191            }
10192            timeout = getInputDispatchingTimeoutLocked(proc);
10193        }
10194
10195        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10196            return -1;
10197        }
10198
10199        return timeout;
10200    }
10201
10202    /**
10203     * Handle input dispatching timeouts.
10204     * Returns whether input dispatching should be aborted or not.
10205     */
10206    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10207            final ActivityRecord activity, final ActivityRecord parent,
10208            final boolean aboveSystem, String reason) {
10209        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10210                != PackageManager.PERMISSION_GRANTED) {
10211            throw new SecurityException("Requires permission "
10212                    + android.Manifest.permission.FILTER_EVENTS);
10213        }
10214
10215        final String annotation;
10216        if (reason == null) {
10217            annotation = "Input dispatching timed out";
10218        } else {
10219            annotation = "Input dispatching timed out (" + reason + ")";
10220        }
10221
10222        if (proc != null) {
10223            synchronized (this) {
10224                if (proc.debugging) {
10225                    return false;
10226                }
10227
10228                if (mDidDexOpt) {
10229                    // Give more time since we were dexopting.
10230                    mDidDexOpt = false;
10231                    return false;
10232                }
10233
10234                if (proc.instrumentationClass != null) {
10235                    Bundle info = new Bundle();
10236                    info.putString("shortMsg", "keyDispatchingTimedOut");
10237                    info.putString("longMsg", annotation);
10238                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10239                    return true;
10240                }
10241            }
10242            mHandler.post(new Runnable() {
10243                @Override
10244                public void run() {
10245                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10246                }
10247            });
10248        }
10249
10250        return true;
10251    }
10252
10253    public Bundle getAssistContextExtras(int requestType) {
10254        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10255                "getAssistContextExtras()");
10256        PendingAssistExtras pae;
10257        Bundle extras = new Bundle();
10258        synchronized (this) {
10259            ActivityRecord activity = getFocusedStack().mResumedActivity;
10260            if (activity == null) {
10261                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10262                return null;
10263            }
10264            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10265            if (activity.app == null || activity.app.thread == null) {
10266                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10267                return extras;
10268            }
10269            if (activity.app.pid == Binder.getCallingPid()) {
10270                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10271                return extras;
10272            }
10273            pae = new PendingAssistExtras(activity);
10274            try {
10275                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10276                        requestType);
10277                mPendingAssistExtras.add(pae);
10278                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10279            } catch (RemoteException e) {
10280                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10281                return extras;
10282            }
10283        }
10284        synchronized (pae) {
10285            while (!pae.haveResult) {
10286                try {
10287                    pae.wait();
10288                } catch (InterruptedException e) {
10289                }
10290            }
10291            if (pae.result != null) {
10292                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10293            }
10294        }
10295        synchronized (this) {
10296            mPendingAssistExtras.remove(pae);
10297            mHandler.removeCallbacks(pae);
10298        }
10299        return extras;
10300    }
10301
10302    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10303        PendingAssistExtras pae = (PendingAssistExtras)token;
10304        synchronized (pae) {
10305            pae.result = extras;
10306            pae.haveResult = true;
10307            pae.notifyAll();
10308        }
10309    }
10310
10311    public void registerProcessObserver(IProcessObserver observer) {
10312        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10313                "registerProcessObserver()");
10314        synchronized (this) {
10315            mProcessObservers.register(observer);
10316        }
10317    }
10318
10319    @Override
10320    public void unregisterProcessObserver(IProcessObserver observer) {
10321        synchronized (this) {
10322            mProcessObservers.unregister(observer);
10323        }
10324    }
10325
10326    @Override
10327    public boolean convertFromTranslucent(IBinder token) {
10328        final long origId = Binder.clearCallingIdentity();
10329        try {
10330            synchronized (this) {
10331                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10332                if (r == null) {
10333                    return false;
10334                }
10335                final boolean translucentChanged = r.changeWindowTranslucency(true);
10336                if (translucentChanged) {
10337                    r.task.stack.releaseBackgroundResources();
10338                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10339                }
10340                mWindowManager.setAppFullscreen(token, true);
10341                return translucentChanged;
10342            }
10343        } finally {
10344            Binder.restoreCallingIdentity(origId);
10345        }
10346    }
10347
10348    @Override
10349    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10350        final long origId = Binder.clearCallingIdentity();
10351        try {
10352            synchronized (this) {
10353                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10354                if (r == null) {
10355                    return false;
10356                }
10357                int index = r.task.mActivities.lastIndexOf(r);
10358                if (index > 0) {
10359                    ActivityRecord under = r.task.mActivities.get(index - 1);
10360                    under.returningOptions = options;
10361                }
10362                final boolean translucentChanged = r.changeWindowTranslucency(false);
10363                if (translucentChanged) {
10364                    r.task.stack.convertToTranslucent(r);
10365                }
10366                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10367                mWindowManager.setAppFullscreen(token, false);
10368                return translucentChanged;
10369            }
10370        } finally {
10371            Binder.restoreCallingIdentity(origId);
10372        }
10373    }
10374
10375    @Override
10376    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10377        final long origId = Binder.clearCallingIdentity();
10378        try {
10379            synchronized (this) {
10380                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10381                if (r != null) {
10382                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10383                }
10384            }
10385            return false;
10386        } finally {
10387            Binder.restoreCallingIdentity(origId);
10388        }
10389    }
10390
10391    @Override
10392    public boolean isBackgroundVisibleBehind(IBinder token) {
10393        final long origId = Binder.clearCallingIdentity();
10394        try {
10395            synchronized (this) {
10396                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10397                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10398                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10399                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10400                return visible;
10401            }
10402        } finally {
10403            Binder.restoreCallingIdentity(origId);
10404        }
10405    }
10406
10407    @Override
10408    public ActivityOptions getActivityOptions(IBinder token) {
10409        final long origId = Binder.clearCallingIdentity();
10410        try {
10411            synchronized (this) {
10412                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10413                if (r != null) {
10414                    final ActivityOptions activityOptions = r.pendingOptions;
10415                    r.pendingOptions = null;
10416                    return activityOptions;
10417                }
10418                return null;
10419            }
10420        } finally {
10421            Binder.restoreCallingIdentity(origId);
10422        }
10423    }
10424
10425    @Override
10426    public void setImmersive(IBinder token, boolean immersive) {
10427        synchronized(this) {
10428            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10429            if (r == null) {
10430                throw new IllegalArgumentException();
10431            }
10432            r.immersive = immersive;
10433
10434            // update associated state if we're frontmost
10435            if (r == mFocusedActivity) {
10436                if (DEBUG_IMMERSIVE) {
10437                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10438                }
10439                applyUpdateLockStateLocked(r);
10440            }
10441        }
10442    }
10443
10444    @Override
10445    public boolean isImmersive(IBinder token) {
10446        synchronized (this) {
10447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10448            if (r == null) {
10449                throw new IllegalArgumentException();
10450            }
10451            return r.immersive;
10452        }
10453    }
10454
10455    public boolean isTopActivityImmersive() {
10456        enforceNotIsolatedCaller("startActivity");
10457        synchronized (this) {
10458            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10459            return (r != null) ? r.immersive : false;
10460        }
10461    }
10462
10463    @Override
10464    public boolean isTopOfTask(IBinder token) {
10465        synchronized (this) {
10466            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10467            if (r == null) {
10468                throw new IllegalArgumentException();
10469            }
10470            return r.task.getTopActivity() == r;
10471        }
10472    }
10473
10474    public final void enterSafeMode() {
10475        synchronized(this) {
10476            // It only makes sense to do this before the system is ready
10477            // and started launching other packages.
10478            if (!mSystemReady) {
10479                try {
10480                    AppGlobals.getPackageManager().enterSafeMode();
10481                } catch (RemoteException e) {
10482                }
10483            }
10484
10485            mSafeMode = true;
10486        }
10487    }
10488
10489    public final void showSafeModeOverlay() {
10490        View v = LayoutInflater.from(mContext).inflate(
10491                com.android.internal.R.layout.safe_mode, null);
10492        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10493        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10494        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10495        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10496        lp.gravity = Gravity.BOTTOM | Gravity.START;
10497        lp.format = v.getBackground().getOpacity();
10498        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10499                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10500        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10501        ((WindowManager)mContext.getSystemService(
10502                Context.WINDOW_SERVICE)).addView(v, lp);
10503    }
10504
10505    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10506        if (!(sender instanceof PendingIntentRecord)) {
10507            return;
10508        }
10509        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10510        synchronized (stats) {
10511            if (mBatteryStatsService.isOnBattery()) {
10512                mBatteryStatsService.enforceCallingPermission();
10513                PendingIntentRecord rec = (PendingIntentRecord)sender;
10514                int MY_UID = Binder.getCallingUid();
10515                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10516                BatteryStatsImpl.Uid.Pkg pkg =
10517                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10518                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10519                pkg.incWakeupsLocked();
10520            }
10521        }
10522    }
10523
10524    public boolean killPids(int[] pids, String pReason, boolean secure) {
10525        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10526            throw new SecurityException("killPids only available to the system");
10527        }
10528        String reason = (pReason == null) ? "Unknown" : pReason;
10529        // XXX Note: don't acquire main activity lock here, because the window
10530        // manager calls in with its locks held.
10531
10532        boolean killed = false;
10533        synchronized (mPidsSelfLocked) {
10534            int[] types = new int[pids.length];
10535            int worstType = 0;
10536            for (int i=0; i<pids.length; i++) {
10537                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10538                if (proc != null) {
10539                    int type = proc.setAdj;
10540                    types[i] = type;
10541                    if (type > worstType) {
10542                        worstType = type;
10543                    }
10544                }
10545            }
10546
10547            // If the worst oom_adj is somewhere in the cached proc LRU range,
10548            // then constrain it so we will kill all cached procs.
10549            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10550                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10551                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10552            }
10553
10554            // If this is not a secure call, don't let it kill processes that
10555            // are important.
10556            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10557                worstType = ProcessList.SERVICE_ADJ;
10558            }
10559
10560            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10561            for (int i=0; i<pids.length; i++) {
10562                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10563                if (proc == null) {
10564                    continue;
10565                }
10566                int adj = proc.setAdj;
10567                if (adj >= worstType && !proc.killedByAm) {
10568                    proc.kill(reason, true);
10569                    killed = true;
10570                }
10571            }
10572        }
10573        return killed;
10574    }
10575
10576    @Override
10577    public void killUid(int uid, String reason) {
10578        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10579            throw new SecurityException("killUid only available to the system");
10580        }
10581        synchronized (this) {
10582            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10583                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10584                    reason != null ? reason : "kill uid");
10585        }
10586    }
10587
10588    @Override
10589    public boolean killProcessesBelowForeground(String reason) {
10590        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10591            throw new SecurityException("killProcessesBelowForeground() only available to system");
10592        }
10593
10594        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10595    }
10596
10597    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10598        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10599            throw new SecurityException("killProcessesBelowAdj() only available to system");
10600        }
10601
10602        boolean killed = false;
10603        synchronized (mPidsSelfLocked) {
10604            final int size = mPidsSelfLocked.size();
10605            for (int i = 0; i < size; i++) {
10606                final int pid = mPidsSelfLocked.keyAt(i);
10607                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10608                if (proc == null) continue;
10609
10610                final int adj = proc.setAdj;
10611                if (adj > belowAdj && !proc.killedByAm) {
10612                    proc.kill(reason, true);
10613                    killed = true;
10614                }
10615            }
10616        }
10617        return killed;
10618    }
10619
10620    @Override
10621    public void hang(final IBinder who, boolean allowRestart) {
10622        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10623                != PackageManager.PERMISSION_GRANTED) {
10624            throw new SecurityException("Requires permission "
10625                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10626        }
10627
10628        final IBinder.DeathRecipient death = new DeathRecipient() {
10629            @Override
10630            public void binderDied() {
10631                synchronized (this) {
10632                    notifyAll();
10633                }
10634            }
10635        };
10636
10637        try {
10638            who.linkToDeath(death, 0);
10639        } catch (RemoteException e) {
10640            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10641            return;
10642        }
10643
10644        synchronized (this) {
10645            Watchdog.getInstance().setAllowRestart(allowRestart);
10646            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10647            synchronized (death) {
10648                while (who.isBinderAlive()) {
10649                    try {
10650                        death.wait();
10651                    } catch (InterruptedException e) {
10652                    }
10653                }
10654            }
10655            Watchdog.getInstance().setAllowRestart(true);
10656        }
10657    }
10658
10659    @Override
10660    public void restart() {
10661        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10662                != PackageManager.PERMISSION_GRANTED) {
10663            throw new SecurityException("Requires permission "
10664                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10665        }
10666
10667        Log.i(TAG, "Sending shutdown broadcast...");
10668
10669        BroadcastReceiver br = new BroadcastReceiver() {
10670            @Override public void onReceive(Context context, Intent intent) {
10671                // Now the broadcast is done, finish up the low-level shutdown.
10672                Log.i(TAG, "Shutting down activity manager...");
10673                shutdown(10000);
10674                Log.i(TAG, "Shutdown complete, restarting!");
10675                Process.killProcess(Process.myPid());
10676                System.exit(10);
10677            }
10678        };
10679
10680        // First send the high-level shut down broadcast.
10681        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10682        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10683        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10684        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10685        mContext.sendOrderedBroadcastAsUser(intent,
10686                UserHandle.ALL, null, br, mHandler, 0, null, null);
10687        */
10688        br.onReceive(mContext, intent);
10689    }
10690
10691    private long getLowRamTimeSinceIdle(long now) {
10692        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10693    }
10694
10695    @Override
10696    public void performIdleMaintenance() {
10697        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10698                != PackageManager.PERMISSION_GRANTED) {
10699            throw new SecurityException("Requires permission "
10700                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10701        }
10702
10703        synchronized (this) {
10704            final long now = SystemClock.uptimeMillis();
10705            final long timeSinceLastIdle = now - mLastIdleTime;
10706            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10707            mLastIdleTime = now;
10708            mLowRamTimeSinceLastIdle = 0;
10709            if (mLowRamStartTime != 0) {
10710                mLowRamStartTime = now;
10711            }
10712
10713            StringBuilder sb = new StringBuilder(128);
10714            sb.append("Idle maintenance over ");
10715            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10716            sb.append(" low RAM for ");
10717            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10718            Slog.i(TAG, sb.toString());
10719
10720            // If at least 1/3 of our time since the last idle period has been spent
10721            // with RAM low, then we want to kill processes.
10722            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10723
10724            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10725                ProcessRecord proc = mLruProcesses.get(i);
10726                if (proc.notCachedSinceIdle) {
10727                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10728                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10729                        if (doKilling && proc.initialIdlePss != 0
10730                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10731                            proc.kill("idle maint (pss " + proc.lastPss
10732                                    + " from " + proc.initialIdlePss + ")", true);
10733                        }
10734                    }
10735                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10736                    proc.notCachedSinceIdle = true;
10737                    proc.initialIdlePss = 0;
10738                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10739                            isSleeping(), now);
10740                }
10741            }
10742
10743            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10744            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10745        }
10746    }
10747
10748    private void retrieveSettings() {
10749        final ContentResolver resolver = mContext.getContentResolver();
10750        String debugApp = Settings.Global.getString(
10751            resolver, Settings.Global.DEBUG_APP);
10752        boolean waitForDebugger = Settings.Global.getInt(
10753            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10754        boolean alwaysFinishActivities = Settings.Global.getInt(
10755            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10756        boolean forceRtl = Settings.Global.getInt(
10757                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10758        // Transfer any global setting for forcing RTL layout, into a System Property
10759        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10760
10761        Configuration configuration = new Configuration();
10762        Settings.System.getConfiguration(resolver, configuration);
10763        if (forceRtl) {
10764            // This will take care of setting the correct layout direction flags
10765            configuration.setLayoutDirection(configuration.locale);
10766        }
10767
10768        synchronized (this) {
10769            mDebugApp = mOrigDebugApp = debugApp;
10770            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10771            mAlwaysFinishActivities = alwaysFinishActivities;
10772            // This happens before any activities are started, so we can
10773            // change mConfiguration in-place.
10774            updateConfigurationLocked(configuration, null, false, true);
10775            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10776        }
10777    }
10778
10779    /** Loads resources after the current configuration has been set. */
10780    private void loadResourcesOnSystemReady() {
10781        final Resources res = mContext.getResources();
10782        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10783        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10784        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10785    }
10786
10787    public boolean testIsSystemReady() {
10788        // no need to synchronize(this) just to read & return the value
10789        return mSystemReady;
10790    }
10791
10792    private static File getCalledPreBootReceiversFile() {
10793        File dataDir = Environment.getDataDirectory();
10794        File systemDir = new File(dataDir, "system");
10795        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10796        return fname;
10797    }
10798
10799    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10800        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10801        File file = getCalledPreBootReceiversFile();
10802        FileInputStream fis = null;
10803        try {
10804            fis = new FileInputStream(file);
10805            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10806            int fvers = dis.readInt();
10807            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10808                String vers = dis.readUTF();
10809                String codename = dis.readUTF();
10810                String build = dis.readUTF();
10811                if (android.os.Build.VERSION.RELEASE.equals(vers)
10812                        && android.os.Build.VERSION.CODENAME.equals(codename)
10813                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10814                    int num = dis.readInt();
10815                    while (num > 0) {
10816                        num--;
10817                        String pkg = dis.readUTF();
10818                        String cls = dis.readUTF();
10819                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10820                    }
10821                }
10822            }
10823        } catch (FileNotFoundException e) {
10824        } catch (IOException e) {
10825            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10826        } finally {
10827            if (fis != null) {
10828                try {
10829                    fis.close();
10830                } catch (IOException e) {
10831                }
10832            }
10833        }
10834        return lastDoneReceivers;
10835    }
10836
10837    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10838        File file = getCalledPreBootReceiversFile();
10839        FileOutputStream fos = null;
10840        DataOutputStream dos = null;
10841        try {
10842            fos = new FileOutputStream(file);
10843            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10844            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10845            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10846            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10847            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10848            dos.writeInt(list.size());
10849            for (int i=0; i<list.size(); i++) {
10850                dos.writeUTF(list.get(i).getPackageName());
10851                dos.writeUTF(list.get(i).getClassName());
10852            }
10853        } catch (IOException e) {
10854            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10855            file.delete();
10856        } finally {
10857            FileUtils.sync(fos);
10858            if (dos != null) {
10859                try {
10860                    dos.close();
10861                } catch (IOException e) {
10862                    // TODO Auto-generated catch block
10863                    e.printStackTrace();
10864                }
10865            }
10866        }
10867    }
10868
10869    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10870            ArrayList<ComponentName> doneReceivers, int userId) {
10871        boolean waitingUpdate = false;
10872        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10873        List<ResolveInfo> ris = null;
10874        try {
10875            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10876                    intent, null, 0, userId);
10877        } catch (RemoteException e) {
10878        }
10879        if (ris != null) {
10880            for (int i=ris.size()-1; i>=0; i--) {
10881                if ((ris.get(i).activityInfo.applicationInfo.flags
10882                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10883                    ris.remove(i);
10884                }
10885            }
10886            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10887
10888            // For User 0, load the version number. When delivering to a new user, deliver
10889            // to all receivers.
10890            if (userId == UserHandle.USER_OWNER) {
10891                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10892                for (int i=0; i<ris.size(); i++) {
10893                    ActivityInfo ai = ris.get(i).activityInfo;
10894                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10895                    if (lastDoneReceivers.contains(comp)) {
10896                        // We already did the pre boot receiver for this app with the current
10897                        // platform version, so don't do it again...
10898                        ris.remove(i);
10899                        i--;
10900                        // ...however, do keep it as one that has been done, so we don't
10901                        // forget about it when rewriting the file of last done receivers.
10902                        doneReceivers.add(comp);
10903                    }
10904                }
10905            }
10906
10907            // If primary user, send broadcast to all available users, else just to userId
10908            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10909                    : new int[] { userId };
10910            for (int i = 0; i < ris.size(); i++) {
10911                ActivityInfo ai = ris.get(i).activityInfo;
10912                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10913                doneReceivers.add(comp);
10914                intent.setComponent(comp);
10915                for (int j=0; j<users.length; j++) {
10916                    IIntentReceiver finisher = null;
10917                    // On last receiver and user, set up a completion callback
10918                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10919                        finisher = new IIntentReceiver.Stub() {
10920                            public void performReceive(Intent intent, int resultCode,
10921                                    String data, Bundle extras, boolean ordered,
10922                                    boolean sticky, int sendingUser) {
10923                                // The raw IIntentReceiver interface is called
10924                                // with the AM lock held, so redispatch to
10925                                // execute our code without the lock.
10926                                mHandler.post(onFinishCallback);
10927                            }
10928                        };
10929                    }
10930                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10931                            + " for user " + users[j]);
10932                    broadcastIntentLocked(null, null, intent, null, finisher,
10933                            0, null, null, null, AppOpsManager.OP_NONE,
10934                            true, false, MY_PID, Process.SYSTEM_UID,
10935                            users[j]);
10936                    if (finisher != null) {
10937                        waitingUpdate = true;
10938                    }
10939                }
10940            }
10941        }
10942
10943        return waitingUpdate;
10944    }
10945
10946    public void systemReady(final Runnable goingCallback) {
10947        synchronized(this) {
10948            if (mSystemReady) {
10949                // If we're done calling all the receivers, run the next "boot phase" passed in
10950                // by the SystemServer
10951                if (goingCallback != null) {
10952                    goingCallback.run();
10953                }
10954                return;
10955            }
10956
10957            // Make sure we have the current profile info, since it is needed for
10958            // security checks.
10959            updateCurrentProfileIdsLocked();
10960
10961            if (mRecentTasks == null) {
10962                mRecentTasks = mTaskPersister.restoreTasksLocked();
10963                if (!mRecentTasks.isEmpty()) {
10964                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10965                }
10966                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10967                mTaskPersister.startPersisting();
10968            }
10969
10970            // Check to see if there are any update receivers to run.
10971            if (!mDidUpdate) {
10972                if (mWaitingUpdate) {
10973                    return;
10974                }
10975                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10976                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10977                    public void run() {
10978                        synchronized (ActivityManagerService.this) {
10979                            mDidUpdate = true;
10980                        }
10981                        writeLastDonePreBootReceivers(doneReceivers);
10982                        showBootMessage(mContext.getText(
10983                                R.string.android_upgrading_complete),
10984                                false);
10985                        systemReady(goingCallback);
10986                    }
10987                }, doneReceivers, UserHandle.USER_OWNER);
10988
10989                if (mWaitingUpdate) {
10990                    return;
10991                }
10992                mDidUpdate = true;
10993            }
10994
10995            mAppOpsService.systemReady();
10996            mSystemReady = true;
10997        }
10998
10999        ArrayList<ProcessRecord> procsToKill = null;
11000        synchronized(mPidsSelfLocked) {
11001            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11002                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11003                if (!isAllowedWhileBooting(proc.info)){
11004                    if (procsToKill == null) {
11005                        procsToKill = new ArrayList<ProcessRecord>();
11006                    }
11007                    procsToKill.add(proc);
11008                }
11009            }
11010        }
11011
11012        synchronized(this) {
11013            if (procsToKill != null) {
11014                for (int i=procsToKill.size()-1; i>=0; i--) {
11015                    ProcessRecord proc = procsToKill.get(i);
11016                    Slog.i(TAG, "Removing system update proc: " + proc);
11017                    removeProcessLocked(proc, true, false, "system update done");
11018                }
11019            }
11020
11021            // Now that we have cleaned up any update processes, we
11022            // are ready to start launching real processes and know that
11023            // we won't trample on them any more.
11024            mProcessesReady = true;
11025        }
11026
11027        Slog.i(TAG, "System now ready");
11028        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11029            SystemClock.uptimeMillis());
11030
11031        synchronized(this) {
11032            // Make sure we have no pre-ready processes sitting around.
11033
11034            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11035                ResolveInfo ri = mContext.getPackageManager()
11036                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11037                                STOCK_PM_FLAGS);
11038                CharSequence errorMsg = null;
11039                if (ri != null) {
11040                    ActivityInfo ai = ri.activityInfo;
11041                    ApplicationInfo app = ai.applicationInfo;
11042                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11043                        mTopAction = Intent.ACTION_FACTORY_TEST;
11044                        mTopData = null;
11045                        mTopComponent = new ComponentName(app.packageName,
11046                                ai.name);
11047                    } else {
11048                        errorMsg = mContext.getResources().getText(
11049                                com.android.internal.R.string.factorytest_not_system);
11050                    }
11051                } else {
11052                    errorMsg = mContext.getResources().getText(
11053                            com.android.internal.R.string.factorytest_no_action);
11054                }
11055                if (errorMsg != null) {
11056                    mTopAction = null;
11057                    mTopData = null;
11058                    mTopComponent = null;
11059                    Message msg = Message.obtain();
11060                    msg.what = SHOW_FACTORY_ERROR_MSG;
11061                    msg.getData().putCharSequence("msg", errorMsg);
11062                    mHandler.sendMessage(msg);
11063                }
11064            }
11065        }
11066
11067        retrieveSettings();
11068        loadResourcesOnSystemReady();
11069
11070        synchronized (this) {
11071            readGrantedUriPermissionsLocked();
11072        }
11073
11074        if (goingCallback != null) goingCallback.run();
11075
11076        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11077                Integer.toString(mCurrentUserId), mCurrentUserId);
11078        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11079                Integer.toString(mCurrentUserId), mCurrentUserId);
11080        mSystemServiceManager.startUser(mCurrentUserId);
11081
11082        synchronized (this) {
11083            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11084                try {
11085                    List apps = AppGlobals.getPackageManager().
11086                        getPersistentApplications(STOCK_PM_FLAGS);
11087                    if (apps != null) {
11088                        int N = apps.size();
11089                        int i;
11090                        for (i=0; i<N; i++) {
11091                            ApplicationInfo info
11092                                = (ApplicationInfo)apps.get(i);
11093                            if (info != null &&
11094                                    !info.packageName.equals("android")) {
11095                                addAppLocked(info, false, null /* ABI override */);
11096                            }
11097                        }
11098                    }
11099                } catch (RemoteException ex) {
11100                    // pm is in same process, this will never happen.
11101                }
11102            }
11103
11104            // Start up initial activity.
11105            mBooting = true;
11106
11107            try {
11108                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11109                    Message msg = Message.obtain();
11110                    msg.what = SHOW_UID_ERROR_MSG;
11111                    mHandler.sendMessage(msg);
11112                }
11113            } catch (RemoteException e) {
11114            }
11115
11116            long ident = Binder.clearCallingIdentity();
11117            try {
11118                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11119                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11120                        | Intent.FLAG_RECEIVER_FOREGROUND);
11121                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11122                broadcastIntentLocked(null, null, intent,
11123                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11124                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11125                intent = new Intent(Intent.ACTION_USER_STARTING);
11126                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11127                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11128                broadcastIntentLocked(null, null, intent,
11129                        null, new IIntentReceiver.Stub() {
11130                            @Override
11131                            public void performReceive(Intent intent, int resultCode, String data,
11132                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11133                                    throws RemoteException {
11134                            }
11135                        }, 0, null, null,
11136                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11137                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11138            } catch (Throwable t) {
11139                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11140            } finally {
11141                Binder.restoreCallingIdentity(ident);
11142            }
11143            mStackSupervisor.resumeTopActivitiesLocked();
11144            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11145        }
11146    }
11147
11148    private boolean makeAppCrashingLocked(ProcessRecord app,
11149            String shortMsg, String longMsg, String stackTrace) {
11150        app.crashing = true;
11151        app.crashingReport = generateProcessError(app,
11152                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11153        startAppProblemLocked(app);
11154        app.stopFreezingAllLocked();
11155        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11156    }
11157
11158    private void makeAppNotRespondingLocked(ProcessRecord app,
11159            String activity, String shortMsg, String longMsg) {
11160        app.notResponding = true;
11161        app.notRespondingReport = generateProcessError(app,
11162                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11163                activity, shortMsg, longMsg, null);
11164        startAppProblemLocked(app);
11165        app.stopFreezingAllLocked();
11166    }
11167
11168    /**
11169     * Generate a process error record, suitable for attachment to a ProcessRecord.
11170     *
11171     * @param app The ProcessRecord in which the error occurred.
11172     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11173     *                      ActivityManager.AppErrorStateInfo
11174     * @param activity The activity associated with the crash, if known.
11175     * @param shortMsg Short message describing the crash.
11176     * @param longMsg Long message describing the crash.
11177     * @param stackTrace Full crash stack trace, may be null.
11178     *
11179     * @return Returns a fully-formed AppErrorStateInfo record.
11180     */
11181    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11182            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11183        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11184
11185        report.condition = condition;
11186        report.processName = app.processName;
11187        report.pid = app.pid;
11188        report.uid = app.info.uid;
11189        report.tag = activity;
11190        report.shortMsg = shortMsg;
11191        report.longMsg = longMsg;
11192        report.stackTrace = stackTrace;
11193
11194        return report;
11195    }
11196
11197    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11198        synchronized (this) {
11199            app.crashing = false;
11200            app.crashingReport = null;
11201            app.notResponding = false;
11202            app.notRespondingReport = null;
11203            if (app.anrDialog == fromDialog) {
11204                app.anrDialog = null;
11205            }
11206            if (app.waitDialog == fromDialog) {
11207                app.waitDialog = null;
11208            }
11209            if (app.pid > 0 && app.pid != MY_PID) {
11210                handleAppCrashLocked(app, null, null, null);
11211                app.kill("user request after error", true);
11212            }
11213        }
11214    }
11215
11216    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11217            String stackTrace) {
11218        long now = SystemClock.uptimeMillis();
11219
11220        Long crashTime;
11221        if (!app.isolated) {
11222            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11223        } else {
11224            crashTime = null;
11225        }
11226        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11227            // This process loses!
11228            Slog.w(TAG, "Process " + app.info.processName
11229                    + " has crashed too many times: killing!");
11230            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11231                    app.userId, app.info.processName, app.uid);
11232            mStackSupervisor.handleAppCrashLocked(app);
11233            if (!app.persistent) {
11234                // We don't want to start this process again until the user
11235                // explicitly does so...  but for persistent process, we really
11236                // need to keep it running.  If a persistent process is actually
11237                // repeatedly crashing, then badness for everyone.
11238                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11239                        app.info.processName);
11240                if (!app.isolated) {
11241                    // XXX We don't have a way to mark isolated processes
11242                    // as bad, since they don't have a peristent identity.
11243                    mBadProcesses.put(app.info.processName, app.uid,
11244                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11245                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11246                }
11247                app.bad = true;
11248                app.removed = true;
11249                // Don't let services in this process be restarted and potentially
11250                // annoy the user repeatedly.  Unless it is persistent, since those
11251                // processes run critical code.
11252                removeProcessLocked(app, false, false, "crash");
11253                mStackSupervisor.resumeTopActivitiesLocked();
11254                return false;
11255            }
11256            mStackSupervisor.resumeTopActivitiesLocked();
11257        } else {
11258            mStackSupervisor.finishTopRunningActivityLocked(app);
11259        }
11260
11261        // Bump up the crash count of any services currently running in the proc.
11262        for (int i=app.services.size()-1; i>=0; i--) {
11263            // Any services running in the application need to be placed
11264            // back in the pending list.
11265            ServiceRecord sr = app.services.valueAt(i);
11266            sr.crashCount++;
11267        }
11268
11269        // If the crashing process is what we consider to be the "home process" and it has been
11270        // replaced by a third-party app, clear the package preferred activities from packages
11271        // with a home activity running in the process to prevent a repeatedly crashing app
11272        // from blocking the user to manually clear the list.
11273        final ArrayList<ActivityRecord> activities = app.activities;
11274        if (app == mHomeProcess && activities.size() > 0
11275                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11276            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11277                final ActivityRecord r = activities.get(activityNdx);
11278                if (r.isHomeActivity()) {
11279                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11280                    try {
11281                        ActivityThread.getPackageManager()
11282                                .clearPackagePreferredActivities(r.packageName);
11283                    } catch (RemoteException c) {
11284                        // pm is in same process, this will never happen.
11285                    }
11286                }
11287            }
11288        }
11289
11290        if (!app.isolated) {
11291            // XXX Can't keep track of crash times for isolated processes,
11292            // because they don't have a perisistent identity.
11293            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11294        }
11295
11296        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11297        return true;
11298    }
11299
11300    void startAppProblemLocked(ProcessRecord app) {
11301        // If this app is not running under the current user, then we
11302        // can't give it a report button because that would require
11303        // launching the report UI under a different user.
11304        app.errorReportReceiver = null;
11305
11306        for (int userId : mCurrentProfileIds) {
11307            if (app.userId == userId) {
11308                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11309                        mContext, app.info.packageName, app.info.flags);
11310            }
11311        }
11312        skipCurrentReceiverLocked(app);
11313    }
11314
11315    void skipCurrentReceiverLocked(ProcessRecord app) {
11316        for (BroadcastQueue queue : mBroadcastQueues) {
11317            queue.skipCurrentReceiverLocked(app);
11318        }
11319    }
11320
11321    /**
11322     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11323     * The application process will exit immediately after this call returns.
11324     * @param app object of the crashing app, null for the system server
11325     * @param crashInfo describing the exception
11326     */
11327    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11328        ProcessRecord r = findAppProcess(app, "Crash");
11329        final String processName = app == null ? "system_server"
11330                : (r == null ? "unknown" : r.processName);
11331
11332        handleApplicationCrashInner("crash", r, processName, crashInfo);
11333    }
11334
11335    /* Native crash reporting uses this inner version because it needs to be somewhat
11336     * decoupled from the AM-managed cleanup lifecycle
11337     */
11338    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11339            ApplicationErrorReport.CrashInfo crashInfo) {
11340        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11341                UserHandle.getUserId(Binder.getCallingUid()), processName,
11342                r == null ? -1 : r.info.flags,
11343                crashInfo.exceptionClassName,
11344                crashInfo.exceptionMessage,
11345                crashInfo.throwFileName,
11346                crashInfo.throwLineNumber);
11347
11348        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11349
11350        crashApplication(r, crashInfo);
11351    }
11352
11353    public void handleApplicationStrictModeViolation(
11354            IBinder app,
11355            int violationMask,
11356            StrictMode.ViolationInfo info) {
11357        ProcessRecord r = findAppProcess(app, "StrictMode");
11358        if (r == null) {
11359            return;
11360        }
11361
11362        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11363            Integer stackFingerprint = info.hashCode();
11364            boolean logIt = true;
11365            synchronized (mAlreadyLoggedViolatedStacks) {
11366                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11367                    logIt = false;
11368                    // TODO: sub-sample into EventLog for these, with
11369                    // the info.durationMillis?  Then we'd get
11370                    // the relative pain numbers, without logging all
11371                    // the stack traces repeatedly.  We'd want to do
11372                    // likewise in the client code, which also does
11373                    // dup suppression, before the Binder call.
11374                } else {
11375                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11376                        mAlreadyLoggedViolatedStacks.clear();
11377                    }
11378                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11379                }
11380            }
11381            if (logIt) {
11382                logStrictModeViolationToDropBox(r, info);
11383            }
11384        }
11385
11386        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11387            AppErrorResult result = new AppErrorResult();
11388            synchronized (this) {
11389                final long origId = Binder.clearCallingIdentity();
11390
11391                Message msg = Message.obtain();
11392                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11393                HashMap<String, Object> data = new HashMap<String, Object>();
11394                data.put("result", result);
11395                data.put("app", r);
11396                data.put("violationMask", violationMask);
11397                data.put("info", info);
11398                msg.obj = data;
11399                mHandler.sendMessage(msg);
11400
11401                Binder.restoreCallingIdentity(origId);
11402            }
11403            int res = result.get();
11404            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11405        }
11406    }
11407
11408    // Depending on the policy in effect, there could be a bunch of
11409    // these in quick succession so we try to batch these together to
11410    // minimize disk writes, number of dropbox entries, and maximize
11411    // compression, by having more fewer, larger records.
11412    private void logStrictModeViolationToDropBox(
11413            ProcessRecord process,
11414            StrictMode.ViolationInfo info) {
11415        if (info == null) {
11416            return;
11417        }
11418        final boolean isSystemApp = process == null ||
11419                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11420                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11421        final String processName = process == null ? "unknown" : process.processName;
11422        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11423        final DropBoxManager dbox = (DropBoxManager)
11424                mContext.getSystemService(Context.DROPBOX_SERVICE);
11425
11426        // Exit early if the dropbox isn't configured to accept this report type.
11427        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11428
11429        boolean bufferWasEmpty;
11430        boolean needsFlush;
11431        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11432        synchronized (sb) {
11433            bufferWasEmpty = sb.length() == 0;
11434            appendDropBoxProcessHeaders(process, processName, sb);
11435            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11436            sb.append("System-App: ").append(isSystemApp).append("\n");
11437            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11438            if (info.violationNumThisLoop != 0) {
11439                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11440            }
11441            if (info.numAnimationsRunning != 0) {
11442                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11443            }
11444            if (info.broadcastIntentAction != null) {
11445                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11446            }
11447            if (info.durationMillis != -1) {
11448                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11449            }
11450            if (info.numInstances != -1) {
11451                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11452            }
11453            if (info.tags != null) {
11454                for (String tag : info.tags) {
11455                    sb.append("Span-Tag: ").append(tag).append("\n");
11456                }
11457            }
11458            sb.append("\n");
11459            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11460                sb.append(info.crashInfo.stackTrace);
11461            }
11462            sb.append("\n");
11463
11464            // Only buffer up to ~64k.  Various logging bits truncate
11465            // things at 128k.
11466            needsFlush = (sb.length() > 64 * 1024);
11467        }
11468
11469        // Flush immediately if the buffer's grown too large, or this
11470        // is a non-system app.  Non-system apps are isolated with a
11471        // different tag & policy and not batched.
11472        //
11473        // Batching is useful during internal testing with
11474        // StrictMode settings turned up high.  Without batching,
11475        // thousands of separate files could be created on boot.
11476        if (!isSystemApp || needsFlush) {
11477            new Thread("Error dump: " + dropboxTag) {
11478                @Override
11479                public void run() {
11480                    String report;
11481                    synchronized (sb) {
11482                        report = sb.toString();
11483                        sb.delete(0, sb.length());
11484                        sb.trimToSize();
11485                    }
11486                    if (report.length() != 0) {
11487                        dbox.addText(dropboxTag, report);
11488                    }
11489                }
11490            }.start();
11491            return;
11492        }
11493
11494        // System app batching:
11495        if (!bufferWasEmpty) {
11496            // An existing dropbox-writing thread is outstanding, so
11497            // we don't need to start it up.  The existing thread will
11498            // catch the buffer appends we just did.
11499            return;
11500        }
11501
11502        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11503        // (After this point, we shouldn't access AMS internal data structures.)
11504        new Thread("Error dump: " + dropboxTag) {
11505            @Override
11506            public void run() {
11507                // 5 second sleep to let stacks arrive and be batched together
11508                try {
11509                    Thread.sleep(5000);  // 5 seconds
11510                } catch (InterruptedException e) {}
11511
11512                String errorReport;
11513                synchronized (mStrictModeBuffer) {
11514                    errorReport = mStrictModeBuffer.toString();
11515                    if (errorReport.length() == 0) {
11516                        return;
11517                    }
11518                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11519                    mStrictModeBuffer.trimToSize();
11520                }
11521                dbox.addText(dropboxTag, errorReport);
11522            }
11523        }.start();
11524    }
11525
11526    /**
11527     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11528     * @param app object of the crashing app, null for the system server
11529     * @param tag reported by the caller
11530     * @param system whether this wtf is coming from the system
11531     * @param crashInfo describing the context of the error
11532     * @return true if the process should exit immediately (WTF is fatal)
11533     */
11534    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11535            final ApplicationErrorReport.CrashInfo crashInfo) {
11536        final ProcessRecord r = findAppProcess(app, "WTF");
11537        final String processName = app == null ? "system_server"
11538                : (r == null ? "unknown" : r.processName);
11539
11540        EventLog.writeEvent(EventLogTags.AM_WTF,
11541                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11542                processName,
11543                r == null ? -1 : r.info.flags,
11544                tag, crashInfo.exceptionMessage);
11545
11546        if (system) {
11547            // If this is coming from the system, we could very well have low-level
11548            // system locks held, so we want to do this all asynchronously.  And we
11549            // never want this to become fatal, so there is that too.
11550            mHandler.post(new Runnable() {
11551                @Override public void run() {
11552                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11553                            crashInfo);
11554                }
11555            });
11556            return false;
11557        }
11558
11559        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11560
11561        if (r != null && r.pid != Process.myPid() &&
11562                Settings.Global.getInt(mContext.getContentResolver(),
11563                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11564            crashApplication(r, crashInfo);
11565            return true;
11566        } else {
11567            return false;
11568        }
11569    }
11570
11571    /**
11572     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11573     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11574     */
11575    private ProcessRecord findAppProcess(IBinder app, String reason) {
11576        if (app == null) {
11577            return null;
11578        }
11579
11580        synchronized (this) {
11581            final int NP = mProcessNames.getMap().size();
11582            for (int ip=0; ip<NP; ip++) {
11583                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11584                final int NA = apps.size();
11585                for (int ia=0; ia<NA; ia++) {
11586                    ProcessRecord p = apps.valueAt(ia);
11587                    if (p.thread != null && p.thread.asBinder() == app) {
11588                        return p;
11589                    }
11590                }
11591            }
11592
11593            Slog.w(TAG, "Can't find mystery application for " + reason
11594                    + " from pid=" + Binder.getCallingPid()
11595                    + " uid=" + Binder.getCallingUid() + ": " + app);
11596            return null;
11597        }
11598    }
11599
11600    /**
11601     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11602     * to append various headers to the dropbox log text.
11603     */
11604    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11605            StringBuilder sb) {
11606        // Watchdog thread ends up invoking this function (with
11607        // a null ProcessRecord) to add the stack file to dropbox.
11608        // Do not acquire a lock on this (am) in such cases, as it
11609        // could cause a potential deadlock, if and when watchdog
11610        // is invoked due to unavailability of lock on am and it
11611        // would prevent watchdog from killing system_server.
11612        if (process == null) {
11613            sb.append("Process: ").append(processName).append("\n");
11614            return;
11615        }
11616        // Note: ProcessRecord 'process' is guarded by the service
11617        // instance.  (notably process.pkgList, which could otherwise change
11618        // concurrently during execution of this method)
11619        synchronized (this) {
11620            sb.append("Process: ").append(processName).append("\n");
11621            int flags = process.info.flags;
11622            IPackageManager pm = AppGlobals.getPackageManager();
11623            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11624            for (int ip=0; ip<process.pkgList.size(); ip++) {
11625                String pkg = process.pkgList.keyAt(ip);
11626                sb.append("Package: ").append(pkg);
11627                try {
11628                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11629                    if (pi != null) {
11630                        sb.append(" v").append(pi.versionCode);
11631                        if (pi.versionName != null) {
11632                            sb.append(" (").append(pi.versionName).append(")");
11633                        }
11634                    }
11635                } catch (RemoteException e) {
11636                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11637                }
11638                sb.append("\n");
11639            }
11640        }
11641    }
11642
11643    private static String processClass(ProcessRecord process) {
11644        if (process == null || process.pid == MY_PID) {
11645            return "system_server";
11646        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11647            return "system_app";
11648        } else {
11649            return "data_app";
11650        }
11651    }
11652
11653    /**
11654     * Write a description of an error (crash, WTF, ANR) to the drop box.
11655     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11656     * @param process which caused the error, null means the system server
11657     * @param activity which triggered the error, null if unknown
11658     * @param parent activity related to the error, null if unknown
11659     * @param subject line related to the error, null if absent
11660     * @param report in long form describing the error, null if absent
11661     * @param logFile to include in the report, null if none
11662     * @param crashInfo giving an application stack trace, null if absent
11663     */
11664    public void addErrorToDropBox(String eventType,
11665            ProcessRecord process, String processName, ActivityRecord activity,
11666            ActivityRecord parent, String subject,
11667            final String report, final File logFile,
11668            final ApplicationErrorReport.CrashInfo crashInfo) {
11669        // NOTE -- this must never acquire the ActivityManagerService lock,
11670        // otherwise the watchdog may be prevented from resetting the system.
11671
11672        final String dropboxTag = processClass(process) + "_" + eventType;
11673        final DropBoxManager dbox = (DropBoxManager)
11674                mContext.getSystemService(Context.DROPBOX_SERVICE);
11675
11676        // Exit early if the dropbox isn't configured to accept this report type.
11677        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11678
11679        final StringBuilder sb = new StringBuilder(1024);
11680        appendDropBoxProcessHeaders(process, processName, sb);
11681        if (activity != null) {
11682            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11683        }
11684        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11685            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11686        }
11687        if (parent != null && parent != activity) {
11688            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11689        }
11690        if (subject != null) {
11691            sb.append("Subject: ").append(subject).append("\n");
11692        }
11693        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11694        if (Debug.isDebuggerConnected()) {
11695            sb.append("Debugger: Connected\n");
11696        }
11697        sb.append("\n");
11698
11699        // Do the rest in a worker thread to avoid blocking the caller on I/O
11700        // (After this point, we shouldn't access AMS internal data structures.)
11701        Thread worker = new Thread("Error dump: " + dropboxTag) {
11702            @Override
11703            public void run() {
11704                if (report != null) {
11705                    sb.append(report);
11706                }
11707                if (logFile != null) {
11708                    try {
11709                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11710                                    "\n\n[[TRUNCATED]]"));
11711                    } catch (IOException e) {
11712                        Slog.e(TAG, "Error reading " + logFile, e);
11713                    }
11714                }
11715                if (crashInfo != null && crashInfo.stackTrace != null) {
11716                    sb.append(crashInfo.stackTrace);
11717                }
11718
11719                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11720                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11721                if (lines > 0) {
11722                    sb.append("\n");
11723
11724                    // Merge several logcat streams, and take the last N lines
11725                    InputStreamReader input = null;
11726                    try {
11727                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11728                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11729                                "-b", "crash",
11730                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11731
11732                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11733                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11734                        input = new InputStreamReader(logcat.getInputStream());
11735
11736                        int num;
11737                        char[] buf = new char[8192];
11738                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11739                    } catch (IOException e) {
11740                        Slog.e(TAG, "Error running logcat", e);
11741                    } finally {
11742                        if (input != null) try { input.close(); } catch (IOException e) {}
11743                    }
11744                }
11745
11746                dbox.addText(dropboxTag, sb.toString());
11747            }
11748        };
11749
11750        if (process == null) {
11751            // If process is null, we are being called from some internal code
11752            // and may be about to die -- run this synchronously.
11753            worker.run();
11754        } else {
11755            worker.start();
11756        }
11757    }
11758
11759    /**
11760     * Bring up the "unexpected error" dialog box for a crashing app.
11761     * Deal with edge cases (intercepts from instrumented applications,
11762     * ActivityController, error intent receivers, that sort of thing).
11763     * @param r the application crashing
11764     * @param crashInfo describing the failure
11765     */
11766    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11767        long timeMillis = System.currentTimeMillis();
11768        String shortMsg = crashInfo.exceptionClassName;
11769        String longMsg = crashInfo.exceptionMessage;
11770        String stackTrace = crashInfo.stackTrace;
11771        if (shortMsg != null && longMsg != null) {
11772            longMsg = shortMsg + ": " + longMsg;
11773        } else if (shortMsg != null) {
11774            longMsg = shortMsg;
11775        }
11776
11777        AppErrorResult result = new AppErrorResult();
11778        synchronized (this) {
11779            if (mController != null) {
11780                try {
11781                    String name = r != null ? r.processName : null;
11782                    int pid = r != null ? r.pid : Binder.getCallingPid();
11783                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11784                    if (!mController.appCrashed(name, pid,
11785                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11786                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11787                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11788                            Slog.w(TAG, "Skip killing native crashed app " + name
11789                                    + "(" + pid + ") during testing");
11790                        } else {
11791                            Slog.w(TAG, "Force-killing crashed app " + name
11792                                    + " at watcher's request");
11793                            if (r != null) {
11794                                r.kill("crash", true);
11795                            } else {
11796                                // Huh.
11797                                Process.killProcess(pid);
11798                                Process.killProcessGroup(uid, pid);
11799                            }
11800                        }
11801                        return;
11802                    }
11803                } catch (RemoteException e) {
11804                    mController = null;
11805                    Watchdog.getInstance().setActivityController(null);
11806                }
11807            }
11808
11809            final long origId = Binder.clearCallingIdentity();
11810
11811            // If this process is running instrumentation, finish it.
11812            if (r != null && r.instrumentationClass != null) {
11813                Slog.w(TAG, "Error in app " + r.processName
11814                      + " running instrumentation " + r.instrumentationClass + ":");
11815                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11816                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11817                Bundle info = new Bundle();
11818                info.putString("shortMsg", shortMsg);
11819                info.putString("longMsg", longMsg);
11820                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11821                Binder.restoreCallingIdentity(origId);
11822                return;
11823            }
11824
11825            // If we can't identify the process or it's already exceeded its crash quota,
11826            // quit right away without showing a crash dialog.
11827            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11828                Binder.restoreCallingIdentity(origId);
11829                return;
11830            }
11831
11832            Message msg = Message.obtain();
11833            msg.what = SHOW_ERROR_MSG;
11834            HashMap data = new HashMap();
11835            data.put("result", result);
11836            data.put("app", r);
11837            msg.obj = data;
11838            mHandler.sendMessage(msg);
11839
11840            Binder.restoreCallingIdentity(origId);
11841        }
11842
11843        int res = result.get();
11844
11845        Intent appErrorIntent = null;
11846        synchronized (this) {
11847            if (r != null && !r.isolated) {
11848                // XXX Can't keep track of crash time for isolated processes,
11849                // since they don't have a persistent identity.
11850                mProcessCrashTimes.put(r.info.processName, r.uid,
11851                        SystemClock.uptimeMillis());
11852            }
11853            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11854                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11855            }
11856        }
11857
11858        if (appErrorIntent != null) {
11859            try {
11860                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11861            } catch (ActivityNotFoundException e) {
11862                Slog.w(TAG, "bug report receiver dissappeared", e);
11863            }
11864        }
11865    }
11866
11867    Intent createAppErrorIntentLocked(ProcessRecord r,
11868            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11869        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11870        if (report == null) {
11871            return null;
11872        }
11873        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11874        result.setComponent(r.errorReportReceiver);
11875        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11876        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11877        return result;
11878    }
11879
11880    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11881            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11882        if (r.errorReportReceiver == null) {
11883            return null;
11884        }
11885
11886        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11887            return null;
11888        }
11889
11890        ApplicationErrorReport report = new ApplicationErrorReport();
11891        report.packageName = r.info.packageName;
11892        report.installerPackageName = r.errorReportReceiver.getPackageName();
11893        report.processName = r.processName;
11894        report.time = timeMillis;
11895        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11896
11897        if (r.crashing || r.forceCrashReport) {
11898            report.type = ApplicationErrorReport.TYPE_CRASH;
11899            report.crashInfo = crashInfo;
11900        } else if (r.notResponding) {
11901            report.type = ApplicationErrorReport.TYPE_ANR;
11902            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11903
11904            report.anrInfo.activity = r.notRespondingReport.tag;
11905            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11906            report.anrInfo.info = r.notRespondingReport.longMsg;
11907        }
11908
11909        return report;
11910    }
11911
11912    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11913        enforceNotIsolatedCaller("getProcessesInErrorState");
11914        // assume our apps are happy - lazy create the list
11915        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11916
11917        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11918                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11919        int userId = UserHandle.getUserId(Binder.getCallingUid());
11920
11921        synchronized (this) {
11922
11923            // iterate across all processes
11924            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11925                ProcessRecord app = mLruProcesses.get(i);
11926                if (!allUsers && app.userId != userId) {
11927                    continue;
11928                }
11929                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11930                    // This one's in trouble, so we'll generate a report for it
11931                    // crashes are higher priority (in case there's a crash *and* an anr)
11932                    ActivityManager.ProcessErrorStateInfo report = null;
11933                    if (app.crashing) {
11934                        report = app.crashingReport;
11935                    } else if (app.notResponding) {
11936                        report = app.notRespondingReport;
11937                    }
11938
11939                    if (report != null) {
11940                        if (errList == null) {
11941                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11942                        }
11943                        errList.add(report);
11944                    } else {
11945                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11946                                " crashing = " + app.crashing +
11947                                " notResponding = " + app.notResponding);
11948                    }
11949                }
11950            }
11951        }
11952
11953        return errList;
11954    }
11955
11956    static int procStateToImportance(int procState, int memAdj,
11957            ActivityManager.RunningAppProcessInfo currApp) {
11958        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11959        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11960            currApp.lru = memAdj;
11961        } else {
11962            currApp.lru = 0;
11963        }
11964        return imp;
11965    }
11966
11967    private void fillInProcMemInfo(ProcessRecord app,
11968            ActivityManager.RunningAppProcessInfo outInfo) {
11969        outInfo.pid = app.pid;
11970        outInfo.uid = app.info.uid;
11971        if (mHeavyWeightProcess == app) {
11972            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11973        }
11974        if (app.persistent) {
11975            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11976        }
11977        if (app.activities.size() > 0) {
11978            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11979        }
11980        outInfo.lastTrimLevel = app.trimMemoryLevel;
11981        int adj = app.curAdj;
11982        int procState = app.curProcState;
11983        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11984        outInfo.importanceReasonCode = app.adjTypeCode;
11985        outInfo.processState = app.curProcState;
11986    }
11987
11988    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11989        enforceNotIsolatedCaller("getRunningAppProcesses");
11990        // Lazy instantiation of list
11991        List<ActivityManager.RunningAppProcessInfo> runList = null;
11992        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11993                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11994        int userId = UserHandle.getUserId(Binder.getCallingUid());
11995        synchronized (this) {
11996            // Iterate across all processes
11997            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11998                ProcessRecord app = mLruProcesses.get(i);
11999                if (!allUsers && app.userId != userId) {
12000                    continue;
12001                }
12002                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12003                    // Generate process state info for running application
12004                    ActivityManager.RunningAppProcessInfo currApp =
12005                        new ActivityManager.RunningAppProcessInfo(app.processName,
12006                                app.pid, app.getPackageList());
12007                    fillInProcMemInfo(app, currApp);
12008                    if (app.adjSource instanceof ProcessRecord) {
12009                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12010                        currApp.importanceReasonImportance =
12011                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12012                                        app.adjSourceProcState);
12013                    } else if (app.adjSource instanceof ActivityRecord) {
12014                        ActivityRecord r = (ActivityRecord)app.adjSource;
12015                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12016                    }
12017                    if (app.adjTarget instanceof ComponentName) {
12018                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12019                    }
12020                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12021                    //        + " lru=" + currApp.lru);
12022                    if (runList == null) {
12023                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12024                    }
12025                    runList.add(currApp);
12026                }
12027            }
12028        }
12029        return runList;
12030    }
12031
12032    public List<ApplicationInfo> getRunningExternalApplications() {
12033        enforceNotIsolatedCaller("getRunningExternalApplications");
12034        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12035        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12036        if (runningApps != null && runningApps.size() > 0) {
12037            Set<String> extList = new HashSet<String>();
12038            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12039                if (app.pkgList != null) {
12040                    for (String pkg : app.pkgList) {
12041                        extList.add(pkg);
12042                    }
12043                }
12044            }
12045            IPackageManager pm = AppGlobals.getPackageManager();
12046            for (String pkg : extList) {
12047                try {
12048                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12049                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12050                        retList.add(info);
12051                    }
12052                } catch (RemoteException e) {
12053                }
12054            }
12055        }
12056        return retList;
12057    }
12058
12059    @Override
12060    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12061        enforceNotIsolatedCaller("getMyMemoryState");
12062        synchronized (this) {
12063            ProcessRecord proc;
12064            synchronized (mPidsSelfLocked) {
12065                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12066            }
12067            fillInProcMemInfo(proc, outInfo);
12068        }
12069    }
12070
12071    @Override
12072    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12073        if (checkCallingPermission(android.Manifest.permission.DUMP)
12074                != PackageManager.PERMISSION_GRANTED) {
12075            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12076                    + Binder.getCallingPid()
12077                    + ", uid=" + Binder.getCallingUid()
12078                    + " without permission "
12079                    + android.Manifest.permission.DUMP);
12080            return;
12081        }
12082
12083        boolean dumpAll = false;
12084        boolean dumpClient = false;
12085        String dumpPackage = null;
12086
12087        int opti = 0;
12088        while (opti < args.length) {
12089            String opt = args[opti];
12090            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12091                break;
12092            }
12093            opti++;
12094            if ("-a".equals(opt)) {
12095                dumpAll = true;
12096            } else if ("-c".equals(opt)) {
12097                dumpClient = true;
12098            } else if ("-h".equals(opt)) {
12099                pw.println("Activity manager dump options:");
12100                pw.println("  [-a] [-c] [-h] [cmd] ...");
12101                pw.println("  cmd may be one of:");
12102                pw.println("    a[ctivities]: activity stack state");
12103                pw.println("    r[recents]: recent activities state");
12104                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12105                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12106                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12107                pw.println("    o[om]: out of memory management");
12108                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12109                pw.println("    provider [COMP_SPEC]: provider client-side state");
12110                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12111                pw.println("    service [COMP_SPEC]: service client-side state");
12112                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12113                pw.println("    all: dump all activities");
12114                pw.println("    top: dump the top activity");
12115                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12116                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12117                pw.println("    a partial substring in a component name, a");
12118                pw.println("    hex object identifier.");
12119                pw.println("  -a: include all available server state.");
12120                pw.println("  -c: include client state.");
12121                return;
12122            } else {
12123                pw.println("Unknown argument: " + opt + "; use -h for help");
12124            }
12125        }
12126
12127        long origId = Binder.clearCallingIdentity();
12128        boolean more = false;
12129        // Is the caller requesting to dump a particular piece of data?
12130        if (opti < args.length) {
12131            String cmd = args[opti];
12132            opti++;
12133            if ("activities".equals(cmd) || "a".equals(cmd)) {
12134                synchronized (this) {
12135                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12136                }
12137            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12138                synchronized (this) {
12139                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12140                }
12141            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12142                String[] newArgs;
12143                String name;
12144                if (opti >= args.length) {
12145                    name = null;
12146                    newArgs = EMPTY_STRING_ARRAY;
12147                } else {
12148                    name = args[opti];
12149                    opti++;
12150                    newArgs = new String[args.length - opti];
12151                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12152                            args.length - opti);
12153                }
12154                synchronized (this) {
12155                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12156                }
12157            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12158                String[] newArgs;
12159                String name;
12160                if (opti >= args.length) {
12161                    name = null;
12162                    newArgs = EMPTY_STRING_ARRAY;
12163                } else {
12164                    name = args[opti];
12165                    opti++;
12166                    newArgs = new String[args.length - opti];
12167                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12168                            args.length - opti);
12169                }
12170                synchronized (this) {
12171                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12172                }
12173            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12174                String[] newArgs;
12175                String name;
12176                if (opti >= args.length) {
12177                    name = null;
12178                    newArgs = EMPTY_STRING_ARRAY;
12179                } else {
12180                    name = args[opti];
12181                    opti++;
12182                    newArgs = new String[args.length - opti];
12183                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12184                            args.length - opti);
12185                }
12186                synchronized (this) {
12187                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12188                }
12189            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12190                synchronized (this) {
12191                    dumpOomLocked(fd, pw, args, opti, true);
12192                }
12193            } else if ("provider".equals(cmd)) {
12194                String[] newArgs;
12195                String name;
12196                if (opti >= args.length) {
12197                    name = null;
12198                    newArgs = EMPTY_STRING_ARRAY;
12199                } else {
12200                    name = args[opti];
12201                    opti++;
12202                    newArgs = new String[args.length - opti];
12203                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12204                }
12205                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12206                    pw.println("No providers match: " + name);
12207                    pw.println("Use -h for help.");
12208                }
12209            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12210                synchronized (this) {
12211                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12212                }
12213            } else if ("service".equals(cmd)) {
12214                String[] newArgs;
12215                String name;
12216                if (opti >= args.length) {
12217                    name = null;
12218                    newArgs = EMPTY_STRING_ARRAY;
12219                } else {
12220                    name = args[opti];
12221                    opti++;
12222                    newArgs = new String[args.length - opti];
12223                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12224                            args.length - opti);
12225                }
12226                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12227                    pw.println("No services match: " + name);
12228                    pw.println("Use -h for help.");
12229                }
12230            } else if ("package".equals(cmd)) {
12231                String[] newArgs;
12232                if (opti >= args.length) {
12233                    pw.println("package: no package name specified");
12234                    pw.println("Use -h for help.");
12235                } else {
12236                    dumpPackage = args[opti];
12237                    opti++;
12238                    newArgs = new String[args.length - opti];
12239                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12240                            args.length - opti);
12241                    args = newArgs;
12242                    opti = 0;
12243                    more = true;
12244                }
12245            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12246                synchronized (this) {
12247                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12248                }
12249            } else {
12250                // Dumping a single activity?
12251                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12252                    pw.println("Bad activity command, or no activities match: " + cmd);
12253                    pw.println("Use -h for help.");
12254                }
12255            }
12256            if (!more) {
12257                Binder.restoreCallingIdentity(origId);
12258                return;
12259            }
12260        }
12261
12262        // No piece of data specified, dump everything.
12263        synchronized (this) {
12264            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12265            pw.println();
12266            if (dumpAll) {
12267                pw.println("-------------------------------------------------------------------------------");
12268            }
12269            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12270            pw.println();
12271            if (dumpAll) {
12272                pw.println("-------------------------------------------------------------------------------");
12273            }
12274            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12275            pw.println();
12276            if (dumpAll) {
12277                pw.println("-------------------------------------------------------------------------------");
12278            }
12279            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12280            pw.println();
12281            if (dumpAll) {
12282                pw.println("-------------------------------------------------------------------------------");
12283            }
12284            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12285            pw.println();
12286            if (dumpAll) {
12287                pw.println("-------------------------------------------------------------------------------");
12288            }
12289            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12290            pw.println();
12291            if (dumpAll) {
12292                pw.println("-------------------------------------------------------------------------------");
12293            }
12294            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12295        }
12296        Binder.restoreCallingIdentity(origId);
12297    }
12298
12299    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12300            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12301        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12302
12303        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12304                dumpPackage);
12305        boolean needSep = printedAnything;
12306
12307        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12308                dumpPackage, needSep, "  mFocusedActivity: ");
12309        if (printed) {
12310            printedAnything = true;
12311            needSep = false;
12312        }
12313
12314        if (dumpPackage == null) {
12315            if (needSep) {
12316                pw.println();
12317            }
12318            needSep = true;
12319            printedAnything = true;
12320            mStackSupervisor.dump(pw, "  ");
12321        }
12322
12323        if (!printedAnything) {
12324            pw.println("  (nothing)");
12325        }
12326    }
12327
12328    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12329            int opti, boolean dumpAll, String dumpPackage) {
12330        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12331
12332        boolean printedAnything = false;
12333
12334        if (mRecentTasks.size() > 0) {
12335            boolean printedHeader = false;
12336
12337            final int N = mRecentTasks.size();
12338            for (int i=0; i<N; i++) {
12339                TaskRecord tr = mRecentTasks.get(i);
12340                if (dumpPackage != null) {
12341                    if (tr.realActivity == null ||
12342                            !dumpPackage.equals(tr.realActivity)) {
12343                        continue;
12344                    }
12345                }
12346                if (!printedHeader) {
12347                    pw.println("  Recent tasks:");
12348                    printedHeader = true;
12349                    printedAnything = true;
12350                }
12351                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12352                        pw.println(tr);
12353                if (dumpAll) {
12354                    mRecentTasks.get(i).dump(pw, "    ");
12355                }
12356            }
12357        }
12358
12359        if (!printedAnything) {
12360            pw.println("  (nothing)");
12361        }
12362    }
12363
12364    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12365            int opti, boolean dumpAll, String dumpPackage) {
12366        boolean needSep = false;
12367        boolean printedAnything = false;
12368        int numPers = 0;
12369
12370        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12371
12372        if (dumpAll) {
12373            final int NP = mProcessNames.getMap().size();
12374            for (int ip=0; ip<NP; ip++) {
12375                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12376                final int NA = procs.size();
12377                for (int ia=0; ia<NA; ia++) {
12378                    ProcessRecord r = procs.valueAt(ia);
12379                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12380                        continue;
12381                    }
12382                    if (!needSep) {
12383                        pw.println("  All known processes:");
12384                        needSep = true;
12385                        printedAnything = true;
12386                    }
12387                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12388                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12389                        pw.print(" "); pw.println(r);
12390                    r.dump(pw, "    ");
12391                    if (r.persistent) {
12392                        numPers++;
12393                    }
12394                }
12395            }
12396        }
12397
12398        if (mIsolatedProcesses.size() > 0) {
12399            boolean printed = false;
12400            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12401                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12402                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12403                    continue;
12404                }
12405                if (!printed) {
12406                    if (needSep) {
12407                        pw.println();
12408                    }
12409                    pw.println("  Isolated process list (sorted by uid):");
12410                    printedAnything = true;
12411                    printed = true;
12412                    needSep = true;
12413                }
12414                pw.println(String.format("%sIsolated #%2d: %s",
12415                        "    ", i, r.toString()));
12416            }
12417        }
12418
12419        if (mLruProcesses.size() > 0) {
12420            if (needSep) {
12421                pw.println();
12422            }
12423            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12424                    pw.print(" total, non-act at ");
12425                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12426                    pw.print(", non-svc at ");
12427                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12428                    pw.println("):");
12429            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12430            needSep = true;
12431            printedAnything = true;
12432        }
12433
12434        if (dumpAll || dumpPackage != null) {
12435            synchronized (mPidsSelfLocked) {
12436                boolean printed = false;
12437                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12438                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12439                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12440                        continue;
12441                    }
12442                    if (!printed) {
12443                        if (needSep) pw.println();
12444                        needSep = true;
12445                        pw.println("  PID mappings:");
12446                        printed = true;
12447                        printedAnything = true;
12448                    }
12449                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12450                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12451                }
12452            }
12453        }
12454
12455        if (mForegroundProcesses.size() > 0) {
12456            synchronized (mPidsSelfLocked) {
12457                boolean printed = false;
12458                for (int i=0; i<mForegroundProcesses.size(); i++) {
12459                    ProcessRecord r = mPidsSelfLocked.get(
12460                            mForegroundProcesses.valueAt(i).pid);
12461                    if (dumpPackage != null && (r == null
12462                            || !r.pkgList.containsKey(dumpPackage))) {
12463                        continue;
12464                    }
12465                    if (!printed) {
12466                        if (needSep) pw.println();
12467                        needSep = true;
12468                        pw.println("  Foreground Processes:");
12469                        printed = true;
12470                        printedAnything = true;
12471                    }
12472                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12473                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12474                }
12475            }
12476        }
12477
12478        if (mPersistentStartingProcesses.size() > 0) {
12479            if (needSep) pw.println();
12480            needSep = true;
12481            printedAnything = true;
12482            pw.println("  Persisent processes that are starting:");
12483            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12484                    "Starting Norm", "Restarting PERS", dumpPackage);
12485        }
12486
12487        if (mRemovedProcesses.size() > 0) {
12488            if (needSep) pw.println();
12489            needSep = true;
12490            printedAnything = true;
12491            pw.println("  Processes that are being removed:");
12492            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12493                    "Removed Norm", "Removed PERS", dumpPackage);
12494        }
12495
12496        if (mProcessesOnHold.size() > 0) {
12497            if (needSep) pw.println();
12498            needSep = true;
12499            printedAnything = true;
12500            pw.println("  Processes that are on old until the system is ready:");
12501            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12502                    "OnHold Norm", "OnHold PERS", dumpPackage);
12503        }
12504
12505        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12506
12507        if (mProcessCrashTimes.getMap().size() > 0) {
12508            boolean printed = false;
12509            long now = SystemClock.uptimeMillis();
12510            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12511            final int NP = pmap.size();
12512            for (int ip=0; ip<NP; ip++) {
12513                String pname = pmap.keyAt(ip);
12514                SparseArray<Long> uids = pmap.valueAt(ip);
12515                final int N = uids.size();
12516                for (int i=0; i<N; i++) {
12517                    int puid = uids.keyAt(i);
12518                    ProcessRecord r = mProcessNames.get(pname, puid);
12519                    if (dumpPackage != null && (r == null
12520                            || !r.pkgList.containsKey(dumpPackage))) {
12521                        continue;
12522                    }
12523                    if (!printed) {
12524                        if (needSep) pw.println();
12525                        needSep = true;
12526                        pw.println("  Time since processes crashed:");
12527                        printed = true;
12528                        printedAnything = true;
12529                    }
12530                    pw.print("    Process "); pw.print(pname);
12531                            pw.print(" uid "); pw.print(puid);
12532                            pw.print(": last crashed ");
12533                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12534                            pw.println(" ago");
12535                }
12536            }
12537        }
12538
12539        if (mBadProcesses.getMap().size() > 0) {
12540            boolean printed = false;
12541            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12542            final int NP = pmap.size();
12543            for (int ip=0; ip<NP; ip++) {
12544                String pname = pmap.keyAt(ip);
12545                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12546                final int N = uids.size();
12547                for (int i=0; i<N; i++) {
12548                    int puid = uids.keyAt(i);
12549                    ProcessRecord r = mProcessNames.get(pname, puid);
12550                    if (dumpPackage != null && (r == null
12551                            || !r.pkgList.containsKey(dumpPackage))) {
12552                        continue;
12553                    }
12554                    if (!printed) {
12555                        if (needSep) pw.println();
12556                        needSep = true;
12557                        pw.println("  Bad processes:");
12558                        printedAnything = true;
12559                    }
12560                    BadProcessInfo info = uids.valueAt(i);
12561                    pw.print("    Bad process "); pw.print(pname);
12562                            pw.print(" uid "); pw.print(puid);
12563                            pw.print(": crashed at time "); pw.println(info.time);
12564                    if (info.shortMsg != null) {
12565                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12566                    }
12567                    if (info.longMsg != null) {
12568                        pw.print("      Long msg: "); pw.println(info.longMsg);
12569                    }
12570                    if (info.stack != null) {
12571                        pw.println("      Stack:");
12572                        int lastPos = 0;
12573                        for (int pos=0; pos<info.stack.length(); pos++) {
12574                            if (info.stack.charAt(pos) == '\n') {
12575                                pw.print("        ");
12576                                pw.write(info.stack, lastPos, pos-lastPos);
12577                                pw.println();
12578                                lastPos = pos+1;
12579                            }
12580                        }
12581                        if (lastPos < info.stack.length()) {
12582                            pw.print("        ");
12583                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12584                            pw.println();
12585                        }
12586                    }
12587                }
12588            }
12589        }
12590
12591        if (dumpPackage == null) {
12592            pw.println();
12593            needSep = false;
12594            pw.println("  mStartedUsers:");
12595            for (int i=0; i<mStartedUsers.size(); i++) {
12596                UserStartedState uss = mStartedUsers.valueAt(i);
12597                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12598                        pw.print(": "); uss.dump("", pw);
12599            }
12600            pw.print("  mStartedUserArray: [");
12601            for (int i=0; i<mStartedUserArray.length; i++) {
12602                if (i > 0) pw.print(", ");
12603                pw.print(mStartedUserArray[i]);
12604            }
12605            pw.println("]");
12606            pw.print("  mUserLru: [");
12607            for (int i=0; i<mUserLru.size(); i++) {
12608                if (i > 0) pw.print(", ");
12609                pw.print(mUserLru.get(i));
12610            }
12611            pw.println("]");
12612            if (dumpAll) {
12613                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12614            }
12615            synchronized (mUserProfileGroupIdsSelfLocked) {
12616                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12617                    pw.println("  mUserProfileGroupIds:");
12618                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12619                        pw.print("    User #");
12620                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12621                        pw.print(" -> profile #");
12622                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12623                    }
12624                }
12625            }
12626        }
12627        if (mHomeProcess != null && (dumpPackage == null
12628                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12629            if (needSep) {
12630                pw.println();
12631                needSep = false;
12632            }
12633            pw.println("  mHomeProcess: " + mHomeProcess);
12634        }
12635        if (mPreviousProcess != null && (dumpPackage == null
12636                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12637            if (needSep) {
12638                pw.println();
12639                needSep = false;
12640            }
12641            pw.println("  mPreviousProcess: " + mPreviousProcess);
12642        }
12643        if (dumpAll) {
12644            StringBuilder sb = new StringBuilder(128);
12645            sb.append("  mPreviousProcessVisibleTime: ");
12646            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12647            pw.println(sb);
12648        }
12649        if (mHeavyWeightProcess != null && (dumpPackage == null
12650                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12651            if (needSep) {
12652                pw.println();
12653                needSep = false;
12654            }
12655            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12656        }
12657        if (dumpPackage == null) {
12658            pw.println("  mConfiguration: " + mConfiguration);
12659        }
12660        if (dumpAll) {
12661            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12662            if (mCompatModePackages.getPackages().size() > 0) {
12663                boolean printed = false;
12664                for (Map.Entry<String, Integer> entry
12665                        : mCompatModePackages.getPackages().entrySet()) {
12666                    String pkg = entry.getKey();
12667                    int mode = entry.getValue();
12668                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12669                        continue;
12670                    }
12671                    if (!printed) {
12672                        pw.println("  mScreenCompatPackages:");
12673                        printed = true;
12674                    }
12675                    pw.print("    "); pw.print(pkg); pw.print(": ");
12676                            pw.print(mode); pw.println();
12677                }
12678            }
12679        }
12680        if (dumpPackage == null) {
12681            if (mSleeping || mWentToSleep || mLockScreenShown) {
12682                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12683                        + " mLockScreenShown " + mLockScreenShown);
12684            }
12685            if (mShuttingDown || mRunningVoice) {
12686                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12687            }
12688        }
12689        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12690                || mOrigWaitForDebugger) {
12691            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12692                    || dumpPackage.equals(mOrigDebugApp)) {
12693                if (needSep) {
12694                    pw.println();
12695                    needSep = false;
12696                }
12697                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12698                        + " mDebugTransient=" + mDebugTransient
12699                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12700            }
12701        }
12702        if (mOpenGlTraceApp != null) {
12703            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12704                if (needSep) {
12705                    pw.println();
12706                    needSep = false;
12707                }
12708                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12709            }
12710        }
12711        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12712                || mProfileFd != null) {
12713            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12714                if (needSep) {
12715                    pw.println();
12716                    needSep = false;
12717                }
12718                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12719                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12720                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12721                        + mAutoStopProfiler);
12722                pw.println("  mProfileType=" + mProfileType);
12723            }
12724        }
12725        if (dumpPackage == null) {
12726            if (mAlwaysFinishActivities || mController != null) {
12727                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12728                        + " mController=" + mController);
12729            }
12730            if (dumpAll) {
12731                pw.println("  Total persistent processes: " + numPers);
12732                pw.println("  mProcessesReady=" + mProcessesReady
12733                        + " mSystemReady=" + mSystemReady);
12734                pw.println("  mBooting=" + mBooting
12735                        + " mBooted=" + mBooted
12736                        + " mFactoryTest=" + mFactoryTest);
12737                pw.print("  mLastPowerCheckRealtime=");
12738                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12739                        pw.println("");
12740                pw.print("  mLastPowerCheckUptime=");
12741                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12742                        pw.println("");
12743                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12744                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12745                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12746                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12747                        + " (" + mLruProcesses.size() + " total)"
12748                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12749                        + " mNumServiceProcs=" + mNumServiceProcs
12750                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12751                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12752                        + " mLastMemoryLevel" + mLastMemoryLevel
12753                        + " mLastNumProcesses" + mLastNumProcesses);
12754                long now = SystemClock.uptimeMillis();
12755                pw.print("  mLastIdleTime=");
12756                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12757                        pw.print(" mLowRamSinceLastIdle=");
12758                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12759                        pw.println();
12760            }
12761        }
12762
12763        if (!printedAnything) {
12764            pw.println("  (nothing)");
12765        }
12766    }
12767
12768    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12769            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12770        if (mProcessesToGc.size() > 0) {
12771            boolean printed = false;
12772            long now = SystemClock.uptimeMillis();
12773            for (int i=0; i<mProcessesToGc.size(); i++) {
12774                ProcessRecord proc = mProcessesToGc.get(i);
12775                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12776                    continue;
12777                }
12778                if (!printed) {
12779                    if (needSep) pw.println();
12780                    needSep = true;
12781                    pw.println("  Processes that are waiting to GC:");
12782                    printed = true;
12783                }
12784                pw.print("    Process "); pw.println(proc);
12785                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12786                        pw.print(", last gced=");
12787                        pw.print(now-proc.lastRequestedGc);
12788                        pw.print(" ms ago, last lowMem=");
12789                        pw.print(now-proc.lastLowMemory);
12790                        pw.println(" ms ago");
12791
12792            }
12793        }
12794        return needSep;
12795    }
12796
12797    void printOomLevel(PrintWriter pw, String name, int adj) {
12798        pw.print("    ");
12799        if (adj >= 0) {
12800            pw.print(' ');
12801            if (adj < 10) pw.print(' ');
12802        } else {
12803            if (adj > -10) pw.print(' ');
12804        }
12805        pw.print(adj);
12806        pw.print(": ");
12807        pw.print(name);
12808        pw.print(" (");
12809        pw.print(mProcessList.getMemLevel(adj)/1024);
12810        pw.println(" kB)");
12811    }
12812
12813    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12814            int opti, boolean dumpAll) {
12815        boolean needSep = false;
12816
12817        if (mLruProcesses.size() > 0) {
12818            if (needSep) pw.println();
12819            needSep = true;
12820            pw.println("  OOM levels:");
12821            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12822            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12823            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12824            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12825            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12826            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12827            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12828            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12829            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12830            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12831            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12832            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12833            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12834
12835            if (needSep) pw.println();
12836            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12837                    pw.print(" total, non-act at ");
12838                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12839                    pw.print(", non-svc at ");
12840                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12841                    pw.println("):");
12842            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12843            needSep = true;
12844        }
12845
12846        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12847
12848        pw.println();
12849        pw.println("  mHomeProcess: " + mHomeProcess);
12850        pw.println("  mPreviousProcess: " + mPreviousProcess);
12851        if (mHeavyWeightProcess != null) {
12852            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12853        }
12854
12855        return true;
12856    }
12857
12858    /**
12859     * There are three ways to call this:
12860     *  - no provider specified: dump all the providers
12861     *  - a flattened component name that matched an existing provider was specified as the
12862     *    first arg: dump that one provider
12863     *  - the first arg isn't the flattened component name of an existing provider:
12864     *    dump all providers whose component contains the first arg as a substring
12865     */
12866    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12867            int opti, boolean dumpAll) {
12868        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12869    }
12870
12871    static class ItemMatcher {
12872        ArrayList<ComponentName> components;
12873        ArrayList<String> strings;
12874        ArrayList<Integer> objects;
12875        boolean all;
12876
12877        ItemMatcher() {
12878            all = true;
12879        }
12880
12881        void build(String name) {
12882            ComponentName componentName = ComponentName.unflattenFromString(name);
12883            if (componentName != null) {
12884                if (components == null) {
12885                    components = new ArrayList<ComponentName>();
12886                }
12887                components.add(componentName);
12888                all = false;
12889            } else {
12890                int objectId = 0;
12891                // Not a '/' separated full component name; maybe an object ID?
12892                try {
12893                    objectId = Integer.parseInt(name, 16);
12894                    if (objects == null) {
12895                        objects = new ArrayList<Integer>();
12896                    }
12897                    objects.add(objectId);
12898                    all = false;
12899                } catch (RuntimeException e) {
12900                    // Not an integer; just do string match.
12901                    if (strings == null) {
12902                        strings = new ArrayList<String>();
12903                    }
12904                    strings.add(name);
12905                    all = false;
12906                }
12907            }
12908        }
12909
12910        int build(String[] args, int opti) {
12911            for (; opti<args.length; opti++) {
12912                String name = args[opti];
12913                if ("--".equals(name)) {
12914                    return opti+1;
12915                }
12916                build(name);
12917            }
12918            return opti;
12919        }
12920
12921        boolean match(Object object, ComponentName comp) {
12922            if (all) {
12923                return true;
12924            }
12925            if (components != null) {
12926                for (int i=0; i<components.size(); i++) {
12927                    if (components.get(i).equals(comp)) {
12928                        return true;
12929                    }
12930                }
12931            }
12932            if (objects != null) {
12933                for (int i=0; i<objects.size(); i++) {
12934                    if (System.identityHashCode(object) == objects.get(i)) {
12935                        return true;
12936                    }
12937                }
12938            }
12939            if (strings != null) {
12940                String flat = comp.flattenToString();
12941                for (int i=0; i<strings.size(); i++) {
12942                    if (flat.contains(strings.get(i))) {
12943                        return true;
12944                    }
12945                }
12946            }
12947            return false;
12948        }
12949    }
12950
12951    /**
12952     * There are three things that cmd can be:
12953     *  - a flattened component name that matches an existing activity
12954     *  - the cmd arg isn't the flattened component name of an existing activity:
12955     *    dump all activity whose component contains the cmd as a substring
12956     *  - A hex number of the ActivityRecord object instance.
12957     */
12958    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12959            int opti, boolean dumpAll) {
12960        ArrayList<ActivityRecord> activities;
12961
12962        synchronized (this) {
12963            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12964        }
12965
12966        if (activities.size() <= 0) {
12967            return false;
12968        }
12969
12970        String[] newArgs = new String[args.length - opti];
12971        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12972
12973        TaskRecord lastTask = null;
12974        boolean needSep = false;
12975        for (int i=activities.size()-1; i>=0; i--) {
12976            ActivityRecord r = activities.get(i);
12977            if (needSep) {
12978                pw.println();
12979            }
12980            needSep = true;
12981            synchronized (this) {
12982                if (lastTask != r.task) {
12983                    lastTask = r.task;
12984                    pw.print("TASK "); pw.print(lastTask.affinity);
12985                            pw.print(" id="); pw.println(lastTask.taskId);
12986                    if (dumpAll) {
12987                        lastTask.dump(pw, "  ");
12988                    }
12989                }
12990            }
12991            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12992        }
12993        return true;
12994    }
12995
12996    /**
12997     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12998     * there is a thread associated with the activity.
12999     */
13000    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13001            final ActivityRecord r, String[] args, boolean dumpAll) {
13002        String innerPrefix = prefix + "  ";
13003        synchronized (this) {
13004            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13005                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13006                    pw.print(" pid=");
13007                    if (r.app != null) pw.println(r.app.pid);
13008                    else pw.println("(not running)");
13009            if (dumpAll) {
13010                r.dump(pw, innerPrefix);
13011            }
13012        }
13013        if (r.app != null && r.app.thread != null) {
13014            // flush anything that is already in the PrintWriter since the thread is going
13015            // to write to the file descriptor directly
13016            pw.flush();
13017            try {
13018                TransferPipe tp = new TransferPipe();
13019                try {
13020                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13021                            r.appToken, innerPrefix, args);
13022                    tp.go(fd);
13023                } finally {
13024                    tp.kill();
13025                }
13026            } catch (IOException e) {
13027                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13028            } catch (RemoteException e) {
13029                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13030            }
13031        }
13032    }
13033
13034    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13035            int opti, boolean dumpAll, String dumpPackage) {
13036        boolean needSep = false;
13037        boolean onlyHistory = false;
13038        boolean printedAnything = false;
13039
13040        if ("history".equals(dumpPackage)) {
13041            if (opti < args.length && "-s".equals(args[opti])) {
13042                dumpAll = false;
13043            }
13044            onlyHistory = true;
13045            dumpPackage = null;
13046        }
13047
13048        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13049        if (!onlyHistory && dumpAll) {
13050            if (mRegisteredReceivers.size() > 0) {
13051                boolean printed = false;
13052                Iterator it = mRegisteredReceivers.values().iterator();
13053                while (it.hasNext()) {
13054                    ReceiverList r = (ReceiverList)it.next();
13055                    if (dumpPackage != null && (r.app == null ||
13056                            !dumpPackage.equals(r.app.info.packageName))) {
13057                        continue;
13058                    }
13059                    if (!printed) {
13060                        pw.println("  Registered Receivers:");
13061                        needSep = true;
13062                        printed = true;
13063                        printedAnything = true;
13064                    }
13065                    pw.print("  * "); pw.println(r);
13066                    r.dump(pw, "    ");
13067                }
13068            }
13069
13070            if (mReceiverResolver.dump(pw, needSep ?
13071                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13072                    "    ", dumpPackage, false)) {
13073                needSep = true;
13074                printedAnything = true;
13075            }
13076        }
13077
13078        for (BroadcastQueue q : mBroadcastQueues) {
13079            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13080            printedAnything |= needSep;
13081        }
13082
13083        needSep = true;
13084
13085        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13086            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13087                if (needSep) {
13088                    pw.println();
13089                }
13090                needSep = true;
13091                printedAnything = true;
13092                pw.print("  Sticky broadcasts for user ");
13093                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13094                StringBuilder sb = new StringBuilder(128);
13095                for (Map.Entry<String, ArrayList<Intent>> ent
13096                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13097                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13098                    if (dumpAll) {
13099                        pw.println(":");
13100                        ArrayList<Intent> intents = ent.getValue();
13101                        final int N = intents.size();
13102                        for (int i=0; i<N; i++) {
13103                            sb.setLength(0);
13104                            sb.append("    Intent: ");
13105                            intents.get(i).toShortString(sb, false, true, false, false);
13106                            pw.println(sb.toString());
13107                            Bundle bundle = intents.get(i).getExtras();
13108                            if (bundle != null) {
13109                                pw.print("      ");
13110                                pw.println(bundle.toString());
13111                            }
13112                        }
13113                    } else {
13114                        pw.println("");
13115                    }
13116                }
13117            }
13118        }
13119
13120        if (!onlyHistory && dumpAll) {
13121            pw.println();
13122            for (BroadcastQueue queue : mBroadcastQueues) {
13123                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13124                        + queue.mBroadcastsScheduled);
13125            }
13126            pw.println("  mHandler:");
13127            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13128            needSep = true;
13129            printedAnything = true;
13130        }
13131
13132        if (!printedAnything) {
13133            pw.println("  (nothing)");
13134        }
13135    }
13136
13137    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13138            int opti, boolean dumpAll, String dumpPackage) {
13139        boolean needSep;
13140        boolean printedAnything = false;
13141
13142        ItemMatcher matcher = new ItemMatcher();
13143        matcher.build(args, opti);
13144
13145        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13146
13147        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13148        printedAnything |= needSep;
13149
13150        if (mLaunchingProviders.size() > 0) {
13151            boolean printed = false;
13152            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13153                ContentProviderRecord r = mLaunchingProviders.get(i);
13154                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13155                    continue;
13156                }
13157                if (!printed) {
13158                    if (needSep) pw.println();
13159                    needSep = true;
13160                    pw.println("  Launching content providers:");
13161                    printed = true;
13162                    printedAnything = true;
13163                }
13164                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13165                        pw.println(r);
13166            }
13167        }
13168
13169        if (mGrantedUriPermissions.size() > 0) {
13170            boolean printed = false;
13171            int dumpUid = -2;
13172            if (dumpPackage != null) {
13173                try {
13174                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13175                } catch (NameNotFoundException e) {
13176                    dumpUid = -1;
13177                }
13178            }
13179            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13180                int uid = mGrantedUriPermissions.keyAt(i);
13181                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13182                    continue;
13183                }
13184                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13185                if (!printed) {
13186                    if (needSep) pw.println();
13187                    needSep = true;
13188                    pw.println("  Granted Uri Permissions:");
13189                    printed = true;
13190                    printedAnything = true;
13191                }
13192                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13193                for (UriPermission perm : perms.values()) {
13194                    pw.print("    "); pw.println(perm);
13195                    if (dumpAll) {
13196                        perm.dump(pw, "      ");
13197                    }
13198                }
13199            }
13200        }
13201
13202        if (!printedAnything) {
13203            pw.println("  (nothing)");
13204        }
13205    }
13206
13207    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13208            int opti, boolean dumpAll, String dumpPackage) {
13209        boolean printed = false;
13210
13211        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13212
13213        if (mIntentSenderRecords.size() > 0) {
13214            Iterator<WeakReference<PendingIntentRecord>> it
13215                    = mIntentSenderRecords.values().iterator();
13216            while (it.hasNext()) {
13217                WeakReference<PendingIntentRecord> ref = it.next();
13218                PendingIntentRecord rec = ref != null ? ref.get(): null;
13219                if (dumpPackage != null && (rec == null
13220                        || !dumpPackage.equals(rec.key.packageName))) {
13221                    continue;
13222                }
13223                printed = true;
13224                if (rec != null) {
13225                    pw.print("  * "); pw.println(rec);
13226                    if (dumpAll) {
13227                        rec.dump(pw, "    ");
13228                    }
13229                } else {
13230                    pw.print("  * "); pw.println(ref);
13231                }
13232            }
13233        }
13234
13235        if (!printed) {
13236            pw.println("  (nothing)");
13237        }
13238    }
13239
13240    private static final int dumpProcessList(PrintWriter pw,
13241            ActivityManagerService service, List list,
13242            String prefix, String normalLabel, String persistentLabel,
13243            String dumpPackage) {
13244        int numPers = 0;
13245        final int N = list.size()-1;
13246        for (int i=N; i>=0; i--) {
13247            ProcessRecord r = (ProcessRecord)list.get(i);
13248            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13249                continue;
13250            }
13251            pw.println(String.format("%s%s #%2d: %s",
13252                    prefix, (r.persistent ? persistentLabel : normalLabel),
13253                    i, r.toString()));
13254            if (r.persistent) {
13255                numPers++;
13256            }
13257        }
13258        return numPers;
13259    }
13260
13261    private static final boolean dumpProcessOomList(PrintWriter pw,
13262            ActivityManagerService service, List<ProcessRecord> origList,
13263            String prefix, String normalLabel, String persistentLabel,
13264            boolean inclDetails, String dumpPackage) {
13265
13266        ArrayList<Pair<ProcessRecord, Integer>> list
13267                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13268        for (int i=0; i<origList.size(); i++) {
13269            ProcessRecord r = origList.get(i);
13270            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13271                continue;
13272            }
13273            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13274        }
13275
13276        if (list.size() <= 0) {
13277            return false;
13278        }
13279
13280        Comparator<Pair<ProcessRecord, Integer>> comparator
13281                = new Comparator<Pair<ProcessRecord, Integer>>() {
13282            @Override
13283            public int compare(Pair<ProcessRecord, Integer> object1,
13284                    Pair<ProcessRecord, Integer> object2) {
13285                if (object1.first.setAdj != object2.first.setAdj) {
13286                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13287                }
13288                if (object1.second.intValue() != object2.second.intValue()) {
13289                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13290                }
13291                return 0;
13292            }
13293        };
13294
13295        Collections.sort(list, comparator);
13296
13297        final long curRealtime = SystemClock.elapsedRealtime();
13298        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13299        final long curUptime = SystemClock.uptimeMillis();
13300        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13301
13302        for (int i=list.size()-1; i>=0; i--) {
13303            ProcessRecord r = list.get(i).first;
13304            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13305            char schedGroup;
13306            switch (r.setSchedGroup) {
13307                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13308                    schedGroup = 'B';
13309                    break;
13310                case Process.THREAD_GROUP_DEFAULT:
13311                    schedGroup = 'F';
13312                    break;
13313                default:
13314                    schedGroup = '?';
13315                    break;
13316            }
13317            char foreground;
13318            if (r.foregroundActivities) {
13319                foreground = 'A';
13320            } else if (r.foregroundServices) {
13321                foreground = 'S';
13322            } else {
13323                foreground = ' ';
13324            }
13325            String procState = ProcessList.makeProcStateString(r.curProcState);
13326            pw.print(prefix);
13327            pw.print(r.persistent ? persistentLabel : normalLabel);
13328            pw.print(" #");
13329            int num = (origList.size()-1)-list.get(i).second;
13330            if (num < 10) pw.print(' ');
13331            pw.print(num);
13332            pw.print(": ");
13333            pw.print(oomAdj);
13334            pw.print(' ');
13335            pw.print(schedGroup);
13336            pw.print('/');
13337            pw.print(foreground);
13338            pw.print('/');
13339            pw.print(procState);
13340            pw.print(" trm:");
13341            if (r.trimMemoryLevel < 10) pw.print(' ');
13342            pw.print(r.trimMemoryLevel);
13343            pw.print(' ');
13344            pw.print(r.toShortString());
13345            pw.print(" (");
13346            pw.print(r.adjType);
13347            pw.println(')');
13348            if (r.adjSource != null || r.adjTarget != null) {
13349                pw.print(prefix);
13350                pw.print("    ");
13351                if (r.adjTarget instanceof ComponentName) {
13352                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13353                } else if (r.adjTarget != null) {
13354                    pw.print(r.adjTarget.toString());
13355                } else {
13356                    pw.print("{null}");
13357                }
13358                pw.print("<=");
13359                if (r.adjSource instanceof ProcessRecord) {
13360                    pw.print("Proc{");
13361                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13362                    pw.println("}");
13363                } else if (r.adjSource != null) {
13364                    pw.println(r.adjSource.toString());
13365                } else {
13366                    pw.println("{null}");
13367                }
13368            }
13369            if (inclDetails) {
13370                pw.print(prefix);
13371                pw.print("    ");
13372                pw.print("oom: max="); pw.print(r.maxAdj);
13373                pw.print(" curRaw="); pw.print(r.curRawAdj);
13374                pw.print(" setRaw="); pw.print(r.setRawAdj);
13375                pw.print(" cur="); pw.print(r.curAdj);
13376                pw.print(" set="); pw.println(r.setAdj);
13377                pw.print(prefix);
13378                pw.print("    ");
13379                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13380                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13381                pw.print(" lastPss="); pw.print(r.lastPss);
13382                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13383                pw.print(prefix);
13384                pw.print("    ");
13385                pw.print("cached="); pw.print(r.cached);
13386                pw.print(" empty="); pw.print(r.empty);
13387                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13388
13389                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13390                    if (r.lastWakeTime != 0) {
13391                        long wtime;
13392                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13393                        synchronized (stats) {
13394                            wtime = stats.getProcessWakeTime(r.info.uid,
13395                                    r.pid, curRealtime);
13396                        }
13397                        long timeUsed = wtime - r.lastWakeTime;
13398                        pw.print(prefix);
13399                        pw.print("    ");
13400                        pw.print("keep awake over ");
13401                        TimeUtils.formatDuration(realtimeSince, pw);
13402                        pw.print(" used ");
13403                        TimeUtils.formatDuration(timeUsed, pw);
13404                        pw.print(" (");
13405                        pw.print((timeUsed*100)/realtimeSince);
13406                        pw.println("%)");
13407                    }
13408                    if (r.lastCpuTime != 0) {
13409                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13410                        pw.print(prefix);
13411                        pw.print("    ");
13412                        pw.print("run cpu over ");
13413                        TimeUtils.formatDuration(uptimeSince, pw);
13414                        pw.print(" used ");
13415                        TimeUtils.formatDuration(timeUsed, pw);
13416                        pw.print(" (");
13417                        pw.print((timeUsed*100)/uptimeSince);
13418                        pw.println("%)");
13419                    }
13420                }
13421            }
13422        }
13423        return true;
13424    }
13425
13426    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13427        ArrayList<ProcessRecord> procs;
13428        synchronized (this) {
13429            if (args != null && args.length > start
13430                    && args[start].charAt(0) != '-') {
13431                procs = new ArrayList<ProcessRecord>();
13432                int pid = -1;
13433                try {
13434                    pid = Integer.parseInt(args[start]);
13435                } catch (NumberFormatException e) {
13436                }
13437                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13438                    ProcessRecord proc = mLruProcesses.get(i);
13439                    if (proc.pid == pid) {
13440                        procs.add(proc);
13441                    } else if (proc.processName.equals(args[start])) {
13442                        procs.add(proc);
13443                    }
13444                }
13445                if (procs.size() <= 0) {
13446                    return null;
13447                }
13448            } else {
13449                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13450            }
13451        }
13452        return procs;
13453    }
13454
13455    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13456            PrintWriter pw, String[] args) {
13457        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13458        if (procs == null) {
13459            pw.println("No process found for: " + args[0]);
13460            return;
13461        }
13462
13463        long uptime = SystemClock.uptimeMillis();
13464        long realtime = SystemClock.elapsedRealtime();
13465        pw.println("Applications Graphics Acceleration Info:");
13466        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13467
13468        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13469            ProcessRecord r = procs.get(i);
13470            if (r.thread != null) {
13471                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13472                pw.flush();
13473                try {
13474                    TransferPipe tp = new TransferPipe();
13475                    try {
13476                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13477                        tp.go(fd);
13478                    } finally {
13479                        tp.kill();
13480                    }
13481                } catch (IOException e) {
13482                    pw.println("Failure while dumping the app: " + r);
13483                    pw.flush();
13484                } catch (RemoteException e) {
13485                    pw.println("Got a RemoteException while dumping the app " + r);
13486                    pw.flush();
13487                }
13488            }
13489        }
13490    }
13491
13492    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13493        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13494        if (procs == null) {
13495            pw.println("No process found for: " + args[0]);
13496            return;
13497        }
13498
13499        pw.println("Applications Database Info:");
13500
13501        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13502            ProcessRecord r = procs.get(i);
13503            if (r.thread != null) {
13504                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13505                pw.flush();
13506                try {
13507                    TransferPipe tp = new TransferPipe();
13508                    try {
13509                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13510                        tp.go(fd);
13511                    } finally {
13512                        tp.kill();
13513                    }
13514                } catch (IOException e) {
13515                    pw.println("Failure while dumping the app: " + r);
13516                    pw.flush();
13517                } catch (RemoteException e) {
13518                    pw.println("Got a RemoteException while dumping the app " + r);
13519                    pw.flush();
13520                }
13521            }
13522        }
13523    }
13524
13525    final static class MemItem {
13526        final boolean isProc;
13527        final String label;
13528        final String shortLabel;
13529        final long pss;
13530        final int id;
13531        final boolean hasActivities;
13532        ArrayList<MemItem> subitems;
13533
13534        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13535                boolean _hasActivities) {
13536            isProc = true;
13537            label = _label;
13538            shortLabel = _shortLabel;
13539            pss = _pss;
13540            id = _id;
13541            hasActivities = _hasActivities;
13542        }
13543
13544        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13545            isProc = false;
13546            label = _label;
13547            shortLabel = _shortLabel;
13548            pss = _pss;
13549            id = _id;
13550            hasActivities = false;
13551        }
13552    }
13553
13554    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13555            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13556        if (sort && !isCompact) {
13557            Collections.sort(items, new Comparator<MemItem>() {
13558                @Override
13559                public int compare(MemItem lhs, MemItem rhs) {
13560                    if (lhs.pss < rhs.pss) {
13561                        return 1;
13562                    } else if (lhs.pss > rhs.pss) {
13563                        return -1;
13564                    }
13565                    return 0;
13566                }
13567            });
13568        }
13569
13570        for (int i=0; i<items.size(); i++) {
13571            MemItem mi = items.get(i);
13572            if (!isCompact) {
13573                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13574            } else if (mi.isProc) {
13575                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13576                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13577                pw.println(mi.hasActivities ? ",a" : ",e");
13578            } else {
13579                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13580                pw.println(mi.pss);
13581            }
13582            if (mi.subitems != null) {
13583                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13584                        true, isCompact);
13585            }
13586        }
13587    }
13588
13589    // These are in KB.
13590    static final long[] DUMP_MEM_BUCKETS = new long[] {
13591        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13592        120*1024, 160*1024, 200*1024,
13593        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13594        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13595    };
13596
13597    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13598            boolean stackLike) {
13599        int start = label.lastIndexOf('.');
13600        if (start >= 0) start++;
13601        else start = 0;
13602        int end = label.length();
13603        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13604            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13605                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13606                out.append(bucket);
13607                out.append(stackLike ? "MB." : "MB ");
13608                out.append(label, start, end);
13609                return;
13610            }
13611        }
13612        out.append(memKB/1024);
13613        out.append(stackLike ? "MB." : "MB ");
13614        out.append(label, start, end);
13615    }
13616
13617    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13618            ProcessList.NATIVE_ADJ,
13619            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13620            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13621            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13622            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13623            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13624    };
13625    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13626            "Native",
13627            "System", "Persistent", "Foreground",
13628            "Visible", "Perceptible",
13629            "Heavy Weight", "Backup",
13630            "A Services", "Home",
13631            "Previous", "B Services", "Cached"
13632    };
13633    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13634            "native",
13635            "sys", "pers", "fore",
13636            "vis", "percept",
13637            "heavy", "backup",
13638            "servicea", "home",
13639            "prev", "serviceb", "cached"
13640    };
13641
13642    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13643            long realtime, boolean isCheckinRequest, boolean isCompact) {
13644        if (isCheckinRequest || isCompact) {
13645            // short checkin version
13646            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13647        } else {
13648            pw.println("Applications Memory Usage (kB):");
13649            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13650        }
13651    }
13652
13653    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13654            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13655        boolean dumpDetails = false;
13656        boolean dumpFullDetails = false;
13657        boolean dumpDalvik = false;
13658        boolean oomOnly = false;
13659        boolean isCompact = false;
13660        boolean localOnly = false;
13661
13662        int opti = 0;
13663        while (opti < args.length) {
13664            String opt = args[opti];
13665            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13666                break;
13667            }
13668            opti++;
13669            if ("-a".equals(opt)) {
13670                dumpDetails = true;
13671                dumpFullDetails = true;
13672                dumpDalvik = true;
13673            } else if ("-d".equals(opt)) {
13674                dumpDalvik = true;
13675            } else if ("-c".equals(opt)) {
13676                isCompact = true;
13677            } else if ("--oom".equals(opt)) {
13678                oomOnly = true;
13679            } else if ("--local".equals(opt)) {
13680                localOnly = true;
13681            } else if ("-h".equals(opt)) {
13682                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13683                pw.println("  -a: include all available information for each process.");
13684                pw.println("  -d: include dalvik details when dumping process details.");
13685                pw.println("  -c: dump in a compact machine-parseable representation.");
13686                pw.println("  --oom: only show processes organized by oom adj.");
13687                pw.println("  --local: only collect details locally, don't call process.");
13688                pw.println("If [process] is specified it can be the name or ");
13689                pw.println("pid of a specific process to dump.");
13690                return;
13691            } else {
13692                pw.println("Unknown argument: " + opt + "; use -h for help");
13693            }
13694        }
13695
13696        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13697        long uptime = SystemClock.uptimeMillis();
13698        long realtime = SystemClock.elapsedRealtime();
13699        final long[] tmpLong = new long[1];
13700
13701        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13702        if (procs == null) {
13703            // No Java processes.  Maybe they want to print a native process.
13704            if (args != null && args.length > opti
13705                    && args[opti].charAt(0) != '-') {
13706                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13707                        = new ArrayList<ProcessCpuTracker.Stats>();
13708                updateCpuStatsNow();
13709                int findPid = -1;
13710                try {
13711                    findPid = Integer.parseInt(args[opti]);
13712                } catch (NumberFormatException e) {
13713                }
13714                synchronized (mProcessCpuThread) {
13715                    final int N = mProcessCpuTracker.countStats();
13716                    for (int i=0; i<N; i++) {
13717                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13718                        if (st.pid == findPid || (st.baseName != null
13719                                && st.baseName.equals(args[opti]))) {
13720                            nativeProcs.add(st);
13721                        }
13722                    }
13723                }
13724                if (nativeProcs.size() > 0) {
13725                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13726                            isCompact);
13727                    Debug.MemoryInfo mi = null;
13728                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13729                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13730                        final int pid = r.pid;
13731                        if (!isCheckinRequest && dumpDetails) {
13732                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13733                        }
13734                        if (mi == null) {
13735                            mi = new Debug.MemoryInfo();
13736                        }
13737                        if (dumpDetails || (!brief && !oomOnly)) {
13738                            Debug.getMemoryInfo(pid, mi);
13739                        } else {
13740                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13741                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13742                        }
13743                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13744                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13745                        if (isCheckinRequest) {
13746                            pw.println();
13747                        }
13748                    }
13749                    return;
13750                }
13751            }
13752            pw.println("No process found for: " + args[opti]);
13753            return;
13754        }
13755
13756        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13757            dumpDetails = true;
13758        }
13759
13760        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13761
13762        String[] innerArgs = new String[args.length-opti];
13763        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13764
13765        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13766        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13767        long nativePss=0, dalvikPss=0, otherPss=0;
13768        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13769
13770        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13771        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13772                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13773
13774        long totalPss = 0;
13775        long cachedPss = 0;
13776
13777        Debug.MemoryInfo mi = null;
13778        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13779            final ProcessRecord r = procs.get(i);
13780            final IApplicationThread thread;
13781            final int pid;
13782            final int oomAdj;
13783            final boolean hasActivities;
13784            synchronized (this) {
13785                thread = r.thread;
13786                pid = r.pid;
13787                oomAdj = r.getSetAdjWithServices();
13788                hasActivities = r.activities.size() > 0;
13789            }
13790            if (thread != null) {
13791                if (!isCheckinRequest && dumpDetails) {
13792                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13793                }
13794                if (mi == null) {
13795                    mi = new Debug.MemoryInfo();
13796                }
13797                if (dumpDetails || (!brief && !oomOnly)) {
13798                    Debug.getMemoryInfo(pid, mi);
13799                } else {
13800                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13801                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13802                }
13803                if (dumpDetails) {
13804                    if (localOnly) {
13805                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13806                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13807                        if (isCheckinRequest) {
13808                            pw.println();
13809                        }
13810                    } else {
13811                        try {
13812                            pw.flush();
13813                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13814                                    dumpDalvik, innerArgs);
13815                        } catch (RemoteException e) {
13816                            if (!isCheckinRequest) {
13817                                pw.println("Got RemoteException!");
13818                                pw.flush();
13819                            }
13820                        }
13821                    }
13822                }
13823
13824                final long myTotalPss = mi.getTotalPss();
13825                final long myTotalUss = mi.getTotalUss();
13826
13827                synchronized (this) {
13828                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13829                        // Record this for posterity if the process has been stable.
13830                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13831                    }
13832                }
13833
13834                if (!isCheckinRequest && mi != null) {
13835                    totalPss += myTotalPss;
13836                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13837                            (hasActivities ? " / activities)" : ")"),
13838                            r.processName, myTotalPss, pid, hasActivities);
13839                    procMems.add(pssItem);
13840                    procMemsMap.put(pid, pssItem);
13841
13842                    nativePss += mi.nativePss;
13843                    dalvikPss += mi.dalvikPss;
13844                    otherPss += mi.otherPss;
13845                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13846                        long mem = mi.getOtherPss(j);
13847                        miscPss[j] += mem;
13848                        otherPss -= mem;
13849                    }
13850
13851                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13852                        cachedPss += myTotalPss;
13853                    }
13854
13855                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13856                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13857                                || oomIndex == (oomPss.length-1)) {
13858                            oomPss[oomIndex] += myTotalPss;
13859                            if (oomProcs[oomIndex] == null) {
13860                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13861                            }
13862                            oomProcs[oomIndex].add(pssItem);
13863                            break;
13864                        }
13865                    }
13866                }
13867            }
13868        }
13869
13870        long nativeProcTotalPss = 0;
13871
13872        if (!isCheckinRequest && procs.size() > 1) {
13873            // If we are showing aggregations, also look for native processes to
13874            // include so that our aggregations are more accurate.
13875            updateCpuStatsNow();
13876            synchronized (mProcessCpuThread) {
13877                final int N = mProcessCpuTracker.countStats();
13878                for (int i=0; i<N; i++) {
13879                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13880                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13881                        if (mi == null) {
13882                            mi = new Debug.MemoryInfo();
13883                        }
13884                        if (!brief && !oomOnly) {
13885                            Debug.getMemoryInfo(st.pid, mi);
13886                        } else {
13887                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13888                            mi.nativePrivateDirty = (int)tmpLong[0];
13889                        }
13890
13891                        final long myTotalPss = mi.getTotalPss();
13892                        totalPss += myTotalPss;
13893                        nativeProcTotalPss += myTotalPss;
13894
13895                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13896                                st.name, myTotalPss, st.pid, false);
13897                        procMems.add(pssItem);
13898
13899                        nativePss += mi.nativePss;
13900                        dalvikPss += mi.dalvikPss;
13901                        otherPss += mi.otherPss;
13902                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13903                            long mem = mi.getOtherPss(j);
13904                            miscPss[j] += mem;
13905                            otherPss -= mem;
13906                        }
13907                        oomPss[0] += myTotalPss;
13908                        if (oomProcs[0] == null) {
13909                            oomProcs[0] = new ArrayList<MemItem>();
13910                        }
13911                        oomProcs[0].add(pssItem);
13912                    }
13913                }
13914            }
13915
13916            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13917
13918            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13919            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13920            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13921            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13922                String label = Debug.MemoryInfo.getOtherLabel(j);
13923                catMems.add(new MemItem(label, label, miscPss[j], j));
13924            }
13925
13926            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13927            for (int j=0; j<oomPss.length; j++) {
13928                if (oomPss[j] != 0) {
13929                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13930                            : DUMP_MEM_OOM_LABEL[j];
13931                    MemItem item = new MemItem(label, label, oomPss[j],
13932                            DUMP_MEM_OOM_ADJ[j]);
13933                    item.subitems = oomProcs[j];
13934                    oomMems.add(item);
13935                }
13936            }
13937
13938            if (!brief && !oomOnly && !isCompact) {
13939                pw.println();
13940                pw.println("Total PSS by process:");
13941                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13942                pw.println();
13943            }
13944            if (!isCompact) {
13945                pw.println("Total PSS by OOM adjustment:");
13946            }
13947            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13948            if (!brief && !oomOnly) {
13949                PrintWriter out = categoryPw != null ? categoryPw : pw;
13950                if (!isCompact) {
13951                    out.println();
13952                    out.println("Total PSS by category:");
13953                }
13954                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13955            }
13956            if (!isCompact) {
13957                pw.println();
13958            }
13959            MemInfoReader memInfo = new MemInfoReader();
13960            memInfo.readMemInfo();
13961            if (nativeProcTotalPss > 0) {
13962                synchronized (this) {
13963                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13964                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13965                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13966                            nativeProcTotalPss);
13967                }
13968            }
13969            if (!brief) {
13970                if (!isCompact) {
13971                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13972                    pw.print(" kB (status ");
13973                    switch (mLastMemoryLevel) {
13974                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13975                            pw.println("normal)");
13976                            break;
13977                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13978                            pw.println("moderate)");
13979                            break;
13980                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13981                            pw.println("low)");
13982                            break;
13983                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13984                            pw.println("critical)");
13985                            break;
13986                        default:
13987                            pw.print(mLastMemoryLevel);
13988                            pw.println(")");
13989                            break;
13990                    }
13991                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13992                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13993                            pw.print(cachedPss); pw.print(" cached pss + ");
13994                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13995                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13996                } else {
13997                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13998                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13999                            + memInfo.getFreeSizeKb()); pw.print(",");
14000                    pw.println(totalPss - cachedPss);
14001                }
14002            }
14003            if (!isCompact) {
14004                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14005                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14006                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14007                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14008                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14009                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14010                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14011                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14012                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14013                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14014                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14015            }
14016            if (!brief) {
14017                if (memInfo.getZramTotalSizeKb() != 0) {
14018                    if (!isCompact) {
14019                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14020                                pw.print(" kB physical used for ");
14021                                pw.print(memInfo.getSwapTotalSizeKb()
14022                                        - memInfo.getSwapFreeSizeKb());
14023                                pw.print(" kB in swap (");
14024                                pw.print(memInfo.getSwapTotalSizeKb());
14025                                pw.println(" kB total swap)");
14026                    } else {
14027                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14028                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14029                                pw.println(memInfo.getSwapFreeSizeKb());
14030                    }
14031                }
14032                final int[] SINGLE_LONG_FORMAT = new int[] {
14033                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14034                };
14035                long[] longOut = new long[1];
14036                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14037                        SINGLE_LONG_FORMAT, null, longOut, null);
14038                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14039                longOut[0] = 0;
14040                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14041                        SINGLE_LONG_FORMAT, null, longOut, null);
14042                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14043                longOut[0] = 0;
14044                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14045                        SINGLE_LONG_FORMAT, null, longOut, null);
14046                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14047                longOut[0] = 0;
14048                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14049                        SINGLE_LONG_FORMAT, null, longOut, null);
14050                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14051                if (!isCompact) {
14052                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14053                        pw.print("      KSM: "); pw.print(sharing);
14054                                pw.print(" kB saved from shared ");
14055                                pw.print(shared); pw.println(" kB");
14056                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14057                                pw.print(voltile); pw.println(" kB volatile");
14058                    }
14059                    pw.print("   Tuning: ");
14060                    pw.print(ActivityManager.staticGetMemoryClass());
14061                    pw.print(" (large ");
14062                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14063                    pw.print("), oom ");
14064                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14065                    pw.print(" kB");
14066                    pw.print(", restore limit ");
14067                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14068                    pw.print(" kB");
14069                    if (ActivityManager.isLowRamDeviceStatic()) {
14070                        pw.print(" (low-ram)");
14071                    }
14072                    if (ActivityManager.isHighEndGfx()) {
14073                        pw.print(" (high-end-gfx)");
14074                    }
14075                    pw.println();
14076                } else {
14077                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14078                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14079                    pw.println(voltile);
14080                    pw.print("tuning,");
14081                    pw.print(ActivityManager.staticGetMemoryClass());
14082                    pw.print(',');
14083                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14084                    pw.print(',');
14085                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14086                    if (ActivityManager.isLowRamDeviceStatic()) {
14087                        pw.print(",low-ram");
14088                    }
14089                    if (ActivityManager.isHighEndGfx()) {
14090                        pw.print(",high-end-gfx");
14091                    }
14092                    pw.println();
14093                }
14094            }
14095        }
14096    }
14097
14098    /**
14099     * Searches array of arguments for the specified string
14100     * @param args array of argument strings
14101     * @param value value to search for
14102     * @return true if the value is contained in the array
14103     */
14104    private static boolean scanArgs(String[] args, String value) {
14105        if (args != null) {
14106            for (String arg : args) {
14107                if (value.equals(arg)) {
14108                    return true;
14109                }
14110            }
14111        }
14112        return false;
14113    }
14114
14115    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14116            ContentProviderRecord cpr, boolean always) {
14117        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14118
14119        if (!inLaunching || always) {
14120            synchronized (cpr) {
14121                cpr.launchingApp = null;
14122                cpr.notifyAll();
14123            }
14124            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14125            String names[] = cpr.info.authority.split(";");
14126            for (int j = 0; j < names.length; j++) {
14127                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14128            }
14129        }
14130
14131        for (int i=0; i<cpr.connections.size(); i++) {
14132            ContentProviderConnection conn = cpr.connections.get(i);
14133            if (conn.waiting) {
14134                // If this connection is waiting for the provider, then we don't
14135                // need to mess with its process unless we are always removing
14136                // or for some reason the provider is not currently launching.
14137                if (inLaunching && !always) {
14138                    continue;
14139                }
14140            }
14141            ProcessRecord capp = conn.client;
14142            conn.dead = true;
14143            if (conn.stableCount > 0) {
14144                if (!capp.persistent && capp.thread != null
14145                        && capp.pid != 0
14146                        && capp.pid != MY_PID) {
14147                    capp.kill("depends on provider "
14148                            + cpr.name.flattenToShortString()
14149                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14150                }
14151            } else if (capp.thread != null && conn.provider.provider != null) {
14152                try {
14153                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14154                } catch (RemoteException e) {
14155                }
14156                // In the protocol here, we don't expect the client to correctly
14157                // clean up this connection, we'll just remove it.
14158                cpr.connections.remove(i);
14159                conn.client.conProviders.remove(conn);
14160            }
14161        }
14162
14163        if (inLaunching && always) {
14164            mLaunchingProviders.remove(cpr);
14165        }
14166        return inLaunching;
14167    }
14168
14169    /**
14170     * Main code for cleaning up a process when it has gone away.  This is
14171     * called both as a result of the process dying, or directly when stopping
14172     * a process when running in single process mode.
14173     */
14174    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14175            boolean restarting, boolean allowRestart, int index) {
14176        if (index >= 0) {
14177            removeLruProcessLocked(app);
14178            ProcessList.remove(app.pid);
14179        }
14180
14181        mProcessesToGc.remove(app);
14182        mPendingPssProcesses.remove(app);
14183
14184        // Dismiss any open dialogs.
14185        if (app.crashDialog != null && !app.forceCrashReport) {
14186            app.crashDialog.dismiss();
14187            app.crashDialog = null;
14188        }
14189        if (app.anrDialog != null) {
14190            app.anrDialog.dismiss();
14191            app.anrDialog = null;
14192        }
14193        if (app.waitDialog != null) {
14194            app.waitDialog.dismiss();
14195            app.waitDialog = null;
14196        }
14197
14198        app.crashing = false;
14199        app.notResponding = false;
14200
14201        app.resetPackageList(mProcessStats);
14202        app.unlinkDeathRecipient();
14203        app.makeInactive(mProcessStats);
14204        app.waitingToKill = null;
14205        app.forcingToForeground = null;
14206        updateProcessForegroundLocked(app, false, false);
14207        app.foregroundActivities = false;
14208        app.hasShownUi = false;
14209        app.treatLikeActivity = false;
14210        app.hasAboveClient = false;
14211        app.hasClientActivities = false;
14212
14213        mServices.killServicesLocked(app, allowRestart);
14214
14215        boolean restart = false;
14216
14217        // Remove published content providers.
14218        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14219            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14220            final boolean always = app.bad || !allowRestart;
14221            if (removeDyingProviderLocked(app, cpr, always) || always) {
14222                // We left the provider in the launching list, need to
14223                // restart it.
14224                restart = true;
14225            }
14226
14227            cpr.provider = null;
14228            cpr.proc = null;
14229        }
14230        app.pubProviders.clear();
14231
14232        // Take care of any launching providers waiting for this process.
14233        if (checkAppInLaunchingProvidersLocked(app, false)) {
14234            restart = true;
14235        }
14236
14237        // Unregister from connected content providers.
14238        if (!app.conProviders.isEmpty()) {
14239            for (int i=0; i<app.conProviders.size(); i++) {
14240                ContentProviderConnection conn = app.conProviders.get(i);
14241                conn.provider.connections.remove(conn);
14242            }
14243            app.conProviders.clear();
14244        }
14245
14246        // At this point there may be remaining entries in mLaunchingProviders
14247        // where we were the only one waiting, so they are no longer of use.
14248        // Look for these and clean up if found.
14249        // XXX Commented out for now.  Trying to figure out a way to reproduce
14250        // the actual situation to identify what is actually going on.
14251        if (false) {
14252            for (int i=0; i<mLaunchingProviders.size(); i++) {
14253                ContentProviderRecord cpr = (ContentProviderRecord)
14254                        mLaunchingProviders.get(i);
14255                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14256                    synchronized (cpr) {
14257                        cpr.launchingApp = null;
14258                        cpr.notifyAll();
14259                    }
14260                }
14261            }
14262        }
14263
14264        skipCurrentReceiverLocked(app);
14265
14266        // Unregister any receivers.
14267        for (int i=app.receivers.size()-1; i>=0; i--) {
14268            removeReceiverLocked(app.receivers.valueAt(i));
14269        }
14270        app.receivers.clear();
14271
14272        // If the app is undergoing backup, tell the backup manager about it
14273        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14274            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14275                    + mBackupTarget.appInfo + " died during backup");
14276            try {
14277                IBackupManager bm = IBackupManager.Stub.asInterface(
14278                        ServiceManager.getService(Context.BACKUP_SERVICE));
14279                bm.agentDisconnected(app.info.packageName);
14280            } catch (RemoteException e) {
14281                // can't happen; backup manager is local
14282            }
14283        }
14284
14285        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14286            ProcessChangeItem item = mPendingProcessChanges.get(i);
14287            if (item.pid == app.pid) {
14288                mPendingProcessChanges.remove(i);
14289                mAvailProcessChanges.add(item);
14290            }
14291        }
14292        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14293
14294        // If the caller is restarting this app, then leave it in its
14295        // current lists and let the caller take care of it.
14296        if (restarting) {
14297            return;
14298        }
14299
14300        if (!app.persistent || app.isolated) {
14301            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14302                    "Removing non-persistent process during cleanup: " + app);
14303            mProcessNames.remove(app.processName, app.uid);
14304            mIsolatedProcesses.remove(app.uid);
14305            if (mHeavyWeightProcess == app) {
14306                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14307                        mHeavyWeightProcess.userId, 0));
14308                mHeavyWeightProcess = null;
14309            }
14310        } else if (!app.removed) {
14311            // This app is persistent, so we need to keep its record around.
14312            // If it is not already on the pending app list, add it there
14313            // and start a new process for it.
14314            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14315                mPersistentStartingProcesses.add(app);
14316                restart = true;
14317            }
14318        }
14319        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14320                "Clean-up removing on hold: " + app);
14321        mProcessesOnHold.remove(app);
14322
14323        if (app == mHomeProcess) {
14324            mHomeProcess = null;
14325        }
14326        if (app == mPreviousProcess) {
14327            mPreviousProcess = null;
14328        }
14329
14330        if (restart && !app.isolated) {
14331            // We have components that still need to be running in the
14332            // process, so re-launch it.
14333            mProcessNames.put(app.processName, app.uid, app);
14334            startProcessLocked(app, "restart", app.processName);
14335        } else if (app.pid > 0 && app.pid != MY_PID) {
14336            // Goodbye!
14337            boolean removed;
14338            synchronized (mPidsSelfLocked) {
14339                mPidsSelfLocked.remove(app.pid);
14340                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14341            }
14342            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14343            if (app.isolated) {
14344                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14345            }
14346            app.setPid(0);
14347        }
14348    }
14349
14350    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14351        // Look through the content providers we are waiting to have launched,
14352        // and if any run in this process then either schedule a restart of
14353        // the process or kill the client waiting for it if this process has
14354        // gone bad.
14355        int NL = mLaunchingProviders.size();
14356        boolean restart = false;
14357        for (int i=0; i<NL; i++) {
14358            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14359            if (cpr.launchingApp == app) {
14360                if (!alwaysBad && !app.bad) {
14361                    restart = true;
14362                } else {
14363                    removeDyingProviderLocked(app, cpr, true);
14364                    // cpr should have been removed from mLaunchingProviders
14365                    NL = mLaunchingProviders.size();
14366                    i--;
14367                }
14368            }
14369        }
14370        return restart;
14371    }
14372
14373    // =========================================================
14374    // SERVICES
14375    // =========================================================
14376
14377    @Override
14378    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14379            int flags) {
14380        enforceNotIsolatedCaller("getServices");
14381        synchronized (this) {
14382            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14383        }
14384    }
14385
14386    @Override
14387    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14388        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14389        synchronized (this) {
14390            return mServices.getRunningServiceControlPanelLocked(name);
14391        }
14392    }
14393
14394    @Override
14395    public ComponentName startService(IApplicationThread caller, Intent service,
14396            String resolvedType, int userId) {
14397        enforceNotIsolatedCaller("startService");
14398        // Refuse possible leaked file descriptors
14399        if (service != null && service.hasFileDescriptors() == true) {
14400            throw new IllegalArgumentException("File descriptors passed in Intent");
14401        }
14402
14403        if (DEBUG_SERVICE)
14404            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14405        synchronized(this) {
14406            final int callingPid = Binder.getCallingPid();
14407            final int callingUid = Binder.getCallingUid();
14408            final long origId = Binder.clearCallingIdentity();
14409            ComponentName res = mServices.startServiceLocked(caller, service,
14410                    resolvedType, callingPid, callingUid, userId);
14411            Binder.restoreCallingIdentity(origId);
14412            return res;
14413        }
14414    }
14415
14416    ComponentName startServiceInPackage(int uid,
14417            Intent service, String resolvedType, int userId) {
14418        synchronized(this) {
14419            if (DEBUG_SERVICE)
14420                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14421            final long origId = Binder.clearCallingIdentity();
14422            ComponentName res = mServices.startServiceLocked(null, service,
14423                    resolvedType, -1, uid, userId);
14424            Binder.restoreCallingIdentity(origId);
14425            return res;
14426        }
14427    }
14428
14429    @Override
14430    public int stopService(IApplicationThread caller, Intent service,
14431            String resolvedType, int userId) {
14432        enforceNotIsolatedCaller("stopService");
14433        // Refuse possible leaked file descriptors
14434        if (service != null && service.hasFileDescriptors() == true) {
14435            throw new IllegalArgumentException("File descriptors passed in Intent");
14436        }
14437
14438        synchronized(this) {
14439            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14440        }
14441    }
14442
14443    @Override
14444    public IBinder peekService(Intent service, String resolvedType) {
14445        enforceNotIsolatedCaller("peekService");
14446        // Refuse possible leaked file descriptors
14447        if (service != null && service.hasFileDescriptors() == true) {
14448            throw new IllegalArgumentException("File descriptors passed in Intent");
14449        }
14450        synchronized(this) {
14451            return mServices.peekServiceLocked(service, resolvedType);
14452        }
14453    }
14454
14455    @Override
14456    public boolean stopServiceToken(ComponentName className, IBinder token,
14457            int startId) {
14458        synchronized(this) {
14459            return mServices.stopServiceTokenLocked(className, token, startId);
14460        }
14461    }
14462
14463    @Override
14464    public void setServiceForeground(ComponentName className, IBinder token,
14465            int id, Notification notification, boolean removeNotification) {
14466        synchronized(this) {
14467            mServices.setServiceForegroundLocked(className, token, id, notification,
14468                    removeNotification);
14469        }
14470    }
14471
14472    @Override
14473    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14474            boolean requireFull, String name, String callerPackage) {
14475        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14476                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14477    }
14478
14479    int unsafeConvertIncomingUser(int userId) {
14480        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14481                ? mCurrentUserId : userId;
14482    }
14483
14484    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14485            int allowMode, String name, String callerPackage) {
14486        final int callingUserId = UserHandle.getUserId(callingUid);
14487        if (callingUserId == userId) {
14488            return userId;
14489        }
14490
14491        // Note that we may be accessing mCurrentUserId outside of a lock...
14492        // shouldn't be a big deal, if this is being called outside
14493        // of a locked context there is intrinsically a race with
14494        // the value the caller will receive and someone else changing it.
14495        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14496        // we will switch to the calling user if access to the current user fails.
14497        int targetUserId = unsafeConvertIncomingUser(userId);
14498
14499        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14500            final boolean allow;
14501            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14502                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14503                // If the caller has this permission, they always pass go.  And collect $200.
14504                allow = true;
14505            } else if (allowMode == ALLOW_FULL_ONLY) {
14506                // We require full access, sucks to be you.
14507                allow = false;
14508            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14509                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14510                // If the caller does not have either permission, they are always doomed.
14511                allow = false;
14512            } else if (allowMode == ALLOW_NON_FULL) {
14513                // We are blanket allowing non-full access, you lucky caller!
14514                allow = true;
14515            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14516                // We may or may not allow this depending on whether the two users are
14517                // in the same profile.
14518                synchronized (mUserProfileGroupIdsSelfLocked) {
14519                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14520                            UserInfo.NO_PROFILE_GROUP_ID);
14521                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14522                            UserInfo.NO_PROFILE_GROUP_ID);
14523                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14524                            && callingProfile == targetProfile;
14525                }
14526            } else {
14527                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14528            }
14529            if (!allow) {
14530                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14531                    // In this case, they would like to just execute as their
14532                    // owner user instead of failing.
14533                    targetUserId = callingUserId;
14534                } else {
14535                    StringBuilder builder = new StringBuilder(128);
14536                    builder.append("Permission Denial: ");
14537                    builder.append(name);
14538                    if (callerPackage != null) {
14539                        builder.append(" from ");
14540                        builder.append(callerPackage);
14541                    }
14542                    builder.append(" asks to run as user ");
14543                    builder.append(userId);
14544                    builder.append(" but is calling from user ");
14545                    builder.append(UserHandle.getUserId(callingUid));
14546                    builder.append("; this requires ");
14547                    builder.append(INTERACT_ACROSS_USERS_FULL);
14548                    if (allowMode != ALLOW_FULL_ONLY) {
14549                        builder.append(" or ");
14550                        builder.append(INTERACT_ACROSS_USERS);
14551                    }
14552                    String msg = builder.toString();
14553                    Slog.w(TAG, msg);
14554                    throw new SecurityException(msg);
14555                }
14556            }
14557        }
14558        if (!allowAll && targetUserId < 0) {
14559            throw new IllegalArgumentException(
14560                    "Call does not support special user #" + targetUserId);
14561        }
14562        // Check shell permission
14563        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14564            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14565                    targetUserId)) {
14566                throw new SecurityException("Shell does not have permission to access user "
14567                        + targetUserId + "\n " + Debug.getCallers(3));
14568            }
14569        }
14570        return targetUserId;
14571    }
14572
14573    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14574            String className, int flags) {
14575        boolean result = false;
14576        // For apps that don't have pre-defined UIDs, check for permission
14577        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14578            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14579                if (ActivityManager.checkUidPermission(
14580                        INTERACT_ACROSS_USERS,
14581                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14582                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14583                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14584                            + " requests FLAG_SINGLE_USER, but app does not hold "
14585                            + INTERACT_ACROSS_USERS;
14586                    Slog.w(TAG, msg);
14587                    throw new SecurityException(msg);
14588                }
14589                // Permission passed
14590                result = true;
14591            }
14592        } else if ("system".equals(componentProcessName)) {
14593            result = true;
14594        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14595                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14596            // Phone app is allowed to export singleuser providers.
14597            result = true;
14598        } else {
14599            // App with pre-defined UID, check if it's a persistent app
14600            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14601        }
14602        if (DEBUG_MU) {
14603            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14604                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14605        }
14606        return result;
14607    }
14608
14609    /**
14610     * Checks to see if the caller is in the same app as the singleton
14611     * component, or the component is in a special app. It allows special apps
14612     * to export singleton components but prevents exporting singleton
14613     * components for regular apps.
14614     */
14615    boolean isValidSingletonCall(int callingUid, int componentUid) {
14616        int componentAppId = UserHandle.getAppId(componentUid);
14617        return UserHandle.isSameApp(callingUid, componentUid)
14618                || componentAppId == Process.SYSTEM_UID
14619                || componentAppId == Process.PHONE_UID
14620                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14621                        == PackageManager.PERMISSION_GRANTED;
14622    }
14623
14624    public int bindService(IApplicationThread caller, IBinder token,
14625            Intent service, String resolvedType,
14626            IServiceConnection connection, int flags, int userId) {
14627        enforceNotIsolatedCaller("bindService");
14628
14629        // Refuse possible leaked file descriptors
14630        if (service != null && service.hasFileDescriptors() == true) {
14631            throw new IllegalArgumentException("File descriptors passed in Intent");
14632        }
14633
14634        synchronized(this) {
14635            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14636                    connection, flags, userId);
14637        }
14638    }
14639
14640    public boolean unbindService(IServiceConnection connection) {
14641        synchronized (this) {
14642            return mServices.unbindServiceLocked(connection);
14643        }
14644    }
14645
14646    public void publishService(IBinder token, Intent intent, IBinder service) {
14647        // Refuse possible leaked file descriptors
14648        if (intent != null && intent.hasFileDescriptors() == true) {
14649            throw new IllegalArgumentException("File descriptors passed in Intent");
14650        }
14651
14652        synchronized(this) {
14653            if (!(token instanceof ServiceRecord)) {
14654                throw new IllegalArgumentException("Invalid service token");
14655            }
14656            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14657        }
14658    }
14659
14660    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14661        // Refuse possible leaked file descriptors
14662        if (intent != null && intent.hasFileDescriptors() == true) {
14663            throw new IllegalArgumentException("File descriptors passed in Intent");
14664        }
14665
14666        synchronized(this) {
14667            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14668        }
14669    }
14670
14671    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14672        synchronized(this) {
14673            if (!(token instanceof ServiceRecord)) {
14674                throw new IllegalArgumentException("Invalid service token");
14675            }
14676            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14677        }
14678    }
14679
14680    // =========================================================
14681    // BACKUP AND RESTORE
14682    // =========================================================
14683
14684    // Cause the target app to be launched if necessary and its backup agent
14685    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14686    // activity manager to announce its creation.
14687    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14688        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14689        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14690
14691        synchronized(this) {
14692            // !!! TODO: currently no check here that we're already bound
14693            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14694            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14695            synchronized (stats) {
14696                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14697            }
14698
14699            // Backup agent is now in use, its package can't be stopped.
14700            try {
14701                AppGlobals.getPackageManager().setPackageStoppedState(
14702                        app.packageName, false, UserHandle.getUserId(app.uid));
14703            } catch (RemoteException e) {
14704            } catch (IllegalArgumentException e) {
14705                Slog.w(TAG, "Failed trying to unstop package "
14706                        + app.packageName + ": " + e);
14707            }
14708
14709            BackupRecord r = new BackupRecord(ss, app, backupMode);
14710            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14711                    ? new ComponentName(app.packageName, app.backupAgentName)
14712                    : new ComponentName("android", "FullBackupAgent");
14713            // startProcessLocked() returns existing proc's record if it's already running
14714            ProcessRecord proc = startProcessLocked(app.processName, app,
14715                    false, 0, "backup", hostingName, false, false, false);
14716            if (proc == null) {
14717                Slog.e(TAG, "Unable to start backup agent process " + r);
14718                return false;
14719            }
14720
14721            r.app = proc;
14722            mBackupTarget = r;
14723            mBackupAppName = app.packageName;
14724
14725            // Try not to kill the process during backup
14726            updateOomAdjLocked(proc);
14727
14728            // If the process is already attached, schedule the creation of the backup agent now.
14729            // If it is not yet live, this will be done when it attaches to the framework.
14730            if (proc.thread != null) {
14731                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14732                try {
14733                    proc.thread.scheduleCreateBackupAgent(app,
14734                            compatibilityInfoForPackageLocked(app), backupMode);
14735                } catch (RemoteException e) {
14736                    // Will time out on the backup manager side
14737                }
14738            } else {
14739                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14740            }
14741            // Invariants: at this point, the target app process exists and the application
14742            // is either already running or in the process of coming up.  mBackupTarget and
14743            // mBackupAppName describe the app, so that when it binds back to the AM we
14744            // know that it's scheduled for a backup-agent operation.
14745        }
14746
14747        return true;
14748    }
14749
14750    @Override
14751    public void clearPendingBackup() {
14752        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14753        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14754
14755        synchronized (this) {
14756            mBackupTarget = null;
14757            mBackupAppName = null;
14758        }
14759    }
14760
14761    // A backup agent has just come up
14762    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14763        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14764                + " = " + agent);
14765
14766        synchronized(this) {
14767            if (!agentPackageName.equals(mBackupAppName)) {
14768                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14769                return;
14770            }
14771        }
14772
14773        long oldIdent = Binder.clearCallingIdentity();
14774        try {
14775            IBackupManager bm = IBackupManager.Stub.asInterface(
14776                    ServiceManager.getService(Context.BACKUP_SERVICE));
14777            bm.agentConnected(agentPackageName, agent);
14778        } catch (RemoteException e) {
14779            // can't happen; the backup manager service is local
14780        } catch (Exception e) {
14781            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14782            e.printStackTrace();
14783        } finally {
14784            Binder.restoreCallingIdentity(oldIdent);
14785        }
14786    }
14787
14788    // done with this agent
14789    public void unbindBackupAgent(ApplicationInfo appInfo) {
14790        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14791        if (appInfo == null) {
14792            Slog.w(TAG, "unbind backup agent for null app");
14793            return;
14794        }
14795
14796        synchronized(this) {
14797            try {
14798                if (mBackupAppName == null) {
14799                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14800                    return;
14801                }
14802
14803                if (!mBackupAppName.equals(appInfo.packageName)) {
14804                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14805                    return;
14806                }
14807
14808                // Not backing this app up any more; reset its OOM adjustment
14809                final ProcessRecord proc = mBackupTarget.app;
14810                updateOomAdjLocked(proc);
14811
14812                // If the app crashed during backup, 'thread' will be null here
14813                if (proc.thread != null) {
14814                    try {
14815                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14816                                compatibilityInfoForPackageLocked(appInfo));
14817                    } catch (Exception e) {
14818                        Slog.e(TAG, "Exception when unbinding backup agent:");
14819                        e.printStackTrace();
14820                    }
14821                }
14822            } finally {
14823                mBackupTarget = null;
14824                mBackupAppName = null;
14825            }
14826        }
14827    }
14828    // =========================================================
14829    // BROADCASTS
14830    // =========================================================
14831
14832    private final List getStickiesLocked(String action, IntentFilter filter,
14833            List cur, int userId) {
14834        final ContentResolver resolver = mContext.getContentResolver();
14835        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14836        if (stickies == null) {
14837            return cur;
14838        }
14839        final ArrayList<Intent> list = stickies.get(action);
14840        if (list == null) {
14841            return cur;
14842        }
14843        int N = list.size();
14844        for (int i=0; i<N; i++) {
14845            Intent intent = list.get(i);
14846            if (filter.match(resolver, intent, true, TAG) >= 0) {
14847                if (cur == null) {
14848                    cur = new ArrayList<Intent>();
14849                }
14850                cur.add(intent);
14851            }
14852        }
14853        return cur;
14854    }
14855
14856    boolean isPendingBroadcastProcessLocked(int pid) {
14857        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14858                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14859    }
14860
14861    void skipPendingBroadcastLocked(int pid) {
14862            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14863            for (BroadcastQueue queue : mBroadcastQueues) {
14864                queue.skipPendingBroadcastLocked(pid);
14865            }
14866    }
14867
14868    // The app just attached; send any pending broadcasts that it should receive
14869    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14870        boolean didSomething = false;
14871        for (BroadcastQueue queue : mBroadcastQueues) {
14872            didSomething |= queue.sendPendingBroadcastsLocked(app);
14873        }
14874        return didSomething;
14875    }
14876
14877    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14878            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14879        enforceNotIsolatedCaller("registerReceiver");
14880        int callingUid;
14881        int callingPid;
14882        synchronized(this) {
14883            ProcessRecord callerApp = null;
14884            if (caller != null) {
14885                callerApp = getRecordForAppLocked(caller);
14886                if (callerApp == null) {
14887                    throw new SecurityException(
14888                            "Unable to find app for caller " + caller
14889                            + " (pid=" + Binder.getCallingPid()
14890                            + ") when registering receiver " + receiver);
14891                }
14892                if (callerApp.info.uid != Process.SYSTEM_UID &&
14893                        !callerApp.pkgList.containsKey(callerPackage) &&
14894                        !"android".equals(callerPackage)) {
14895                    throw new SecurityException("Given caller package " + callerPackage
14896                            + " is not running in process " + callerApp);
14897                }
14898                callingUid = callerApp.info.uid;
14899                callingPid = callerApp.pid;
14900            } else {
14901                callerPackage = null;
14902                callingUid = Binder.getCallingUid();
14903                callingPid = Binder.getCallingPid();
14904            }
14905
14906            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14907                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14908
14909            List allSticky = null;
14910
14911            // Look for any matching sticky broadcasts...
14912            Iterator actions = filter.actionsIterator();
14913            if (actions != null) {
14914                while (actions.hasNext()) {
14915                    String action = (String)actions.next();
14916                    allSticky = getStickiesLocked(action, filter, allSticky,
14917                            UserHandle.USER_ALL);
14918                    allSticky = getStickiesLocked(action, filter, allSticky,
14919                            UserHandle.getUserId(callingUid));
14920                }
14921            } else {
14922                allSticky = getStickiesLocked(null, filter, allSticky,
14923                        UserHandle.USER_ALL);
14924                allSticky = getStickiesLocked(null, filter, allSticky,
14925                        UserHandle.getUserId(callingUid));
14926            }
14927
14928            // The first sticky in the list is returned directly back to
14929            // the client.
14930            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14931
14932            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14933                    + ": " + sticky);
14934
14935            if (receiver == null) {
14936                return sticky;
14937            }
14938
14939            ReceiverList rl
14940                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14941            if (rl == null) {
14942                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14943                        userId, receiver);
14944                if (rl.app != null) {
14945                    rl.app.receivers.add(rl);
14946                } else {
14947                    try {
14948                        receiver.asBinder().linkToDeath(rl, 0);
14949                    } catch (RemoteException e) {
14950                        return sticky;
14951                    }
14952                    rl.linkedToDeath = true;
14953                }
14954                mRegisteredReceivers.put(receiver.asBinder(), rl);
14955            } else if (rl.uid != callingUid) {
14956                throw new IllegalArgumentException(
14957                        "Receiver requested to register for uid " + callingUid
14958                        + " was previously registered for uid " + rl.uid);
14959            } else if (rl.pid != callingPid) {
14960                throw new IllegalArgumentException(
14961                        "Receiver requested to register for pid " + callingPid
14962                        + " was previously registered for pid " + rl.pid);
14963            } else if (rl.userId != userId) {
14964                throw new IllegalArgumentException(
14965                        "Receiver requested to register for user " + userId
14966                        + " was previously registered for user " + rl.userId);
14967            }
14968            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14969                    permission, callingUid, userId);
14970            rl.add(bf);
14971            if (!bf.debugCheck()) {
14972                Slog.w(TAG, "==> For Dynamic broadast");
14973            }
14974            mReceiverResolver.addFilter(bf);
14975
14976            // Enqueue broadcasts for all existing stickies that match
14977            // this filter.
14978            if (allSticky != null) {
14979                ArrayList receivers = new ArrayList();
14980                receivers.add(bf);
14981
14982                int N = allSticky.size();
14983                for (int i=0; i<N; i++) {
14984                    Intent intent = (Intent)allSticky.get(i);
14985                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14986                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14987                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14988                            null, null, false, true, true, -1);
14989                    queue.enqueueParallelBroadcastLocked(r);
14990                    queue.scheduleBroadcastsLocked();
14991                }
14992            }
14993
14994            return sticky;
14995        }
14996    }
14997
14998    public void unregisterReceiver(IIntentReceiver receiver) {
14999        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15000
15001        final long origId = Binder.clearCallingIdentity();
15002        try {
15003            boolean doTrim = false;
15004
15005            synchronized(this) {
15006                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15007                if (rl != null) {
15008                    if (rl.curBroadcast != null) {
15009                        BroadcastRecord r = rl.curBroadcast;
15010                        final boolean doNext = finishReceiverLocked(
15011                                receiver.asBinder(), r.resultCode, r.resultData,
15012                                r.resultExtras, r.resultAbort);
15013                        if (doNext) {
15014                            doTrim = true;
15015                            r.queue.processNextBroadcast(false);
15016                        }
15017                    }
15018
15019                    if (rl.app != null) {
15020                        rl.app.receivers.remove(rl);
15021                    }
15022                    removeReceiverLocked(rl);
15023                    if (rl.linkedToDeath) {
15024                        rl.linkedToDeath = false;
15025                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15026                    }
15027                }
15028            }
15029
15030            // If we actually concluded any broadcasts, we might now be able
15031            // to trim the recipients' apps from our working set
15032            if (doTrim) {
15033                trimApplications();
15034                return;
15035            }
15036
15037        } finally {
15038            Binder.restoreCallingIdentity(origId);
15039        }
15040    }
15041
15042    void removeReceiverLocked(ReceiverList rl) {
15043        mRegisteredReceivers.remove(rl.receiver.asBinder());
15044        int N = rl.size();
15045        for (int i=0; i<N; i++) {
15046            mReceiverResolver.removeFilter(rl.get(i));
15047        }
15048    }
15049
15050    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15051        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15052            ProcessRecord r = mLruProcesses.get(i);
15053            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15054                try {
15055                    r.thread.dispatchPackageBroadcast(cmd, packages);
15056                } catch (RemoteException ex) {
15057                }
15058            }
15059        }
15060    }
15061
15062    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15063            int callingUid, int[] users) {
15064        List<ResolveInfo> receivers = null;
15065        try {
15066            HashSet<ComponentName> singleUserReceivers = null;
15067            boolean scannedFirstReceivers = false;
15068            for (int user : users) {
15069                // Skip users that have Shell restrictions
15070                if (callingUid == Process.SHELL_UID
15071                        && getUserManagerLocked().hasUserRestriction(
15072                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15073                    continue;
15074                }
15075                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15076                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15077                if (user != 0 && newReceivers != null) {
15078                    // If this is not the primary user, we need to check for
15079                    // any receivers that should be filtered out.
15080                    for (int i=0; i<newReceivers.size(); i++) {
15081                        ResolveInfo ri = newReceivers.get(i);
15082                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15083                            newReceivers.remove(i);
15084                            i--;
15085                        }
15086                    }
15087                }
15088                if (newReceivers != null && newReceivers.size() == 0) {
15089                    newReceivers = null;
15090                }
15091                if (receivers == null) {
15092                    receivers = newReceivers;
15093                } else if (newReceivers != null) {
15094                    // We need to concatenate the additional receivers
15095                    // found with what we have do far.  This would be easy,
15096                    // but we also need to de-dup any receivers that are
15097                    // singleUser.
15098                    if (!scannedFirstReceivers) {
15099                        // Collect any single user receivers we had already retrieved.
15100                        scannedFirstReceivers = true;
15101                        for (int i=0; i<receivers.size(); i++) {
15102                            ResolveInfo ri = receivers.get(i);
15103                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15104                                ComponentName cn = new ComponentName(
15105                                        ri.activityInfo.packageName, ri.activityInfo.name);
15106                                if (singleUserReceivers == null) {
15107                                    singleUserReceivers = new HashSet<ComponentName>();
15108                                }
15109                                singleUserReceivers.add(cn);
15110                            }
15111                        }
15112                    }
15113                    // Add the new results to the existing results, tracking
15114                    // and de-dupping single user receivers.
15115                    for (int i=0; i<newReceivers.size(); i++) {
15116                        ResolveInfo ri = newReceivers.get(i);
15117                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15118                            ComponentName cn = new ComponentName(
15119                                    ri.activityInfo.packageName, ri.activityInfo.name);
15120                            if (singleUserReceivers == null) {
15121                                singleUserReceivers = new HashSet<ComponentName>();
15122                            }
15123                            if (!singleUserReceivers.contains(cn)) {
15124                                singleUserReceivers.add(cn);
15125                                receivers.add(ri);
15126                            }
15127                        } else {
15128                            receivers.add(ri);
15129                        }
15130                    }
15131                }
15132            }
15133        } catch (RemoteException ex) {
15134            // pm is in same process, this will never happen.
15135        }
15136        return receivers;
15137    }
15138
15139    private final int broadcastIntentLocked(ProcessRecord callerApp,
15140            String callerPackage, Intent intent, String resolvedType,
15141            IIntentReceiver resultTo, int resultCode, String resultData,
15142            Bundle map, String requiredPermission, int appOp,
15143            boolean ordered, boolean sticky, int callingPid, int callingUid,
15144            int userId) {
15145        intent = new Intent(intent);
15146
15147        // By default broadcasts do not go to stopped apps.
15148        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15149
15150        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15151            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15152            + " ordered=" + ordered + " userid=" + userId);
15153        if ((resultTo != null) && !ordered) {
15154            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15155        }
15156
15157        userId = handleIncomingUser(callingPid, callingUid, userId,
15158                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15159
15160        // Make sure that the user who is receiving this broadcast is started.
15161        // If not, we will just skip it.
15162
15163        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15164            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15165                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15166                Slog.w(TAG, "Skipping broadcast of " + intent
15167                        + ": user " + userId + " is stopped");
15168                return ActivityManager.BROADCAST_SUCCESS;
15169            }
15170        }
15171
15172        /*
15173         * Prevent non-system code (defined here to be non-persistent
15174         * processes) from sending protected broadcasts.
15175         */
15176        int callingAppId = UserHandle.getAppId(callingUid);
15177        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15178            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15179            || callingAppId == Process.NFC_UID || callingUid == 0) {
15180            // Always okay.
15181        } else if (callerApp == null || !callerApp.persistent) {
15182            try {
15183                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15184                        intent.getAction())) {
15185                    String msg = "Permission Denial: not allowed to send broadcast "
15186                            + intent.getAction() + " from pid="
15187                            + callingPid + ", uid=" + callingUid;
15188                    Slog.w(TAG, msg);
15189                    throw new SecurityException(msg);
15190                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15191                    // Special case for compatibility: we don't want apps to send this,
15192                    // but historically it has not been protected and apps may be using it
15193                    // to poke their own app widget.  So, instead of making it protected,
15194                    // just limit it to the caller.
15195                    if (callerApp == null) {
15196                        String msg = "Permission Denial: not allowed to send broadcast "
15197                                + intent.getAction() + " from unknown caller.";
15198                        Slog.w(TAG, msg);
15199                        throw new SecurityException(msg);
15200                    } else if (intent.getComponent() != null) {
15201                        // They are good enough to send to an explicit component...  verify
15202                        // it is being sent to the calling app.
15203                        if (!intent.getComponent().getPackageName().equals(
15204                                callerApp.info.packageName)) {
15205                            String msg = "Permission Denial: not allowed to send broadcast "
15206                                    + intent.getAction() + " to "
15207                                    + intent.getComponent().getPackageName() + " from "
15208                                    + callerApp.info.packageName;
15209                            Slog.w(TAG, msg);
15210                            throw new SecurityException(msg);
15211                        }
15212                    } else {
15213                        // Limit broadcast to their own package.
15214                        intent.setPackage(callerApp.info.packageName);
15215                    }
15216                }
15217            } catch (RemoteException e) {
15218                Slog.w(TAG, "Remote exception", e);
15219                return ActivityManager.BROADCAST_SUCCESS;
15220            }
15221        }
15222
15223        // Handle special intents: if this broadcast is from the package
15224        // manager about a package being removed, we need to remove all of
15225        // its activities from the history stack.
15226        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15227                intent.getAction());
15228        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15229                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15230                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15231                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15232                || uidRemoved) {
15233            if (checkComponentPermission(
15234                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15235                    callingPid, callingUid, -1, true)
15236                    == PackageManager.PERMISSION_GRANTED) {
15237                if (uidRemoved) {
15238                    final Bundle intentExtras = intent.getExtras();
15239                    final int uid = intentExtras != null
15240                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15241                    if (uid >= 0) {
15242                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15243                        synchronized (bs) {
15244                            bs.removeUidStatsLocked(uid);
15245                        }
15246                        mAppOpsService.uidRemoved(uid);
15247                    }
15248                } else {
15249                    // If resources are unavailable just force stop all
15250                    // those packages and flush the attribute cache as well.
15251                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15252                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15253                        if (list != null && (list.length > 0)) {
15254                            for (String pkg : list) {
15255                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15256                                        "storage unmount");
15257                            }
15258                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15259                            sendPackageBroadcastLocked(
15260                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15261                        }
15262                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15263                            intent.getAction())) {
15264                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15265                    } else {
15266                        Uri data = intent.getData();
15267                        String ssp;
15268                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15269                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15270                                    intent.getAction());
15271                            boolean fullUninstall = removed &&
15272                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15273                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15274                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15275                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15276                                        false, fullUninstall, userId,
15277                                        removed ? "pkg removed" : "pkg changed");
15278                            }
15279                            if (removed) {
15280                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15281                                        new String[] {ssp}, userId);
15282                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15283                                    mAppOpsService.packageRemoved(
15284                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15285
15286                                    // Remove all permissions granted from/to this package
15287                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15288                                }
15289                            }
15290                        }
15291                    }
15292                }
15293            } else {
15294                String msg = "Permission Denial: " + intent.getAction()
15295                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15296                        + ", uid=" + callingUid + ")"
15297                        + " requires "
15298                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15299                Slog.w(TAG, msg);
15300                throw new SecurityException(msg);
15301            }
15302
15303        // Special case for adding a package: by default turn on compatibility
15304        // mode.
15305        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15306            Uri data = intent.getData();
15307            String ssp;
15308            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15309                mCompatModePackages.handlePackageAddedLocked(ssp,
15310                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15311            }
15312        }
15313
15314        /*
15315         * If this is the time zone changed action, queue up a message that will reset the timezone
15316         * of all currently running processes. This message will get queued up before the broadcast
15317         * happens.
15318         */
15319        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15320            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15321        }
15322
15323        /*
15324         * If the user set the time, let all running processes know.
15325         */
15326        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15327            final int is24Hour = intent.getBooleanExtra(
15328                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15329            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15330            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15331            synchronized (stats) {
15332                stats.noteCurrentTimeChangedLocked();
15333            }
15334        }
15335
15336        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15337            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15338        }
15339
15340        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15341            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15342            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15343        }
15344
15345        // Add to the sticky list if requested.
15346        if (sticky) {
15347            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15348                    callingPid, callingUid)
15349                    != PackageManager.PERMISSION_GRANTED) {
15350                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15351                        + callingPid + ", uid=" + callingUid
15352                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15353                Slog.w(TAG, msg);
15354                throw new SecurityException(msg);
15355            }
15356            if (requiredPermission != null) {
15357                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15358                        + " and enforce permission " + requiredPermission);
15359                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15360            }
15361            if (intent.getComponent() != null) {
15362                throw new SecurityException(
15363                        "Sticky broadcasts can't target a specific component");
15364            }
15365            // We use userId directly here, since the "all" target is maintained
15366            // as a separate set of sticky broadcasts.
15367            if (userId != UserHandle.USER_ALL) {
15368                // But first, if this is not a broadcast to all users, then
15369                // make sure it doesn't conflict with an existing broadcast to
15370                // all users.
15371                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15372                        UserHandle.USER_ALL);
15373                if (stickies != null) {
15374                    ArrayList<Intent> list = stickies.get(intent.getAction());
15375                    if (list != null) {
15376                        int N = list.size();
15377                        int i;
15378                        for (i=0; i<N; i++) {
15379                            if (intent.filterEquals(list.get(i))) {
15380                                throw new IllegalArgumentException(
15381                                        "Sticky broadcast " + intent + " for user "
15382                                        + userId + " conflicts with existing global broadcast");
15383                            }
15384                        }
15385                    }
15386                }
15387            }
15388            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15389            if (stickies == null) {
15390                stickies = new ArrayMap<String, ArrayList<Intent>>();
15391                mStickyBroadcasts.put(userId, stickies);
15392            }
15393            ArrayList<Intent> list = stickies.get(intent.getAction());
15394            if (list == null) {
15395                list = new ArrayList<Intent>();
15396                stickies.put(intent.getAction(), list);
15397            }
15398            int N = list.size();
15399            int i;
15400            for (i=0; i<N; i++) {
15401                if (intent.filterEquals(list.get(i))) {
15402                    // This sticky already exists, replace it.
15403                    list.set(i, new Intent(intent));
15404                    break;
15405                }
15406            }
15407            if (i >= N) {
15408                list.add(new Intent(intent));
15409            }
15410        }
15411
15412        int[] users;
15413        if (userId == UserHandle.USER_ALL) {
15414            // Caller wants broadcast to go to all started users.
15415            users = mStartedUserArray;
15416        } else {
15417            // Caller wants broadcast to go to one specific user.
15418            users = new int[] {userId};
15419        }
15420
15421        // Figure out who all will receive this broadcast.
15422        List receivers = null;
15423        List<BroadcastFilter> registeredReceivers = null;
15424        // Need to resolve the intent to interested receivers...
15425        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15426                 == 0) {
15427            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15428        }
15429        if (intent.getComponent() == null) {
15430            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15431                // Query one target user at a time, excluding shell-restricted users
15432                UserManagerService ums = getUserManagerLocked();
15433                for (int i = 0; i < users.length; i++) {
15434                    if (ums.hasUserRestriction(
15435                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15436                        continue;
15437                    }
15438                    List<BroadcastFilter> registeredReceiversForUser =
15439                            mReceiverResolver.queryIntent(intent,
15440                                    resolvedType, false, users[i]);
15441                    if (registeredReceivers == null) {
15442                        registeredReceivers = registeredReceiversForUser;
15443                    } else if (registeredReceiversForUser != null) {
15444                        registeredReceivers.addAll(registeredReceiversForUser);
15445                    }
15446                }
15447            } else {
15448                registeredReceivers = mReceiverResolver.queryIntent(intent,
15449                        resolvedType, false, userId);
15450            }
15451        }
15452
15453        final boolean replacePending =
15454                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15455
15456        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15457                + " replacePending=" + replacePending);
15458
15459        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15460        if (!ordered && NR > 0) {
15461            // If we are not serializing this broadcast, then send the
15462            // registered receivers separately so they don't wait for the
15463            // components to be launched.
15464            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15465            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15466                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15467                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15468                    ordered, sticky, false, userId);
15469            if (DEBUG_BROADCAST) Slog.v(
15470                    TAG, "Enqueueing parallel broadcast " + r);
15471            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15472            if (!replaced) {
15473                queue.enqueueParallelBroadcastLocked(r);
15474                queue.scheduleBroadcastsLocked();
15475            }
15476            registeredReceivers = null;
15477            NR = 0;
15478        }
15479
15480        // Merge into one list.
15481        int ir = 0;
15482        if (receivers != null) {
15483            // A special case for PACKAGE_ADDED: do not allow the package
15484            // being added to see this broadcast.  This prevents them from
15485            // using this as a back door to get run as soon as they are
15486            // installed.  Maybe in the future we want to have a special install
15487            // broadcast or such for apps, but we'd like to deliberately make
15488            // this decision.
15489            String skipPackages[] = null;
15490            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15491                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15492                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15493                Uri data = intent.getData();
15494                if (data != null) {
15495                    String pkgName = data.getSchemeSpecificPart();
15496                    if (pkgName != null) {
15497                        skipPackages = new String[] { pkgName };
15498                    }
15499                }
15500            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15501                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15502            }
15503            if (skipPackages != null && (skipPackages.length > 0)) {
15504                for (String skipPackage : skipPackages) {
15505                    if (skipPackage != null) {
15506                        int NT = receivers.size();
15507                        for (int it=0; it<NT; it++) {
15508                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15509                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15510                                receivers.remove(it);
15511                                it--;
15512                                NT--;
15513                            }
15514                        }
15515                    }
15516                }
15517            }
15518
15519            int NT = receivers != null ? receivers.size() : 0;
15520            int it = 0;
15521            ResolveInfo curt = null;
15522            BroadcastFilter curr = null;
15523            while (it < NT && ir < NR) {
15524                if (curt == null) {
15525                    curt = (ResolveInfo)receivers.get(it);
15526                }
15527                if (curr == null) {
15528                    curr = registeredReceivers.get(ir);
15529                }
15530                if (curr.getPriority() >= curt.priority) {
15531                    // Insert this broadcast record into the final list.
15532                    receivers.add(it, curr);
15533                    ir++;
15534                    curr = null;
15535                    it++;
15536                    NT++;
15537                } else {
15538                    // Skip to the next ResolveInfo in the final list.
15539                    it++;
15540                    curt = null;
15541                }
15542            }
15543        }
15544        while (ir < NR) {
15545            if (receivers == null) {
15546                receivers = new ArrayList();
15547            }
15548            receivers.add(registeredReceivers.get(ir));
15549            ir++;
15550        }
15551
15552        if ((receivers != null && receivers.size() > 0)
15553                || resultTo != null) {
15554            BroadcastQueue queue = broadcastQueueForIntent(intent);
15555            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15556                    callerPackage, callingPid, callingUid, resolvedType,
15557                    requiredPermission, appOp, receivers, resultTo, resultCode,
15558                    resultData, map, ordered, sticky, false, userId);
15559            if (DEBUG_BROADCAST) Slog.v(
15560                    TAG, "Enqueueing ordered broadcast " + r
15561                    + ": prev had " + queue.mOrderedBroadcasts.size());
15562            if (DEBUG_BROADCAST) {
15563                int seq = r.intent.getIntExtra("seq", -1);
15564                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15565            }
15566            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15567            if (!replaced) {
15568                queue.enqueueOrderedBroadcastLocked(r);
15569                queue.scheduleBroadcastsLocked();
15570            }
15571        }
15572
15573        return ActivityManager.BROADCAST_SUCCESS;
15574    }
15575
15576    final Intent verifyBroadcastLocked(Intent intent) {
15577        // Refuse possible leaked file descriptors
15578        if (intent != null && intent.hasFileDescriptors() == true) {
15579            throw new IllegalArgumentException("File descriptors passed in Intent");
15580        }
15581
15582        int flags = intent.getFlags();
15583
15584        if (!mProcessesReady) {
15585            // if the caller really truly claims to know what they're doing, go
15586            // ahead and allow the broadcast without launching any receivers
15587            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15588                intent = new Intent(intent);
15589                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15590            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15591                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15592                        + " before boot completion");
15593                throw new IllegalStateException("Cannot broadcast before boot completed");
15594            }
15595        }
15596
15597        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15598            throw new IllegalArgumentException(
15599                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15600        }
15601
15602        return intent;
15603    }
15604
15605    public final int broadcastIntent(IApplicationThread caller,
15606            Intent intent, String resolvedType, IIntentReceiver resultTo,
15607            int resultCode, String resultData, Bundle map,
15608            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15609        enforceNotIsolatedCaller("broadcastIntent");
15610        synchronized(this) {
15611            intent = verifyBroadcastLocked(intent);
15612
15613            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15614            final int callingPid = Binder.getCallingPid();
15615            final int callingUid = Binder.getCallingUid();
15616            final long origId = Binder.clearCallingIdentity();
15617            int res = broadcastIntentLocked(callerApp,
15618                    callerApp != null ? callerApp.info.packageName : null,
15619                    intent, resolvedType, resultTo,
15620                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15621                    callingPid, callingUid, userId);
15622            Binder.restoreCallingIdentity(origId);
15623            return res;
15624        }
15625    }
15626
15627    int broadcastIntentInPackage(String packageName, int uid,
15628            Intent intent, String resolvedType, IIntentReceiver resultTo,
15629            int resultCode, String resultData, Bundle map,
15630            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15631        synchronized(this) {
15632            intent = verifyBroadcastLocked(intent);
15633
15634            final long origId = Binder.clearCallingIdentity();
15635            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15636                    resultTo, resultCode, resultData, map, requiredPermission,
15637                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15638            Binder.restoreCallingIdentity(origId);
15639            return res;
15640        }
15641    }
15642
15643    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15644        // Refuse possible leaked file descriptors
15645        if (intent != null && intent.hasFileDescriptors() == true) {
15646            throw new IllegalArgumentException("File descriptors passed in Intent");
15647        }
15648
15649        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15650                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15651
15652        synchronized(this) {
15653            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15654                    != PackageManager.PERMISSION_GRANTED) {
15655                String msg = "Permission Denial: unbroadcastIntent() from pid="
15656                        + Binder.getCallingPid()
15657                        + ", uid=" + Binder.getCallingUid()
15658                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15659                Slog.w(TAG, msg);
15660                throw new SecurityException(msg);
15661            }
15662            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15663            if (stickies != null) {
15664                ArrayList<Intent> list = stickies.get(intent.getAction());
15665                if (list != null) {
15666                    int N = list.size();
15667                    int i;
15668                    for (i=0; i<N; i++) {
15669                        if (intent.filterEquals(list.get(i))) {
15670                            list.remove(i);
15671                            break;
15672                        }
15673                    }
15674                    if (list.size() <= 0) {
15675                        stickies.remove(intent.getAction());
15676                    }
15677                }
15678                if (stickies.size() <= 0) {
15679                    mStickyBroadcasts.remove(userId);
15680                }
15681            }
15682        }
15683    }
15684
15685    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15686            String resultData, Bundle resultExtras, boolean resultAbort) {
15687        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15688        if (r == null) {
15689            Slog.w(TAG, "finishReceiver called but not found on queue");
15690            return false;
15691        }
15692
15693        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15694    }
15695
15696    void backgroundServicesFinishedLocked(int userId) {
15697        for (BroadcastQueue queue : mBroadcastQueues) {
15698            queue.backgroundServicesFinishedLocked(userId);
15699        }
15700    }
15701
15702    public void finishReceiver(IBinder who, int resultCode, String resultData,
15703            Bundle resultExtras, boolean resultAbort) {
15704        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15705
15706        // Refuse possible leaked file descriptors
15707        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15708            throw new IllegalArgumentException("File descriptors passed in Bundle");
15709        }
15710
15711        final long origId = Binder.clearCallingIdentity();
15712        try {
15713            boolean doNext = false;
15714            BroadcastRecord r;
15715
15716            synchronized(this) {
15717                r = broadcastRecordForReceiverLocked(who);
15718                if (r != null) {
15719                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15720                        resultData, resultExtras, resultAbort, true);
15721                }
15722            }
15723
15724            if (doNext) {
15725                r.queue.processNextBroadcast(false);
15726            }
15727            trimApplications();
15728        } finally {
15729            Binder.restoreCallingIdentity(origId);
15730        }
15731    }
15732
15733    // =========================================================
15734    // INSTRUMENTATION
15735    // =========================================================
15736
15737    public boolean startInstrumentation(ComponentName className,
15738            String profileFile, int flags, Bundle arguments,
15739            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15740            int userId, String abiOverride) {
15741        enforceNotIsolatedCaller("startInstrumentation");
15742        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15743                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15744        // Refuse possible leaked file descriptors
15745        if (arguments != null && arguments.hasFileDescriptors()) {
15746            throw new IllegalArgumentException("File descriptors passed in Bundle");
15747        }
15748
15749        synchronized(this) {
15750            InstrumentationInfo ii = null;
15751            ApplicationInfo ai = null;
15752            try {
15753                ii = mContext.getPackageManager().getInstrumentationInfo(
15754                    className, STOCK_PM_FLAGS);
15755                ai = AppGlobals.getPackageManager().getApplicationInfo(
15756                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15757            } catch (PackageManager.NameNotFoundException e) {
15758            } catch (RemoteException e) {
15759            }
15760            if (ii == null) {
15761                reportStartInstrumentationFailure(watcher, className,
15762                        "Unable to find instrumentation info for: " + className);
15763                return false;
15764            }
15765            if (ai == null) {
15766                reportStartInstrumentationFailure(watcher, className,
15767                        "Unable to find instrumentation target package: " + ii.targetPackage);
15768                return false;
15769            }
15770
15771            int match = mContext.getPackageManager().checkSignatures(
15772                    ii.targetPackage, ii.packageName);
15773            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15774                String msg = "Permission Denial: starting instrumentation "
15775                        + className + " from pid="
15776                        + Binder.getCallingPid()
15777                        + ", uid=" + Binder.getCallingPid()
15778                        + " not allowed because package " + ii.packageName
15779                        + " does not have a signature matching the target "
15780                        + ii.targetPackage;
15781                reportStartInstrumentationFailure(watcher, className, msg);
15782                throw new SecurityException(msg);
15783            }
15784
15785            final long origId = Binder.clearCallingIdentity();
15786            // Instrumentation can kill and relaunch even persistent processes
15787            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15788                    "start instr");
15789            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15790            app.instrumentationClass = className;
15791            app.instrumentationInfo = ai;
15792            app.instrumentationProfileFile = profileFile;
15793            app.instrumentationArguments = arguments;
15794            app.instrumentationWatcher = watcher;
15795            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15796            app.instrumentationResultClass = className;
15797            Binder.restoreCallingIdentity(origId);
15798        }
15799
15800        return true;
15801    }
15802
15803    /**
15804     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15805     * error to the logs, but if somebody is watching, send the report there too.  This enables
15806     * the "am" command to report errors with more information.
15807     *
15808     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15809     * @param cn The component name of the instrumentation.
15810     * @param report The error report.
15811     */
15812    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15813            ComponentName cn, String report) {
15814        Slog.w(TAG, report);
15815        try {
15816            if (watcher != null) {
15817                Bundle results = new Bundle();
15818                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15819                results.putString("Error", report);
15820                watcher.instrumentationStatus(cn, -1, results);
15821            }
15822        } catch (RemoteException e) {
15823            Slog.w(TAG, e);
15824        }
15825    }
15826
15827    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15828        if (app.instrumentationWatcher != null) {
15829            try {
15830                // NOTE:  IInstrumentationWatcher *must* be oneway here
15831                app.instrumentationWatcher.instrumentationFinished(
15832                    app.instrumentationClass,
15833                    resultCode,
15834                    results);
15835            } catch (RemoteException e) {
15836            }
15837        }
15838        if (app.instrumentationUiAutomationConnection != null) {
15839            try {
15840                app.instrumentationUiAutomationConnection.shutdown();
15841            } catch (RemoteException re) {
15842                /* ignore */
15843            }
15844            // Only a UiAutomation can set this flag and now that
15845            // it is finished we make sure it is reset to its default.
15846            mUserIsMonkey = false;
15847        }
15848        app.instrumentationWatcher = null;
15849        app.instrumentationUiAutomationConnection = null;
15850        app.instrumentationClass = null;
15851        app.instrumentationInfo = null;
15852        app.instrumentationProfileFile = null;
15853        app.instrumentationArguments = null;
15854
15855        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15856                "finished inst");
15857    }
15858
15859    public void finishInstrumentation(IApplicationThread target,
15860            int resultCode, Bundle results) {
15861        int userId = UserHandle.getCallingUserId();
15862        // Refuse possible leaked file descriptors
15863        if (results != null && results.hasFileDescriptors()) {
15864            throw new IllegalArgumentException("File descriptors passed in Intent");
15865        }
15866
15867        synchronized(this) {
15868            ProcessRecord app = getRecordForAppLocked(target);
15869            if (app == null) {
15870                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15871                return;
15872            }
15873            final long origId = Binder.clearCallingIdentity();
15874            finishInstrumentationLocked(app, resultCode, results);
15875            Binder.restoreCallingIdentity(origId);
15876        }
15877    }
15878
15879    // =========================================================
15880    // CONFIGURATION
15881    // =========================================================
15882
15883    public ConfigurationInfo getDeviceConfigurationInfo() {
15884        ConfigurationInfo config = new ConfigurationInfo();
15885        synchronized (this) {
15886            config.reqTouchScreen = mConfiguration.touchscreen;
15887            config.reqKeyboardType = mConfiguration.keyboard;
15888            config.reqNavigation = mConfiguration.navigation;
15889            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15890                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15891                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15892            }
15893            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15894                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15895                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15896            }
15897            config.reqGlEsVersion = GL_ES_VERSION;
15898        }
15899        return config;
15900    }
15901
15902    ActivityStack getFocusedStack() {
15903        return mStackSupervisor.getFocusedStack();
15904    }
15905
15906    public Configuration getConfiguration() {
15907        Configuration ci;
15908        synchronized(this) {
15909            ci = new Configuration(mConfiguration);
15910        }
15911        return ci;
15912    }
15913
15914    public void updatePersistentConfiguration(Configuration values) {
15915        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15916                "updateConfiguration()");
15917        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15918                "updateConfiguration()");
15919        if (values == null) {
15920            throw new NullPointerException("Configuration must not be null");
15921        }
15922
15923        synchronized(this) {
15924            final long origId = Binder.clearCallingIdentity();
15925            updateConfigurationLocked(values, null, true, false);
15926            Binder.restoreCallingIdentity(origId);
15927        }
15928    }
15929
15930    public void updateConfiguration(Configuration values) {
15931        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15932                "updateConfiguration()");
15933
15934        synchronized(this) {
15935            if (values == null && mWindowManager != null) {
15936                // sentinel: fetch the current configuration from the window manager
15937                values = mWindowManager.computeNewConfiguration();
15938            }
15939
15940            if (mWindowManager != null) {
15941                mProcessList.applyDisplaySize(mWindowManager);
15942            }
15943
15944            final long origId = Binder.clearCallingIdentity();
15945            if (values != null) {
15946                Settings.System.clearConfiguration(values);
15947            }
15948            updateConfigurationLocked(values, null, false, false);
15949            Binder.restoreCallingIdentity(origId);
15950        }
15951    }
15952
15953    /**
15954     * Do either or both things: (1) change the current configuration, and (2)
15955     * make sure the given activity is running with the (now) current
15956     * configuration.  Returns true if the activity has been left running, or
15957     * false if <var>starting</var> is being destroyed to match the new
15958     * configuration.
15959     * @param persistent TODO
15960     */
15961    boolean updateConfigurationLocked(Configuration values,
15962            ActivityRecord starting, boolean persistent, boolean initLocale) {
15963        int changes = 0;
15964
15965        if (values != null) {
15966            Configuration newConfig = new Configuration(mConfiguration);
15967            changes = newConfig.updateFrom(values);
15968            if (changes != 0) {
15969                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15970                    Slog.i(TAG, "Updating configuration to: " + values);
15971                }
15972
15973                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15974
15975                if (values.locale != null && !initLocale) {
15976                    saveLocaleLocked(values.locale,
15977                                     !values.locale.equals(mConfiguration.locale),
15978                                     values.userSetLocale);
15979                }
15980
15981                mConfigurationSeq++;
15982                if (mConfigurationSeq <= 0) {
15983                    mConfigurationSeq = 1;
15984                }
15985                newConfig.seq = mConfigurationSeq;
15986                mConfiguration = newConfig;
15987                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15988                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15989                //mUsageStatsService.noteStartConfig(newConfig);
15990
15991                final Configuration configCopy = new Configuration(mConfiguration);
15992
15993                // TODO: If our config changes, should we auto dismiss any currently
15994                // showing dialogs?
15995                mShowDialogs = shouldShowDialogs(newConfig);
15996
15997                AttributeCache ac = AttributeCache.instance();
15998                if (ac != null) {
15999                    ac.updateConfiguration(configCopy);
16000                }
16001
16002                // Make sure all resources in our process are updated
16003                // right now, so that anyone who is going to retrieve
16004                // resource values after we return will be sure to get
16005                // the new ones.  This is especially important during
16006                // boot, where the first config change needs to guarantee
16007                // all resources have that config before following boot
16008                // code is executed.
16009                mSystemThread.applyConfigurationToResources(configCopy);
16010
16011                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16012                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16013                    msg.obj = new Configuration(configCopy);
16014                    mHandler.sendMessage(msg);
16015                }
16016
16017                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16018                    ProcessRecord app = mLruProcesses.get(i);
16019                    try {
16020                        if (app.thread != null) {
16021                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16022                                    + app.processName + " new config " + mConfiguration);
16023                            app.thread.scheduleConfigurationChanged(configCopy);
16024                        }
16025                    } catch (Exception e) {
16026                    }
16027                }
16028                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16029                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16030                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16031                        | Intent.FLAG_RECEIVER_FOREGROUND);
16032                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16033                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16034                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16035                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16036                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16037                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16038                    broadcastIntentLocked(null, null, intent,
16039                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16040                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16041                }
16042            }
16043        }
16044
16045        boolean kept = true;
16046        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16047        // mainStack is null during startup.
16048        if (mainStack != null) {
16049            if (changes != 0 && starting == null) {
16050                // If the configuration changed, and the caller is not already
16051                // in the process of starting an activity, then find the top
16052                // activity to check if its configuration needs to change.
16053                starting = mainStack.topRunningActivityLocked(null);
16054            }
16055
16056            if (starting != null) {
16057                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16058                // And we need to make sure at this point that all other activities
16059                // are made visible with the correct configuration.
16060                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16061            }
16062        }
16063
16064        if (values != null && mWindowManager != null) {
16065            mWindowManager.setNewConfiguration(mConfiguration);
16066        }
16067
16068        return kept;
16069    }
16070
16071    /**
16072     * Decide based on the configuration whether we should shouw the ANR,
16073     * crash, etc dialogs.  The idea is that if there is no affordnace to
16074     * press the on-screen buttons, we shouldn't show the dialog.
16075     *
16076     * A thought: SystemUI might also want to get told about this, the Power
16077     * dialog / global actions also might want different behaviors.
16078     */
16079    private static final boolean shouldShowDialogs(Configuration config) {
16080        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16081                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16082    }
16083
16084    /**
16085     * Save the locale.  You must be inside a synchronized (this) block.
16086     */
16087    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16088        if(isDiff) {
16089            SystemProperties.set("user.language", l.getLanguage());
16090            SystemProperties.set("user.region", l.getCountry());
16091        }
16092
16093        if(isPersist) {
16094            SystemProperties.set("persist.sys.language", l.getLanguage());
16095            SystemProperties.set("persist.sys.country", l.getCountry());
16096            SystemProperties.set("persist.sys.localevar", l.getVariant());
16097        }
16098    }
16099
16100    @Override
16101    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16102        synchronized (this) {
16103            ActivityRecord srec = ActivityRecord.forToken(token);
16104            if (srec.task != null && srec.task.stack != null) {
16105                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16106            }
16107        }
16108        return false;
16109    }
16110
16111    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16112            Intent resultData) {
16113
16114        synchronized (this) {
16115            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16116            if (stack != null) {
16117                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16118            }
16119            return false;
16120        }
16121    }
16122
16123    public int getLaunchedFromUid(IBinder activityToken) {
16124        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16125        if (srec == null) {
16126            return -1;
16127        }
16128        return srec.launchedFromUid;
16129    }
16130
16131    public String getLaunchedFromPackage(IBinder activityToken) {
16132        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16133        if (srec == null) {
16134            return null;
16135        }
16136        return srec.launchedFromPackage;
16137    }
16138
16139    // =========================================================
16140    // LIFETIME MANAGEMENT
16141    // =========================================================
16142
16143    // Returns which broadcast queue the app is the current [or imminent] receiver
16144    // on, or 'null' if the app is not an active broadcast recipient.
16145    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16146        BroadcastRecord r = app.curReceiver;
16147        if (r != null) {
16148            return r.queue;
16149        }
16150
16151        // It's not the current receiver, but it might be starting up to become one
16152        synchronized (this) {
16153            for (BroadcastQueue queue : mBroadcastQueues) {
16154                r = queue.mPendingBroadcast;
16155                if (r != null && r.curApp == app) {
16156                    // found it; report which queue it's in
16157                    return queue;
16158                }
16159            }
16160        }
16161
16162        return null;
16163    }
16164
16165    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16166            boolean doingAll, long now) {
16167        if (mAdjSeq == app.adjSeq) {
16168            // This adjustment has already been computed.
16169            return app.curRawAdj;
16170        }
16171
16172        if (app.thread == null) {
16173            app.adjSeq = mAdjSeq;
16174            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16175            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16176            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16177        }
16178
16179        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16180        app.adjSource = null;
16181        app.adjTarget = null;
16182        app.empty = false;
16183        app.cached = false;
16184
16185        final int activitiesSize = app.activities.size();
16186
16187        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16188            // The max adjustment doesn't allow this app to be anything
16189            // below foreground, so it is not worth doing work for it.
16190            app.adjType = "fixed";
16191            app.adjSeq = mAdjSeq;
16192            app.curRawAdj = app.maxAdj;
16193            app.foregroundActivities = false;
16194            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16195            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16196            // System processes can do UI, and when they do we want to have
16197            // them trim their memory after the user leaves the UI.  To
16198            // facilitate this, here we need to determine whether or not it
16199            // is currently showing UI.
16200            app.systemNoUi = true;
16201            if (app == TOP_APP) {
16202                app.systemNoUi = false;
16203            } else if (activitiesSize > 0) {
16204                for (int j = 0; j < activitiesSize; j++) {
16205                    final ActivityRecord r = app.activities.get(j);
16206                    if (r.visible) {
16207                        app.systemNoUi = false;
16208                    }
16209                }
16210            }
16211            if (!app.systemNoUi) {
16212                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16213            }
16214            return (app.curAdj=app.maxAdj);
16215        }
16216
16217        app.systemNoUi = false;
16218
16219        // Determine the importance of the process, starting with most
16220        // important to least, and assign an appropriate OOM adjustment.
16221        int adj;
16222        int schedGroup;
16223        int procState;
16224        boolean foregroundActivities = false;
16225        BroadcastQueue queue;
16226        if (app == TOP_APP) {
16227            // The last app on the list is the foreground app.
16228            adj = ProcessList.FOREGROUND_APP_ADJ;
16229            schedGroup = Process.THREAD_GROUP_DEFAULT;
16230            app.adjType = "top-activity";
16231            foregroundActivities = true;
16232            procState = ActivityManager.PROCESS_STATE_TOP;
16233        } else if (app.instrumentationClass != null) {
16234            // Don't want to kill running instrumentation.
16235            adj = ProcessList.FOREGROUND_APP_ADJ;
16236            schedGroup = Process.THREAD_GROUP_DEFAULT;
16237            app.adjType = "instrumentation";
16238            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16239        } else if ((queue = isReceivingBroadcast(app)) != null) {
16240            // An app that is currently receiving a broadcast also
16241            // counts as being in the foreground for OOM killer purposes.
16242            // It's placed in a sched group based on the nature of the
16243            // broadcast as reflected by which queue it's active in.
16244            adj = ProcessList.FOREGROUND_APP_ADJ;
16245            schedGroup = (queue == mFgBroadcastQueue)
16246                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16247            app.adjType = "broadcast";
16248            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16249        } else if (app.executingServices.size() > 0) {
16250            // An app that is currently executing a service callback also
16251            // counts as being in the foreground.
16252            adj = ProcessList.FOREGROUND_APP_ADJ;
16253            schedGroup = app.execServicesFg ?
16254                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16255            app.adjType = "exec-service";
16256            procState = ActivityManager.PROCESS_STATE_SERVICE;
16257            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16258        } else {
16259            // As far as we know the process is empty.  We may change our mind later.
16260            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16261            // At this point we don't actually know the adjustment.  Use the cached adj
16262            // value that the caller wants us to.
16263            adj = cachedAdj;
16264            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16265            app.cached = true;
16266            app.empty = true;
16267            app.adjType = "cch-empty";
16268        }
16269
16270        // Examine all activities if not already foreground.
16271        if (!foregroundActivities && activitiesSize > 0) {
16272            for (int j = 0; j < activitiesSize; j++) {
16273                final ActivityRecord r = app.activities.get(j);
16274                if (r.app != app) {
16275                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16276                            + app + "?!?");
16277                    continue;
16278                }
16279                if (r.visible) {
16280                    // App has a visible activity; only upgrade adjustment.
16281                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16282                        adj = ProcessList.VISIBLE_APP_ADJ;
16283                        app.adjType = "visible";
16284                    }
16285                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16286                        procState = ActivityManager.PROCESS_STATE_TOP;
16287                    }
16288                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16289                    app.cached = false;
16290                    app.empty = false;
16291                    foregroundActivities = true;
16292                    break;
16293                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16294                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16295                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16296                        app.adjType = "pausing";
16297                    }
16298                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16299                        procState = ActivityManager.PROCESS_STATE_TOP;
16300                    }
16301                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16302                    app.cached = false;
16303                    app.empty = false;
16304                    foregroundActivities = true;
16305                } else if (r.state == ActivityState.STOPPING) {
16306                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16307                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16308                        app.adjType = "stopping";
16309                    }
16310                    // For the process state, we will at this point consider the
16311                    // process to be cached.  It will be cached either as an activity
16312                    // or empty depending on whether the activity is finishing.  We do
16313                    // this so that we can treat the process as cached for purposes of
16314                    // memory trimming (determing current memory level, trim command to
16315                    // send to process) since there can be an arbitrary number of stopping
16316                    // processes and they should soon all go into the cached state.
16317                    if (!r.finishing) {
16318                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16319                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16320                        }
16321                    }
16322                    app.cached = false;
16323                    app.empty = false;
16324                    foregroundActivities = true;
16325                } else {
16326                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16327                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16328                        app.adjType = "cch-act";
16329                    }
16330                }
16331            }
16332        }
16333
16334        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16335            if (app.foregroundServices) {
16336                // The user is aware of this app, so make it visible.
16337                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16338                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16339                app.cached = false;
16340                app.adjType = "fg-service";
16341                schedGroup = Process.THREAD_GROUP_DEFAULT;
16342            } else if (app.forcingToForeground != null) {
16343                // The user is aware of this app, so make it visible.
16344                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16345                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16346                app.cached = false;
16347                app.adjType = "force-fg";
16348                app.adjSource = app.forcingToForeground;
16349                schedGroup = Process.THREAD_GROUP_DEFAULT;
16350            }
16351        }
16352
16353        if (app == mHeavyWeightProcess) {
16354            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16355                // We don't want to kill the current heavy-weight process.
16356                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16357                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16358                app.cached = false;
16359                app.adjType = "heavy";
16360            }
16361            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16362                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16363            }
16364        }
16365
16366        if (app == mHomeProcess) {
16367            if (adj > ProcessList.HOME_APP_ADJ) {
16368                // This process is hosting what we currently consider to be the
16369                // home app, so we don't want to let it go into the background.
16370                adj = ProcessList.HOME_APP_ADJ;
16371                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16372                app.cached = false;
16373                app.adjType = "home";
16374            }
16375            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16376                procState = ActivityManager.PROCESS_STATE_HOME;
16377            }
16378        }
16379
16380        if (app == mPreviousProcess && app.activities.size() > 0) {
16381            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16382                // This was the previous process that showed UI to the user.
16383                // We want to try to keep it around more aggressively, to give
16384                // a good experience around switching between two apps.
16385                adj = ProcessList.PREVIOUS_APP_ADJ;
16386                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16387                app.cached = false;
16388                app.adjType = "previous";
16389            }
16390            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16391                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16392            }
16393        }
16394
16395        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16396                + " reason=" + app.adjType);
16397
16398        // By default, we use the computed adjustment.  It may be changed if
16399        // there are applications dependent on our services or providers, but
16400        // this gives us a baseline and makes sure we don't get into an
16401        // infinite recursion.
16402        app.adjSeq = mAdjSeq;
16403        app.curRawAdj = adj;
16404        app.hasStartedServices = false;
16405
16406        if (mBackupTarget != null && app == mBackupTarget.app) {
16407            // If possible we want to avoid killing apps while they're being backed up
16408            if (adj > ProcessList.BACKUP_APP_ADJ) {
16409                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16410                adj = ProcessList.BACKUP_APP_ADJ;
16411                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16412                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16413                }
16414                app.adjType = "backup";
16415                app.cached = false;
16416            }
16417            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16418                procState = ActivityManager.PROCESS_STATE_BACKUP;
16419            }
16420        }
16421
16422        boolean mayBeTop = false;
16423
16424        for (int is = app.services.size()-1;
16425                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16426                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16427                        || procState > ActivityManager.PROCESS_STATE_TOP);
16428                is--) {
16429            ServiceRecord s = app.services.valueAt(is);
16430            if (s.startRequested) {
16431                app.hasStartedServices = true;
16432                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16433                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16434                }
16435                if (app.hasShownUi && app != mHomeProcess) {
16436                    // If this process has shown some UI, let it immediately
16437                    // go to the LRU list because it may be pretty heavy with
16438                    // UI stuff.  We'll tag it with a label just to help
16439                    // debug and understand what is going on.
16440                    if (adj > ProcessList.SERVICE_ADJ) {
16441                        app.adjType = "cch-started-ui-services";
16442                    }
16443                } else {
16444                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16445                        // This service has seen some activity within
16446                        // recent memory, so we will keep its process ahead
16447                        // of the background processes.
16448                        if (adj > ProcessList.SERVICE_ADJ) {
16449                            adj = ProcessList.SERVICE_ADJ;
16450                            app.adjType = "started-services";
16451                            app.cached = false;
16452                        }
16453                    }
16454                    // If we have let the service slide into the background
16455                    // state, still have some text describing what it is doing
16456                    // even though the service no longer has an impact.
16457                    if (adj > ProcessList.SERVICE_ADJ) {
16458                        app.adjType = "cch-started-services";
16459                    }
16460                }
16461            }
16462            for (int conni = s.connections.size()-1;
16463                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16464                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16465                            || procState > ActivityManager.PROCESS_STATE_TOP);
16466                    conni--) {
16467                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16468                for (int i = 0;
16469                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16470                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16471                                || procState > ActivityManager.PROCESS_STATE_TOP);
16472                        i++) {
16473                    // XXX should compute this based on the max of
16474                    // all connected clients.
16475                    ConnectionRecord cr = clist.get(i);
16476                    if (cr.binding.client == app) {
16477                        // Binding to ourself is not interesting.
16478                        continue;
16479                    }
16480                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16481                        ProcessRecord client = cr.binding.client;
16482                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16483                                TOP_APP, doingAll, now);
16484                        int clientProcState = client.curProcState;
16485                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16486                            // If the other app is cached for any reason, for purposes here
16487                            // we are going to consider it empty.  The specific cached state
16488                            // doesn't propagate except under certain conditions.
16489                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16490                        }
16491                        String adjType = null;
16492                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16493                            // Not doing bind OOM management, so treat
16494                            // this guy more like a started service.
16495                            if (app.hasShownUi && app != mHomeProcess) {
16496                                // If this process has shown some UI, let it immediately
16497                                // go to the LRU list because it may be pretty heavy with
16498                                // UI stuff.  We'll tag it with a label just to help
16499                                // debug and understand what is going on.
16500                                if (adj > clientAdj) {
16501                                    adjType = "cch-bound-ui-services";
16502                                }
16503                                app.cached = false;
16504                                clientAdj = adj;
16505                                clientProcState = procState;
16506                            } else {
16507                                if (now >= (s.lastActivity
16508                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16509                                    // This service has not seen activity within
16510                                    // recent memory, so allow it to drop to the
16511                                    // LRU list if there is no other reason to keep
16512                                    // it around.  We'll also tag it with a label just
16513                                    // to help debug and undertand what is going on.
16514                                    if (adj > clientAdj) {
16515                                        adjType = "cch-bound-services";
16516                                    }
16517                                    clientAdj = adj;
16518                                }
16519                            }
16520                        }
16521                        if (adj > clientAdj) {
16522                            // If this process has recently shown UI, and
16523                            // the process that is binding to it is less
16524                            // important than being visible, then we don't
16525                            // care about the binding as much as we care
16526                            // about letting this process get into the LRU
16527                            // list to be killed and restarted if needed for
16528                            // memory.
16529                            if (app.hasShownUi && app != mHomeProcess
16530                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16531                                adjType = "cch-bound-ui-services";
16532                            } else {
16533                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16534                                        |Context.BIND_IMPORTANT)) != 0) {
16535                                    adj = clientAdj;
16536                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16537                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16538                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16539                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16540                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16541                                    adj = clientAdj;
16542                                } else {
16543                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16544                                        adj = ProcessList.VISIBLE_APP_ADJ;
16545                                    }
16546                                }
16547                                if (!client.cached) {
16548                                    app.cached = false;
16549                                }
16550                                adjType = "service";
16551                            }
16552                        }
16553                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16554                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16555                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16556                            }
16557                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16558                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16559                                    // Special handling of clients who are in the top state.
16560                                    // We *may* want to consider this process to be in the
16561                                    // top state as well, but only if there is not another
16562                                    // reason for it to be running.  Being on the top is a
16563                                    // special state, meaning you are specifically running
16564                                    // for the current top app.  If the process is already
16565                                    // running in the background for some other reason, it
16566                                    // is more important to continue considering it to be
16567                                    // in the background state.
16568                                    mayBeTop = true;
16569                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16570                                } else {
16571                                    // Special handling for above-top states (persistent
16572                                    // processes).  These should not bring the current process
16573                                    // into the top state, since they are not on top.  Instead
16574                                    // give them the best state after that.
16575                                    clientProcState =
16576                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16577                                }
16578                            }
16579                        } else {
16580                            if (clientProcState <
16581                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16582                                clientProcState =
16583                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16584                            }
16585                        }
16586                        if (procState > clientProcState) {
16587                            procState = clientProcState;
16588                        }
16589                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16590                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16591                            app.pendingUiClean = true;
16592                        }
16593                        if (adjType != null) {
16594                            app.adjType = adjType;
16595                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16596                                    .REASON_SERVICE_IN_USE;
16597                            app.adjSource = cr.binding.client;
16598                            app.adjSourceProcState = clientProcState;
16599                            app.adjTarget = s.name;
16600                        }
16601                    }
16602                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16603                        app.treatLikeActivity = true;
16604                    }
16605                    final ActivityRecord a = cr.activity;
16606                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16607                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16608                                (a.visible || a.state == ActivityState.RESUMED
16609                                 || a.state == ActivityState.PAUSING)) {
16610                            adj = ProcessList.FOREGROUND_APP_ADJ;
16611                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16612                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16613                            }
16614                            app.cached = false;
16615                            app.adjType = "service";
16616                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16617                                    .REASON_SERVICE_IN_USE;
16618                            app.adjSource = a;
16619                            app.adjSourceProcState = procState;
16620                            app.adjTarget = s.name;
16621                        }
16622                    }
16623                }
16624            }
16625        }
16626
16627        for (int provi = app.pubProviders.size()-1;
16628                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16629                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16630                        || procState > ActivityManager.PROCESS_STATE_TOP);
16631                provi--) {
16632            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16633            for (int i = cpr.connections.size()-1;
16634                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16635                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16636                            || procState > ActivityManager.PROCESS_STATE_TOP);
16637                    i--) {
16638                ContentProviderConnection conn = cpr.connections.get(i);
16639                ProcessRecord client = conn.client;
16640                if (client == app) {
16641                    // Being our own client is not interesting.
16642                    continue;
16643                }
16644                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16645                int clientProcState = client.curProcState;
16646                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16647                    // If the other app is cached for any reason, for purposes here
16648                    // we are going to consider it empty.
16649                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16650                }
16651                if (adj > clientAdj) {
16652                    if (app.hasShownUi && app != mHomeProcess
16653                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16654                        app.adjType = "cch-ui-provider";
16655                    } else {
16656                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16657                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16658                        app.adjType = "provider";
16659                    }
16660                    app.cached &= client.cached;
16661                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16662                            .REASON_PROVIDER_IN_USE;
16663                    app.adjSource = client;
16664                    app.adjSourceProcState = clientProcState;
16665                    app.adjTarget = cpr.name;
16666                }
16667                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16668                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16669                        // Special handling of clients who are in the top state.
16670                        // We *may* want to consider this process to be in the
16671                        // top state as well, but only if there is not another
16672                        // reason for it to be running.  Being on the top is a
16673                        // special state, meaning you are specifically running
16674                        // for the current top app.  If the process is already
16675                        // running in the background for some other reason, it
16676                        // is more important to continue considering it to be
16677                        // in the background state.
16678                        mayBeTop = true;
16679                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16680                    } else {
16681                        // Special handling for above-top states (persistent
16682                        // processes).  These should not bring the current process
16683                        // into the top state, since they are not on top.  Instead
16684                        // give them the best state after that.
16685                        clientProcState =
16686                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16687                    }
16688                }
16689                if (procState > clientProcState) {
16690                    procState = clientProcState;
16691                }
16692                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16693                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16694                }
16695            }
16696            // If the provider has external (non-framework) process
16697            // dependencies, ensure that its adjustment is at least
16698            // FOREGROUND_APP_ADJ.
16699            if (cpr.hasExternalProcessHandles()) {
16700                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16701                    adj = ProcessList.FOREGROUND_APP_ADJ;
16702                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16703                    app.cached = false;
16704                    app.adjType = "provider";
16705                    app.adjTarget = cpr.name;
16706                }
16707                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16708                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16709                }
16710            }
16711        }
16712
16713        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16714            // A client of one of our services or providers is in the top state.  We
16715            // *may* want to be in the top state, but not if we are already running in
16716            // the background for some other reason.  For the decision here, we are going
16717            // to pick out a few specific states that we want to remain in when a client
16718            // is top (states that tend to be longer-term) and otherwise allow it to go
16719            // to the top state.
16720            switch (procState) {
16721                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16722                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16723                case ActivityManager.PROCESS_STATE_SERVICE:
16724                    // These all are longer-term states, so pull them up to the top
16725                    // of the background states, but not all the way to the top state.
16726                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16727                    break;
16728                default:
16729                    // Otherwise, top is a better choice, so take it.
16730                    procState = ActivityManager.PROCESS_STATE_TOP;
16731                    break;
16732            }
16733        }
16734
16735        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16736            if (app.hasClientActivities) {
16737                // This is a cached process, but with client activities.  Mark it so.
16738                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16739                app.adjType = "cch-client-act";
16740            } else if (app.treatLikeActivity) {
16741                // This is a cached process, but somebody wants us to treat it like it has
16742                // an activity, okay!
16743                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16744                app.adjType = "cch-as-act";
16745            }
16746        }
16747
16748        if (adj == ProcessList.SERVICE_ADJ) {
16749            if (doingAll) {
16750                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16751                mNewNumServiceProcs++;
16752                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16753                if (!app.serviceb) {
16754                    // This service isn't far enough down on the LRU list to
16755                    // normally be a B service, but if we are low on RAM and it
16756                    // is large we want to force it down since we would prefer to
16757                    // keep launcher over it.
16758                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16759                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16760                        app.serviceHighRam = true;
16761                        app.serviceb = true;
16762                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16763                    } else {
16764                        mNewNumAServiceProcs++;
16765                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16766                    }
16767                } else {
16768                    app.serviceHighRam = false;
16769                }
16770            }
16771            if (app.serviceb) {
16772                adj = ProcessList.SERVICE_B_ADJ;
16773            }
16774        }
16775
16776        app.curRawAdj = adj;
16777
16778        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16779        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16780        if (adj > app.maxAdj) {
16781            adj = app.maxAdj;
16782            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16783                schedGroup = Process.THREAD_GROUP_DEFAULT;
16784            }
16785        }
16786
16787        // Do final modification to adj.  Everything we do between here and applying
16788        // the final setAdj must be done in this function, because we will also use
16789        // it when computing the final cached adj later.  Note that we don't need to
16790        // worry about this for max adj above, since max adj will always be used to
16791        // keep it out of the cached vaues.
16792        app.curAdj = app.modifyRawOomAdj(adj);
16793        app.curSchedGroup = schedGroup;
16794        app.curProcState = procState;
16795        app.foregroundActivities = foregroundActivities;
16796
16797        return app.curRawAdj;
16798    }
16799
16800    /**
16801     * Schedule PSS collection of a process.
16802     */
16803    void requestPssLocked(ProcessRecord proc, int procState) {
16804        if (mPendingPssProcesses.contains(proc)) {
16805            return;
16806        }
16807        if (mPendingPssProcesses.size() == 0) {
16808            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16809        }
16810        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16811        proc.pssProcState = procState;
16812        mPendingPssProcesses.add(proc);
16813    }
16814
16815    /**
16816     * Schedule PSS collection of all processes.
16817     */
16818    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16819        if (!always) {
16820            if (now < (mLastFullPssTime +
16821                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16822                return;
16823            }
16824        }
16825        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16826        mLastFullPssTime = now;
16827        mFullPssPending = true;
16828        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16829        mPendingPssProcesses.clear();
16830        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16831            ProcessRecord app = mLruProcesses.get(i);
16832            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16833                app.pssProcState = app.setProcState;
16834                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16835                        isSleeping(), now);
16836                mPendingPssProcesses.add(app);
16837            }
16838        }
16839        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16840    }
16841
16842    /**
16843     * Ask a given process to GC right now.
16844     */
16845    final void performAppGcLocked(ProcessRecord app) {
16846        try {
16847            app.lastRequestedGc = SystemClock.uptimeMillis();
16848            if (app.thread != null) {
16849                if (app.reportLowMemory) {
16850                    app.reportLowMemory = false;
16851                    app.thread.scheduleLowMemory();
16852                } else {
16853                    app.thread.processInBackground();
16854                }
16855            }
16856        } catch (Exception e) {
16857            // whatever.
16858        }
16859    }
16860
16861    /**
16862     * Returns true if things are idle enough to perform GCs.
16863     */
16864    private final boolean canGcNowLocked() {
16865        boolean processingBroadcasts = false;
16866        for (BroadcastQueue q : mBroadcastQueues) {
16867            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16868                processingBroadcasts = true;
16869            }
16870        }
16871        return !processingBroadcasts
16872                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16873    }
16874
16875    /**
16876     * Perform GCs on all processes that are waiting for it, but only
16877     * if things are idle.
16878     */
16879    final void performAppGcsLocked() {
16880        final int N = mProcessesToGc.size();
16881        if (N <= 0) {
16882            return;
16883        }
16884        if (canGcNowLocked()) {
16885            while (mProcessesToGc.size() > 0) {
16886                ProcessRecord proc = mProcessesToGc.remove(0);
16887                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16888                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16889                            <= SystemClock.uptimeMillis()) {
16890                        // To avoid spamming the system, we will GC processes one
16891                        // at a time, waiting a few seconds between each.
16892                        performAppGcLocked(proc);
16893                        scheduleAppGcsLocked();
16894                        return;
16895                    } else {
16896                        // It hasn't been long enough since we last GCed this
16897                        // process...  put it in the list to wait for its time.
16898                        addProcessToGcListLocked(proc);
16899                        break;
16900                    }
16901                }
16902            }
16903
16904            scheduleAppGcsLocked();
16905        }
16906    }
16907
16908    /**
16909     * If all looks good, perform GCs on all processes waiting for them.
16910     */
16911    final void performAppGcsIfAppropriateLocked() {
16912        if (canGcNowLocked()) {
16913            performAppGcsLocked();
16914            return;
16915        }
16916        // Still not idle, wait some more.
16917        scheduleAppGcsLocked();
16918    }
16919
16920    /**
16921     * Schedule the execution of all pending app GCs.
16922     */
16923    final void scheduleAppGcsLocked() {
16924        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16925
16926        if (mProcessesToGc.size() > 0) {
16927            // Schedule a GC for the time to the next process.
16928            ProcessRecord proc = mProcessesToGc.get(0);
16929            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16930
16931            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16932            long now = SystemClock.uptimeMillis();
16933            if (when < (now+GC_TIMEOUT)) {
16934                when = now + GC_TIMEOUT;
16935            }
16936            mHandler.sendMessageAtTime(msg, when);
16937        }
16938    }
16939
16940    /**
16941     * Add a process to the array of processes waiting to be GCed.  Keeps the
16942     * list in sorted order by the last GC time.  The process can't already be
16943     * on the list.
16944     */
16945    final void addProcessToGcListLocked(ProcessRecord proc) {
16946        boolean added = false;
16947        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16948            if (mProcessesToGc.get(i).lastRequestedGc <
16949                    proc.lastRequestedGc) {
16950                added = true;
16951                mProcessesToGc.add(i+1, proc);
16952                break;
16953            }
16954        }
16955        if (!added) {
16956            mProcessesToGc.add(0, proc);
16957        }
16958    }
16959
16960    /**
16961     * Set up to ask a process to GC itself.  This will either do it
16962     * immediately, or put it on the list of processes to gc the next
16963     * time things are idle.
16964     */
16965    final void scheduleAppGcLocked(ProcessRecord app) {
16966        long now = SystemClock.uptimeMillis();
16967        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16968            return;
16969        }
16970        if (!mProcessesToGc.contains(app)) {
16971            addProcessToGcListLocked(app);
16972            scheduleAppGcsLocked();
16973        }
16974    }
16975
16976    final void checkExcessivePowerUsageLocked(boolean doKills) {
16977        updateCpuStatsNow();
16978
16979        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16980        boolean doWakeKills = doKills;
16981        boolean doCpuKills = doKills;
16982        if (mLastPowerCheckRealtime == 0) {
16983            doWakeKills = false;
16984        }
16985        if (mLastPowerCheckUptime == 0) {
16986            doCpuKills = false;
16987        }
16988        if (stats.isScreenOn()) {
16989            doWakeKills = false;
16990        }
16991        final long curRealtime = SystemClock.elapsedRealtime();
16992        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16993        final long curUptime = SystemClock.uptimeMillis();
16994        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16995        mLastPowerCheckRealtime = curRealtime;
16996        mLastPowerCheckUptime = curUptime;
16997        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16998            doWakeKills = false;
16999        }
17000        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17001            doCpuKills = false;
17002        }
17003        int i = mLruProcesses.size();
17004        while (i > 0) {
17005            i--;
17006            ProcessRecord app = mLruProcesses.get(i);
17007            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17008                long wtime;
17009                synchronized (stats) {
17010                    wtime = stats.getProcessWakeTime(app.info.uid,
17011                            app.pid, curRealtime);
17012                }
17013                long wtimeUsed = wtime - app.lastWakeTime;
17014                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17015                if (DEBUG_POWER) {
17016                    StringBuilder sb = new StringBuilder(128);
17017                    sb.append("Wake for ");
17018                    app.toShortString(sb);
17019                    sb.append(": over ");
17020                    TimeUtils.formatDuration(realtimeSince, sb);
17021                    sb.append(" used ");
17022                    TimeUtils.formatDuration(wtimeUsed, sb);
17023                    sb.append(" (");
17024                    sb.append((wtimeUsed*100)/realtimeSince);
17025                    sb.append("%)");
17026                    Slog.i(TAG, sb.toString());
17027                    sb.setLength(0);
17028                    sb.append("CPU for ");
17029                    app.toShortString(sb);
17030                    sb.append(": over ");
17031                    TimeUtils.formatDuration(uptimeSince, sb);
17032                    sb.append(" used ");
17033                    TimeUtils.formatDuration(cputimeUsed, sb);
17034                    sb.append(" (");
17035                    sb.append((cputimeUsed*100)/uptimeSince);
17036                    sb.append("%)");
17037                    Slog.i(TAG, sb.toString());
17038                }
17039                // If a process has held a wake lock for more
17040                // than 50% of the time during this period,
17041                // that sounds bad.  Kill!
17042                if (doWakeKills && realtimeSince > 0
17043                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17044                    synchronized (stats) {
17045                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17046                                realtimeSince, wtimeUsed);
17047                    }
17048                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17049                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17050                } else if (doCpuKills && uptimeSince > 0
17051                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17052                    synchronized (stats) {
17053                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17054                                uptimeSince, cputimeUsed);
17055                    }
17056                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17057                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17058                } else {
17059                    app.lastWakeTime = wtime;
17060                    app.lastCpuTime = app.curCpuTime;
17061                }
17062            }
17063        }
17064    }
17065
17066    private final boolean applyOomAdjLocked(ProcessRecord app,
17067            ProcessRecord TOP_APP, boolean doingAll, long now) {
17068        boolean success = true;
17069
17070        if (app.curRawAdj != app.setRawAdj) {
17071            app.setRawAdj = app.curRawAdj;
17072        }
17073
17074        int changes = 0;
17075
17076        if (app.curAdj != app.setAdj) {
17077            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17078            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17079                TAG, "Set " + app.pid + " " + app.processName +
17080                " adj " + app.curAdj + ": " + app.adjType);
17081            app.setAdj = app.curAdj;
17082        }
17083
17084        if (app.setSchedGroup != app.curSchedGroup) {
17085            app.setSchedGroup = app.curSchedGroup;
17086            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17087                    "Setting process group of " + app.processName
17088                    + " to " + app.curSchedGroup);
17089            if (app.waitingToKill != null &&
17090                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17091                app.kill(app.waitingToKill, true);
17092                success = false;
17093            } else {
17094                if (true) {
17095                    long oldId = Binder.clearCallingIdentity();
17096                    try {
17097                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17098                    } catch (Exception e) {
17099                        Slog.w(TAG, "Failed setting process group of " + app.pid
17100                                + " to " + app.curSchedGroup);
17101                        e.printStackTrace();
17102                    } finally {
17103                        Binder.restoreCallingIdentity(oldId);
17104                    }
17105                } else {
17106                    if (app.thread != null) {
17107                        try {
17108                            app.thread.setSchedulingGroup(app.curSchedGroup);
17109                        } catch (RemoteException e) {
17110                        }
17111                    }
17112                }
17113                Process.setSwappiness(app.pid,
17114                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17115            }
17116        }
17117        if (app.repForegroundActivities != app.foregroundActivities) {
17118            app.repForegroundActivities = app.foregroundActivities;
17119            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17120        }
17121        if (app.repProcState != app.curProcState) {
17122            app.repProcState = app.curProcState;
17123            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17124            if (app.thread != null) {
17125                try {
17126                    if (false) {
17127                        //RuntimeException h = new RuntimeException("here");
17128                        Slog.i(TAG, "Sending new process state " + app.repProcState
17129                                + " to " + app /*, h*/);
17130                    }
17131                    app.thread.setProcessState(app.repProcState);
17132                } catch (RemoteException e) {
17133                }
17134            }
17135        }
17136        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17137                app.setProcState)) {
17138            app.lastStateTime = now;
17139            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17140                    isSleeping(), now);
17141            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17142                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17143                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17144                    + (app.nextPssTime-now) + ": " + app);
17145        } else {
17146            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17147                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17148                requestPssLocked(app, app.setProcState);
17149                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17150                        isSleeping(), now);
17151            } else if (false && DEBUG_PSS) {
17152                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17153            }
17154        }
17155        if (app.setProcState != app.curProcState) {
17156            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17157                    "Proc state change of " + app.processName
17158                    + " to " + app.curProcState);
17159            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17160            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17161            if (setImportant && !curImportant) {
17162                // This app is no longer something we consider important enough to allow to
17163                // use arbitrary amounts of battery power.  Note
17164                // its current wake lock time to later know to kill it if
17165                // it is not behaving well.
17166                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17167                synchronized (stats) {
17168                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17169                            app.pid, SystemClock.elapsedRealtime());
17170                }
17171                app.lastCpuTime = app.curCpuTime;
17172
17173            }
17174            app.setProcState = app.curProcState;
17175            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17176                app.notCachedSinceIdle = false;
17177            }
17178            if (!doingAll) {
17179                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17180            } else {
17181                app.procStateChanged = true;
17182            }
17183        }
17184
17185        if (changes != 0) {
17186            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17187            int i = mPendingProcessChanges.size()-1;
17188            ProcessChangeItem item = null;
17189            while (i >= 0) {
17190                item = mPendingProcessChanges.get(i);
17191                if (item.pid == app.pid) {
17192                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17193                    break;
17194                }
17195                i--;
17196            }
17197            if (i < 0) {
17198                // No existing item in pending changes; need a new one.
17199                final int NA = mAvailProcessChanges.size();
17200                if (NA > 0) {
17201                    item = mAvailProcessChanges.remove(NA-1);
17202                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17203                } else {
17204                    item = new ProcessChangeItem();
17205                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17206                }
17207                item.changes = 0;
17208                item.pid = app.pid;
17209                item.uid = app.info.uid;
17210                if (mPendingProcessChanges.size() == 0) {
17211                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17212                            "*** Enqueueing dispatch processes changed!");
17213                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17214                }
17215                mPendingProcessChanges.add(item);
17216            }
17217            item.changes |= changes;
17218            item.processState = app.repProcState;
17219            item.foregroundActivities = app.repForegroundActivities;
17220            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17221                    + Integer.toHexString(System.identityHashCode(item))
17222                    + " " + app.toShortString() + ": changes=" + item.changes
17223                    + " procState=" + item.processState
17224                    + " foreground=" + item.foregroundActivities
17225                    + " type=" + app.adjType + " source=" + app.adjSource
17226                    + " target=" + app.adjTarget);
17227        }
17228
17229        return success;
17230    }
17231
17232    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17233        if (proc.thread != null) {
17234            if (proc.baseProcessTracker != null) {
17235                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17236            }
17237            if (proc.repProcState >= 0) {
17238                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17239                        proc.repProcState);
17240            }
17241        }
17242    }
17243
17244    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17245            ProcessRecord TOP_APP, boolean doingAll, long now) {
17246        if (app.thread == null) {
17247            return false;
17248        }
17249
17250        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17251
17252        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17253    }
17254
17255    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17256            boolean oomAdj) {
17257        if (isForeground != proc.foregroundServices) {
17258            proc.foregroundServices = isForeground;
17259            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17260                    proc.info.uid);
17261            if (isForeground) {
17262                if (curProcs == null) {
17263                    curProcs = new ArrayList<ProcessRecord>();
17264                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17265                }
17266                if (!curProcs.contains(proc)) {
17267                    curProcs.add(proc);
17268                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17269                            proc.info.packageName, proc.info.uid);
17270                }
17271            } else {
17272                if (curProcs != null) {
17273                    if (curProcs.remove(proc)) {
17274                        mBatteryStatsService.noteEvent(
17275                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17276                                proc.info.packageName, proc.info.uid);
17277                        if (curProcs.size() <= 0) {
17278                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17279                        }
17280                    }
17281                }
17282            }
17283            if (oomAdj) {
17284                updateOomAdjLocked();
17285            }
17286        }
17287    }
17288
17289    private final ActivityRecord resumedAppLocked() {
17290        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17291        String pkg;
17292        int uid;
17293        if (act != null) {
17294            pkg = act.packageName;
17295            uid = act.info.applicationInfo.uid;
17296        } else {
17297            pkg = null;
17298            uid = -1;
17299        }
17300        // Has the UID or resumed package name changed?
17301        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17302                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17303            if (mCurResumedPackage != null) {
17304                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17305                        mCurResumedPackage, mCurResumedUid);
17306            }
17307            mCurResumedPackage = pkg;
17308            mCurResumedUid = uid;
17309            if (mCurResumedPackage != null) {
17310                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17311                        mCurResumedPackage, mCurResumedUid);
17312            }
17313        }
17314        return act;
17315    }
17316
17317    final boolean updateOomAdjLocked(ProcessRecord app) {
17318        final ActivityRecord TOP_ACT = resumedAppLocked();
17319        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17320        final boolean wasCached = app.cached;
17321
17322        mAdjSeq++;
17323
17324        // This is the desired cached adjusment we want to tell it to use.
17325        // If our app is currently cached, we know it, and that is it.  Otherwise,
17326        // we don't know it yet, and it needs to now be cached we will then
17327        // need to do a complete oom adj.
17328        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17329                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17330        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17331                SystemClock.uptimeMillis());
17332        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17333            // Changed to/from cached state, so apps after it in the LRU
17334            // list may also be changed.
17335            updateOomAdjLocked();
17336        }
17337        return success;
17338    }
17339
17340    final void updateOomAdjLocked() {
17341        final ActivityRecord TOP_ACT = resumedAppLocked();
17342        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17343        final long now = SystemClock.uptimeMillis();
17344        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17345        final int N = mLruProcesses.size();
17346
17347        if (false) {
17348            RuntimeException e = new RuntimeException();
17349            e.fillInStackTrace();
17350            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17351        }
17352
17353        mAdjSeq++;
17354        mNewNumServiceProcs = 0;
17355        mNewNumAServiceProcs = 0;
17356
17357        final int emptyProcessLimit;
17358        final int cachedProcessLimit;
17359        if (mProcessLimit <= 0) {
17360            emptyProcessLimit = cachedProcessLimit = 0;
17361        } else if (mProcessLimit == 1) {
17362            emptyProcessLimit = 1;
17363            cachedProcessLimit = 0;
17364        } else {
17365            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17366            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17367        }
17368
17369        // Let's determine how many processes we have running vs.
17370        // how many slots we have for background processes; we may want
17371        // to put multiple processes in a slot of there are enough of
17372        // them.
17373        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17374                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17375        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17376        if (numEmptyProcs > cachedProcessLimit) {
17377            // If there are more empty processes than our limit on cached
17378            // processes, then use the cached process limit for the factor.
17379            // This ensures that the really old empty processes get pushed
17380            // down to the bottom, so if we are running low on memory we will
17381            // have a better chance at keeping around more cached processes
17382            // instead of a gazillion empty processes.
17383            numEmptyProcs = cachedProcessLimit;
17384        }
17385        int emptyFactor = numEmptyProcs/numSlots;
17386        if (emptyFactor < 1) emptyFactor = 1;
17387        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17388        if (cachedFactor < 1) cachedFactor = 1;
17389        int stepCached = 0;
17390        int stepEmpty = 0;
17391        int numCached = 0;
17392        int numEmpty = 0;
17393        int numTrimming = 0;
17394
17395        mNumNonCachedProcs = 0;
17396        mNumCachedHiddenProcs = 0;
17397
17398        // First update the OOM adjustment for each of the
17399        // application processes based on their current state.
17400        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17401        int nextCachedAdj = curCachedAdj+1;
17402        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17403        int nextEmptyAdj = curEmptyAdj+2;
17404        for (int i=N-1; i>=0; i--) {
17405            ProcessRecord app = mLruProcesses.get(i);
17406            if (!app.killedByAm && app.thread != null) {
17407                app.procStateChanged = false;
17408                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17409
17410                // If we haven't yet assigned the final cached adj
17411                // to the process, do that now.
17412                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17413                    switch (app.curProcState) {
17414                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17415                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17416                            // This process is a cached process holding activities...
17417                            // assign it the next cached value for that type, and then
17418                            // step that cached level.
17419                            app.curRawAdj = curCachedAdj;
17420                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17421                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17422                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17423                                    + ")");
17424                            if (curCachedAdj != nextCachedAdj) {
17425                                stepCached++;
17426                                if (stepCached >= cachedFactor) {
17427                                    stepCached = 0;
17428                                    curCachedAdj = nextCachedAdj;
17429                                    nextCachedAdj += 2;
17430                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17431                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17432                                    }
17433                                }
17434                            }
17435                            break;
17436                        default:
17437                            // For everything else, assign next empty cached process
17438                            // level and bump that up.  Note that this means that
17439                            // long-running services that have dropped down to the
17440                            // cached level will be treated as empty (since their process
17441                            // state is still as a service), which is what we want.
17442                            app.curRawAdj = curEmptyAdj;
17443                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17444                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17445                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17446                                    + ")");
17447                            if (curEmptyAdj != nextEmptyAdj) {
17448                                stepEmpty++;
17449                                if (stepEmpty >= emptyFactor) {
17450                                    stepEmpty = 0;
17451                                    curEmptyAdj = nextEmptyAdj;
17452                                    nextEmptyAdj += 2;
17453                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17454                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17455                                    }
17456                                }
17457                            }
17458                            break;
17459                    }
17460                }
17461
17462                applyOomAdjLocked(app, TOP_APP, true, now);
17463
17464                // Count the number of process types.
17465                switch (app.curProcState) {
17466                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17467                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17468                        mNumCachedHiddenProcs++;
17469                        numCached++;
17470                        if (numCached > cachedProcessLimit) {
17471                            app.kill("cached #" + numCached, true);
17472                        }
17473                        break;
17474                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17475                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17476                                && app.lastActivityTime < oldTime) {
17477                            app.kill("empty for "
17478                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17479                                    / 1000) + "s", true);
17480                        } else {
17481                            numEmpty++;
17482                            if (numEmpty > emptyProcessLimit) {
17483                                app.kill("empty #" + numEmpty, true);
17484                            }
17485                        }
17486                        break;
17487                    default:
17488                        mNumNonCachedProcs++;
17489                        break;
17490                }
17491
17492                if (app.isolated && app.services.size() <= 0) {
17493                    // If this is an isolated process, and there are no
17494                    // services running in it, then the process is no longer
17495                    // needed.  We agressively kill these because we can by
17496                    // definition not re-use the same process again, and it is
17497                    // good to avoid having whatever code was running in them
17498                    // left sitting around after no longer needed.
17499                    app.kill("isolated not needed", true);
17500                }
17501
17502                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17503                        && !app.killedByAm) {
17504                    numTrimming++;
17505                }
17506            }
17507        }
17508
17509        mNumServiceProcs = mNewNumServiceProcs;
17510
17511        // Now determine the memory trimming level of background processes.
17512        // Unfortunately we need to start at the back of the list to do this
17513        // properly.  We only do this if the number of background apps we
17514        // are managing to keep around is less than half the maximum we desire;
17515        // if we are keeping a good number around, we'll let them use whatever
17516        // memory they want.
17517        final int numCachedAndEmpty = numCached + numEmpty;
17518        int memFactor;
17519        if (numCached <= ProcessList.TRIM_CACHED_APPS
17520                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17521            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17522                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17523            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17524                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17525            } else {
17526                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17527            }
17528        } else {
17529            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17530        }
17531        // We always allow the memory level to go up (better).  We only allow it to go
17532        // down if we are in a state where that is allowed, *and* the total number of processes
17533        // has gone down since last time.
17534        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17535                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17536                + " last=" + mLastNumProcesses);
17537        if (memFactor > mLastMemoryLevel) {
17538            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17539                memFactor = mLastMemoryLevel;
17540                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17541            }
17542        }
17543        mLastMemoryLevel = memFactor;
17544        mLastNumProcesses = mLruProcesses.size();
17545        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17546        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17547        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17548            if (mLowRamStartTime == 0) {
17549                mLowRamStartTime = now;
17550            }
17551            int step = 0;
17552            int fgTrimLevel;
17553            switch (memFactor) {
17554                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17555                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17556                    break;
17557                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17558                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17559                    break;
17560                default:
17561                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17562                    break;
17563            }
17564            int factor = numTrimming/3;
17565            int minFactor = 2;
17566            if (mHomeProcess != null) minFactor++;
17567            if (mPreviousProcess != null) minFactor++;
17568            if (factor < minFactor) factor = minFactor;
17569            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17570            for (int i=N-1; i>=0; i--) {
17571                ProcessRecord app = mLruProcesses.get(i);
17572                if (allChanged || app.procStateChanged) {
17573                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17574                    app.procStateChanged = false;
17575                }
17576                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17577                        && !app.killedByAm) {
17578                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17579                        try {
17580                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17581                                    "Trimming memory of " + app.processName
17582                                    + " to " + curLevel);
17583                            app.thread.scheduleTrimMemory(curLevel);
17584                        } catch (RemoteException e) {
17585                        }
17586                        if (false) {
17587                            // For now we won't do this; our memory trimming seems
17588                            // to be good enough at this point that destroying
17589                            // activities causes more harm than good.
17590                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17591                                    && app != mHomeProcess && app != mPreviousProcess) {
17592                                // Need to do this on its own message because the stack may not
17593                                // be in a consistent state at this point.
17594                                // For these apps we will also finish their activities
17595                                // to help them free memory.
17596                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17597                            }
17598                        }
17599                    }
17600                    app.trimMemoryLevel = curLevel;
17601                    step++;
17602                    if (step >= factor) {
17603                        step = 0;
17604                        switch (curLevel) {
17605                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17606                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17607                                break;
17608                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17609                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17610                                break;
17611                        }
17612                    }
17613                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17614                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17615                            && app.thread != null) {
17616                        try {
17617                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17618                                    "Trimming memory of heavy-weight " + app.processName
17619                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17620                            app.thread.scheduleTrimMemory(
17621                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17622                        } catch (RemoteException e) {
17623                        }
17624                    }
17625                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17626                } else {
17627                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17628                            || app.systemNoUi) && app.pendingUiClean) {
17629                        // If this application is now in the background and it
17630                        // had done UI, then give it the special trim level to
17631                        // have it free UI resources.
17632                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17633                        if (app.trimMemoryLevel < level && app.thread != null) {
17634                            try {
17635                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17636                                        "Trimming memory of bg-ui " + app.processName
17637                                        + " to " + level);
17638                                app.thread.scheduleTrimMemory(level);
17639                            } catch (RemoteException e) {
17640                            }
17641                        }
17642                        app.pendingUiClean = false;
17643                    }
17644                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17645                        try {
17646                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17647                                    "Trimming memory of fg " + app.processName
17648                                    + " to " + fgTrimLevel);
17649                            app.thread.scheduleTrimMemory(fgTrimLevel);
17650                        } catch (RemoteException e) {
17651                        }
17652                    }
17653                    app.trimMemoryLevel = fgTrimLevel;
17654                }
17655            }
17656        } else {
17657            if (mLowRamStartTime != 0) {
17658                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17659                mLowRamStartTime = 0;
17660            }
17661            for (int i=N-1; i>=0; i--) {
17662                ProcessRecord app = mLruProcesses.get(i);
17663                if (allChanged || app.procStateChanged) {
17664                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17665                    app.procStateChanged = false;
17666                }
17667                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17668                        || app.systemNoUi) && app.pendingUiClean) {
17669                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17670                            && app.thread != null) {
17671                        try {
17672                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17673                                    "Trimming memory of ui hidden " + app.processName
17674                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17675                            app.thread.scheduleTrimMemory(
17676                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17677                        } catch (RemoteException e) {
17678                        }
17679                    }
17680                    app.pendingUiClean = false;
17681                }
17682                app.trimMemoryLevel = 0;
17683            }
17684        }
17685
17686        if (mAlwaysFinishActivities) {
17687            // Need to do this on its own message because the stack may not
17688            // be in a consistent state at this point.
17689            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17690        }
17691
17692        if (allChanged) {
17693            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17694        }
17695
17696        if (mProcessStats.shouldWriteNowLocked(now)) {
17697            mHandler.post(new Runnable() {
17698                @Override public void run() {
17699                    synchronized (ActivityManagerService.this) {
17700                        mProcessStats.writeStateAsyncLocked();
17701                    }
17702                }
17703            });
17704        }
17705
17706        if (DEBUG_OOM_ADJ) {
17707            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17708        }
17709    }
17710
17711    final void trimApplications() {
17712        synchronized (this) {
17713            int i;
17714
17715            // First remove any unused application processes whose package
17716            // has been removed.
17717            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17718                final ProcessRecord app = mRemovedProcesses.get(i);
17719                if (app.activities.size() == 0
17720                        && app.curReceiver == null && app.services.size() == 0) {
17721                    Slog.i(
17722                        TAG, "Exiting empty application process "
17723                        + app.processName + " ("
17724                        + (app.thread != null ? app.thread.asBinder() : null)
17725                        + ")\n");
17726                    if (app.pid > 0 && app.pid != MY_PID) {
17727                        app.kill("empty", false);
17728                    } else {
17729                        try {
17730                            app.thread.scheduleExit();
17731                        } catch (Exception e) {
17732                            // Ignore exceptions.
17733                        }
17734                    }
17735                    cleanUpApplicationRecordLocked(app, false, true, -1);
17736                    mRemovedProcesses.remove(i);
17737
17738                    if (app.persistent) {
17739                        addAppLocked(app.info, false, null /* ABI override */);
17740                    }
17741                }
17742            }
17743
17744            // Now update the oom adj for all processes.
17745            updateOomAdjLocked();
17746        }
17747    }
17748
17749    /** This method sends the specified signal to each of the persistent apps */
17750    public void signalPersistentProcesses(int sig) throws RemoteException {
17751        if (sig != Process.SIGNAL_USR1) {
17752            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17753        }
17754
17755        synchronized (this) {
17756            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17757                    != PackageManager.PERMISSION_GRANTED) {
17758                throw new SecurityException("Requires permission "
17759                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17760            }
17761
17762            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17763                ProcessRecord r = mLruProcesses.get(i);
17764                if (r.thread != null && r.persistent) {
17765                    Process.sendSignal(r.pid, sig);
17766                }
17767            }
17768        }
17769    }
17770
17771    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17772        if (proc == null || proc == mProfileProc) {
17773            proc = mProfileProc;
17774            profileType = mProfileType;
17775            clearProfilerLocked();
17776        }
17777        if (proc == null) {
17778            return;
17779        }
17780        try {
17781            proc.thread.profilerControl(false, null, profileType);
17782        } catch (RemoteException e) {
17783            throw new IllegalStateException("Process disappeared");
17784        }
17785    }
17786
17787    private void clearProfilerLocked() {
17788        if (mProfileFd != null) {
17789            try {
17790                mProfileFd.close();
17791            } catch (IOException e) {
17792            }
17793        }
17794        mProfileApp = null;
17795        mProfileProc = null;
17796        mProfileFile = null;
17797        mProfileType = 0;
17798        mAutoStopProfiler = false;
17799        mSamplingInterval = 0;
17800    }
17801
17802    public boolean profileControl(String process, int userId, boolean start,
17803            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17804
17805        try {
17806            synchronized (this) {
17807                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17808                // its own permission.
17809                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17810                        != PackageManager.PERMISSION_GRANTED) {
17811                    throw new SecurityException("Requires permission "
17812                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17813                }
17814
17815                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17816                    throw new IllegalArgumentException("null profile info or fd");
17817                }
17818
17819                ProcessRecord proc = null;
17820                if (process != null) {
17821                    proc = findProcessLocked(process, userId, "profileControl");
17822                }
17823
17824                if (start && (proc == null || proc.thread == null)) {
17825                    throw new IllegalArgumentException("Unknown process: " + process);
17826                }
17827
17828                if (start) {
17829                    stopProfilerLocked(null, 0);
17830                    setProfileApp(proc.info, proc.processName, profilerInfo);
17831                    mProfileProc = proc;
17832                    mProfileType = profileType;
17833                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17834                    try {
17835                        fd = fd.dup();
17836                    } catch (IOException e) {
17837                        fd = null;
17838                    }
17839                    profilerInfo.profileFd = fd;
17840                    proc.thread.profilerControl(start, profilerInfo, profileType);
17841                    fd = null;
17842                    mProfileFd = null;
17843                } else {
17844                    stopProfilerLocked(proc, profileType);
17845                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17846                        try {
17847                            profilerInfo.profileFd.close();
17848                        } catch (IOException e) {
17849                        }
17850                    }
17851                }
17852
17853                return true;
17854            }
17855        } catch (RemoteException e) {
17856            throw new IllegalStateException("Process disappeared");
17857        } finally {
17858            if (profilerInfo != null && profilerInfo.profileFd != null) {
17859                try {
17860                    profilerInfo.profileFd.close();
17861                } catch (IOException e) {
17862                }
17863            }
17864        }
17865    }
17866
17867    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17868        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17869                userId, true, ALLOW_FULL_ONLY, callName, null);
17870        ProcessRecord proc = null;
17871        try {
17872            int pid = Integer.parseInt(process);
17873            synchronized (mPidsSelfLocked) {
17874                proc = mPidsSelfLocked.get(pid);
17875            }
17876        } catch (NumberFormatException e) {
17877        }
17878
17879        if (proc == null) {
17880            ArrayMap<String, SparseArray<ProcessRecord>> all
17881                    = mProcessNames.getMap();
17882            SparseArray<ProcessRecord> procs = all.get(process);
17883            if (procs != null && procs.size() > 0) {
17884                proc = procs.valueAt(0);
17885                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17886                    for (int i=1; i<procs.size(); i++) {
17887                        ProcessRecord thisProc = procs.valueAt(i);
17888                        if (thisProc.userId == userId) {
17889                            proc = thisProc;
17890                            break;
17891                        }
17892                    }
17893                }
17894            }
17895        }
17896
17897        return proc;
17898    }
17899
17900    public boolean dumpHeap(String process, int userId, boolean managed,
17901            String path, ParcelFileDescriptor fd) throws RemoteException {
17902
17903        try {
17904            synchronized (this) {
17905                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17906                // its own permission (same as profileControl).
17907                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17908                        != PackageManager.PERMISSION_GRANTED) {
17909                    throw new SecurityException("Requires permission "
17910                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17911                }
17912
17913                if (fd == null) {
17914                    throw new IllegalArgumentException("null fd");
17915                }
17916
17917                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17918                if (proc == null || proc.thread == null) {
17919                    throw new IllegalArgumentException("Unknown process: " + process);
17920                }
17921
17922                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17923                if (!isDebuggable) {
17924                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17925                        throw new SecurityException("Process not debuggable: " + proc);
17926                    }
17927                }
17928
17929                proc.thread.dumpHeap(managed, path, fd);
17930                fd = null;
17931                return true;
17932            }
17933        } catch (RemoteException e) {
17934            throw new IllegalStateException("Process disappeared");
17935        } finally {
17936            if (fd != null) {
17937                try {
17938                    fd.close();
17939                } catch (IOException e) {
17940                }
17941            }
17942        }
17943    }
17944
17945    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17946    public void monitor() {
17947        synchronized (this) { }
17948    }
17949
17950    void onCoreSettingsChange(Bundle settings) {
17951        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17952            ProcessRecord processRecord = mLruProcesses.get(i);
17953            try {
17954                if (processRecord.thread != null) {
17955                    processRecord.thread.setCoreSettings(settings);
17956                }
17957            } catch (RemoteException re) {
17958                /* ignore */
17959            }
17960        }
17961    }
17962
17963    // Multi-user methods
17964
17965    /**
17966     * Start user, if its not already running, but don't bring it to foreground.
17967     */
17968    @Override
17969    public boolean startUserInBackground(final int userId) {
17970        return startUser(userId, /* foreground */ false);
17971    }
17972
17973    /**
17974     * Start user, if its not already running, and bring it to foreground.
17975     */
17976    boolean startUserInForeground(final int userId, Dialog dlg) {
17977        boolean result = startUser(userId, /* foreground */ true);
17978        dlg.dismiss();
17979        return result;
17980    }
17981
17982    /**
17983     * Refreshes the list of users related to the current user when either a
17984     * user switch happens or when a new related user is started in the
17985     * background.
17986     */
17987    private void updateCurrentProfileIdsLocked() {
17988        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17989                mCurrentUserId, false /* enabledOnly */);
17990        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17991        for (int i = 0; i < currentProfileIds.length; i++) {
17992            currentProfileIds[i] = profiles.get(i).id;
17993        }
17994        mCurrentProfileIds = currentProfileIds;
17995
17996        synchronized (mUserProfileGroupIdsSelfLocked) {
17997            mUserProfileGroupIdsSelfLocked.clear();
17998            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17999            for (int i = 0; i < users.size(); i++) {
18000                UserInfo user = users.get(i);
18001                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18002                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18003                }
18004            }
18005        }
18006    }
18007
18008    private Set getProfileIdsLocked(int userId) {
18009        Set userIds = new HashSet<Integer>();
18010        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18011                userId, false /* enabledOnly */);
18012        for (UserInfo user : profiles) {
18013            userIds.add(Integer.valueOf(user.id));
18014        }
18015        return userIds;
18016    }
18017
18018    @Override
18019    public boolean switchUser(final int userId) {
18020        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18021        String userName;
18022        synchronized (this) {
18023            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18024            if (userInfo == null) {
18025                Slog.w(TAG, "No user info for user #" + userId);
18026                return false;
18027            }
18028            if (userInfo.isManagedProfile()) {
18029                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18030                return false;
18031            }
18032            userName = userInfo.name;
18033            mTargetUserId = userId;
18034        }
18035        mHandler.removeMessages(START_USER_SWITCH_MSG);
18036        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18037        return true;
18038    }
18039
18040    private void showUserSwitchDialog(int userId, String userName) {
18041        // The dialog will show and then initiate the user switch by calling startUserInForeground
18042        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18043                true /* above system */);
18044        d.show();
18045    }
18046
18047    private boolean startUser(final int userId, final boolean foreground) {
18048        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18049                != PackageManager.PERMISSION_GRANTED) {
18050            String msg = "Permission Denial: switchUser() from pid="
18051                    + Binder.getCallingPid()
18052                    + ", uid=" + Binder.getCallingUid()
18053                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18054            Slog.w(TAG, msg);
18055            throw new SecurityException(msg);
18056        }
18057
18058        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18059
18060        final long ident = Binder.clearCallingIdentity();
18061        try {
18062            synchronized (this) {
18063                final int oldUserId = mCurrentUserId;
18064                if (oldUserId == userId) {
18065                    return true;
18066                }
18067
18068                mStackSupervisor.setLockTaskModeLocked(null, false);
18069
18070                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18071                if (userInfo == null) {
18072                    Slog.w(TAG, "No user info for user #" + userId);
18073                    return false;
18074                }
18075                if (foreground && userInfo.isManagedProfile()) {
18076                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18077                    return false;
18078                }
18079
18080                if (foreground) {
18081                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18082                            R.anim.screen_user_enter);
18083                }
18084
18085                boolean needStart = false;
18086
18087                // If the user we are switching to is not currently started, then
18088                // we need to start it now.
18089                if (mStartedUsers.get(userId) == null) {
18090                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18091                    updateStartedUserArrayLocked();
18092                    needStart = true;
18093                }
18094
18095                final Integer userIdInt = Integer.valueOf(userId);
18096                mUserLru.remove(userIdInt);
18097                mUserLru.add(userIdInt);
18098
18099                if (foreground) {
18100                    mCurrentUserId = userId;
18101                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18102                    updateCurrentProfileIdsLocked();
18103                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18104                    // Once the internal notion of the active user has switched, we lock the device
18105                    // with the option to show the user switcher on the keyguard.
18106                    mWindowManager.lockNow(null);
18107                } else {
18108                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18109                    updateCurrentProfileIdsLocked();
18110                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18111                    mUserLru.remove(currentUserIdInt);
18112                    mUserLru.add(currentUserIdInt);
18113                }
18114
18115                final UserStartedState uss = mStartedUsers.get(userId);
18116
18117                // Make sure user is in the started state.  If it is currently
18118                // stopping, we need to knock that off.
18119                if (uss.mState == UserStartedState.STATE_STOPPING) {
18120                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18121                    // so we can just fairly silently bring the user back from
18122                    // the almost-dead.
18123                    uss.mState = UserStartedState.STATE_RUNNING;
18124                    updateStartedUserArrayLocked();
18125                    needStart = true;
18126                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18127                    // This means ACTION_SHUTDOWN has been sent, so we will
18128                    // need to treat this as a new boot of the user.
18129                    uss.mState = UserStartedState.STATE_BOOTING;
18130                    updateStartedUserArrayLocked();
18131                    needStart = true;
18132                }
18133
18134                if (uss.mState == UserStartedState.STATE_BOOTING) {
18135                    // Booting up a new user, need to tell system services about it.
18136                    // Note that this is on the same handler as scheduling of broadcasts,
18137                    // which is important because it needs to go first.
18138                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18139                }
18140
18141                if (foreground) {
18142                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18143                            oldUserId));
18144                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18145                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18146                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18147                            oldUserId, userId, uss));
18148                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18149                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18150                }
18151
18152                if (needStart) {
18153                    // Send USER_STARTED broadcast
18154                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18155                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18156                            | Intent.FLAG_RECEIVER_FOREGROUND);
18157                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18158                    broadcastIntentLocked(null, null, intent,
18159                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18160                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18161                }
18162
18163                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18164                    if (userId != UserHandle.USER_OWNER) {
18165                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18166                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18167                        broadcastIntentLocked(null, null, intent, null,
18168                                new IIntentReceiver.Stub() {
18169                                    public void performReceive(Intent intent, int resultCode,
18170                                            String data, Bundle extras, boolean ordered,
18171                                            boolean sticky, int sendingUser) {
18172                                        onUserInitialized(uss, foreground, oldUserId, userId);
18173                                    }
18174                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18175                                true, false, MY_PID, Process.SYSTEM_UID,
18176                                userId);
18177                        uss.initializing = true;
18178                    } else {
18179                        getUserManagerLocked().makeInitialized(userInfo.id);
18180                    }
18181                }
18182
18183                if (foreground) {
18184                    if (!uss.initializing) {
18185                        moveUserToForeground(uss, oldUserId, userId);
18186                    }
18187                } else {
18188                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18189                }
18190
18191                if (needStart) {
18192                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18193                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18194                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18195                    broadcastIntentLocked(null, null, intent,
18196                            null, new IIntentReceiver.Stub() {
18197                                @Override
18198                                public void performReceive(Intent intent, int resultCode, String data,
18199                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18200                                        throws RemoteException {
18201                                }
18202                            }, 0, null, null,
18203                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18204                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18205                }
18206            }
18207        } finally {
18208            Binder.restoreCallingIdentity(ident);
18209        }
18210
18211        return true;
18212    }
18213
18214    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18215        long ident = Binder.clearCallingIdentity();
18216        try {
18217            Intent intent;
18218            if (oldUserId >= 0) {
18219                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18220                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18221                int count = profiles.size();
18222                for (int i = 0; i < count; i++) {
18223                    int profileUserId = profiles.get(i).id;
18224                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18225                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18226                            | Intent.FLAG_RECEIVER_FOREGROUND);
18227                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18228                    broadcastIntentLocked(null, null, intent,
18229                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18230                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18231                }
18232            }
18233            if (newUserId >= 0) {
18234                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18235                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18236                int count = profiles.size();
18237                for (int i = 0; i < count; i++) {
18238                    int profileUserId = profiles.get(i).id;
18239                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18240                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18241                            | Intent.FLAG_RECEIVER_FOREGROUND);
18242                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18243                    broadcastIntentLocked(null, null, intent,
18244                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18245                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18246                }
18247                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18248                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18249                        | Intent.FLAG_RECEIVER_FOREGROUND);
18250                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18251                broadcastIntentLocked(null, null, intent,
18252                        null, null, 0, null, null,
18253                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18254                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18255            }
18256        } finally {
18257            Binder.restoreCallingIdentity(ident);
18258        }
18259    }
18260
18261    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18262            final int newUserId) {
18263        final int N = mUserSwitchObservers.beginBroadcast();
18264        if (N > 0) {
18265            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18266                int mCount = 0;
18267                @Override
18268                public void sendResult(Bundle data) throws RemoteException {
18269                    synchronized (ActivityManagerService.this) {
18270                        if (mCurUserSwitchCallback == this) {
18271                            mCount++;
18272                            if (mCount == N) {
18273                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18274                            }
18275                        }
18276                    }
18277                }
18278            };
18279            synchronized (this) {
18280                uss.switching = true;
18281                mCurUserSwitchCallback = callback;
18282            }
18283            for (int i=0; i<N; i++) {
18284                try {
18285                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18286                            newUserId, callback);
18287                } catch (RemoteException e) {
18288                }
18289            }
18290        } else {
18291            synchronized (this) {
18292                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18293            }
18294        }
18295        mUserSwitchObservers.finishBroadcast();
18296    }
18297
18298    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18299        synchronized (this) {
18300            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18301            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18302        }
18303    }
18304
18305    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18306        mCurUserSwitchCallback = null;
18307        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18308        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18309                oldUserId, newUserId, uss));
18310    }
18311
18312    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18313        synchronized (this) {
18314            if (foreground) {
18315                moveUserToForeground(uss, oldUserId, newUserId);
18316            }
18317        }
18318
18319        completeSwitchAndInitalize(uss, newUserId, true, false);
18320    }
18321
18322    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18323        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18324        if (homeInFront) {
18325            startHomeActivityLocked(newUserId);
18326        } else {
18327            mStackSupervisor.resumeTopActivitiesLocked();
18328        }
18329        EventLogTags.writeAmSwitchUser(newUserId);
18330        getUserManagerLocked().userForeground(newUserId);
18331        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18332    }
18333
18334    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18335        completeSwitchAndInitalize(uss, newUserId, false, true);
18336    }
18337
18338    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18339            boolean clearInitializing, boolean clearSwitching) {
18340        boolean unfrozen = false;
18341        synchronized (this) {
18342            if (clearInitializing) {
18343                uss.initializing = false;
18344                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18345            }
18346            if (clearSwitching) {
18347                uss.switching = false;
18348            }
18349            if (!uss.switching && !uss.initializing) {
18350                mWindowManager.stopFreezingScreen();
18351                unfrozen = true;
18352            }
18353        }
18354        if (unfrozen) {
18355            final int N = mUserSwitchObservers.beginBroadcast();
18356            for (int i=0; i<N; i++) {
18357                try {
18358                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18359                } catch (RemoteException e) {
18360                }
18361            }
18362            mUserSwitchObservers.finishBroadcast();
18363        }
18364    }
18365
18366    void scheduleStartProfilesLocked() {
18367        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18368            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18369                    DateUtils.SECOND_IN_MILLIS);
18370        }
18371    }
18372
18373    void startProfilesLocked() {
18374        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18375        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18376                mCurrentUserId, false /* enabledOnly */);
18377        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18378        for (UserInfo user : profiles) {
18379            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18380                    && user.id != mCurrentUserId) {
18381                toStart.add(user);
18382            }
18383        }
18384        final int n = toStart.size();
18385        int i = 0;
18386        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18387            startUserInBackground(toStart.get(i).id);
18388        }
18389        if (i < n) {
18390            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18391        }
18392    }
18393
18394    void finishUserBoot(UserStartedState uss) {
18395        synchronized (this) {
18396            if (uss.mState == UserStartedState.STATE_BOOTING
18397                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18398                uss.mState = UserStartedState.STATE_RUNNING;
18399                final int userId = uss.mHandle.getIdentifier();
18400                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18401                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18402                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18403                broadcastIntentLocked(null, null, intent,
18404                        null, null, 0, null, null,
18405                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18406                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18407            }
18408        }
18409    }
18410
18411    void finishUserSwitch(UserStartedState uss) {
18412        synchronized (this) {
18413            finishUserBoot(uss);
18414
18415            startProfilesLocked();
18416
18417            int num = mUserLru.size();
18418            int i = 0;
18419            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18420                Integer oldUserId = mUserLru.get(i);
18421                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18422                if (oldUss == null) {
18423                    // Shouldn't happen, but be sane if it does.
18424                    mUserLru.remove(i);
18425                    num--;
18426                    continue;
18427                }
18428                if (oldUss.mState == UserStartedState.STATE_STOPPING
18429                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18430                    // This user is already stopping, doesn't count.
18431                    num--;
18432                    i++;
18433                    continue;
18434                }
18435                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18436                    // Owner and current can't be stopped, but count as running.
18437                    i++;
18438                    continue;
18439                }
18440                // This is a user to be stopped.
18441                stopUserLocked(oldUserId, null);
18442                num--;
18443                i++;
18444            }
18445        }
18446    }
18447
18448    @Override
18449    public int stopUser(final int userId, final IStopUserCallback callback) {
18450        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18451                != PackageManager.PERMISSION_GRANTED) {
18452            String msg = "Permission Denial: switchUser() from pid="
18453                    + Binder.getCallingPid()
18454                    + ", uid=" + Binder.getCallingUid()
18455                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18456            Slog.w(TAG, msg);
18457            throw new SecurityException(msg);
18458        }
18459        if (userId <= 0) {
18460            throw new IllegalArgumentException("Can't stop primary user " + userId);
18461        }
18462        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18463        synchronized (this) {
18464            return stopUserLocked(userId, callback);
18465        }
18466    }
18467
18468    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18469        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18470        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18471            return ActivityManager.USER_OP_IS_CURRENT;
18472        }
18473
18474        final UserStartedState uss = mStartedUsers.get(userId);
18475        if (uss == null) {
18476            // User is not started, nothing to do...  but we do need to
18477            // callback if requested.
18478            if (callback != null) {
18479                mHandler.post(new Runnable() {
18480                    @Override
18481                    public void run() {
18482                        try {
18483                            callback.userStopped(userId);
18484                        } catch (RemoteException e) {
18485                        }
18486                    }
18487                });
18488            }
18489            return ActivityManager.USER_OP_SUCCESS;
18490        }
18491
18492        if (callback != null) {
18493            uss.mStopCallbacks.add(callback);
18494        }
18495
18496        if (uss.mState != UserStartedState.STATE_STOPPING
18497                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18498            uss.mState = UserStartedState.STATE_STOPPING;
18499            updateStartedUserArrayLocked();
18500
18501            long ident = Binder.clearCallingIdentity();
18502            try {
18503                // We are going to broadcast ACTION_USER_STOPPING and then
18504                // once that is done send a final ACTION_SHUTDOWN and then
18505                // stop the user.
18506                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18507                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18508                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18509                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18510                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18511                // This is the result receiver for the final shutdown broadcast.
18512                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18513                    @Override
18514                    public void performReceive(Intent intent, int resultCode, String data,
18515                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18516                        finishUserStop(uss);
18517                    }
18518                };
18519                // This is the result receiver for the initial stopping broadcast.
18520                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18521                    @Override
18522                    public void performReceive(Intent intent, int resultCode, String data,
18523                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18524                        // On to the next.
18525                        synchronized (ActivityManagerService.this) {
18526                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18527                                // Whoops, we are being started back up.  Abort, abort!
18528                                return;
18529                            }
18530                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18531                        }
18532                        mBatteryStatsService.noteEvent(
18533                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18534                                Integer.toString(userId), userId);
18535                        mSystemServiceManager.stopUser(userId);
18536                        broadcastIntentLocked(null, null, shutdownIntent,
18537                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18538                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18539                    }
18540                };
18541                // Kick things off.
18542                broadcastIntentLocked(null, null, stoppingIntent,
18543                        null, stoppingReceiver, 0, null, null,
18544                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18545                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18546            } finally {
18547                Binder.restoreCallingIdentity(ident);
18548            }
18549        }
18550
18551        return ActivityManager.USER_OP_SUCCESS;
18552    }
18553
18554    void finishUserStop(UserStartedState uss) {
18555        final int userId = uss.mHandle.getIdentifier();
18556        boolean stopped;
18557        ArrayList<IStopUserCallback> callbacks;
18558        synchronized (this) {
18559            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18560            if (mStartedUsers.get(userId) != uss) {
18561                stopped = false;
18562            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18563                stopped = false;
18564            } else {
18565                stopped = true;
18566                // User can no longer run.
18567                mStartedUsers.remove(userId);
18568                mUserLru.remove(Integer.valueOf(userId));
18569                updateStartedUserArrayLocked();
18570
18571                // Clean up all state and processes associated with the user.
18572                // Kill all the processes for the user.
18573                forceStopUserLocked(userId, "finish user");
18574            }
18575
18576            // Explicitly remove the old information in mRecentTasks.
18577            removeRecentTasksForUserLocked(userId);
18578        }
18579
18580        for (int i=0; i<callbacks.size(); i++) {
18581            try {
18582                if (stopped) callbacks.get(i).userStopped(userId);
18583                else callbacks.get(i).userStopAborted(userId);
18584            } catch (RemoteException e) {
18585            }
18586        }
18587
18588        if (stopped) {
18589            mSystemServiceManager.cleanupUser(userId);
18590            synchronized (this) {
18591                mStackSupervisor.removeUserLocked(userId);
18592            }
18593        }
18594    }
18595
18596    @Override
18597    public UserInfo getCurrentUser() {
18598        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18599                != PackageManager.PERMISSION_GRANTED) && (
18600                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18601                != PackageManager.PERMISSION_GRANTED)) {
18602            String msg = "Permission Denial: getCurrentUser() from pid="
18603                    + Binder.getCallingPid()
18604                    + ", uid=" + Binder.getCallingUid()
18605                    + " requires " + INTERACT_ACROSS_USERS;
18606            Slog.w(TAG, msg);
18607            throw new SecurityException(msg);
18608        }
18609        synchronized (this) {
18610            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18611            return getUserManagerLocked().getUserInfo(userId);
18612        }
18613    }
18614
18615    int getCurrentUserIdLocked() {
18616        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18617    }
18618
18619    @Override
18620    public boolean isUserRunning(int userId, boolean orStopped) {
18621        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18622                != PackageManager.PERMISSION_GRANTED) {
18623            String msg = "Permission Denial: isUserRunning() from pid="
18624                    + Binder.getCallingPid()
18625                    + ", uid=" + Binder.getCallingUid()
18626                    + " requires " + INTERACT_ACROSS_USERS;
18627            Slog.w(TAG, msg);
18628            throw new SecurityException(msg);
18629        }
18630        synchronized (this) {
18631            return isUserRunningLocked(userId, orStopped);
18632        }
18633    }
18634
18635    boolean isUserRunningLocked(int userId, boolean orStopped) {
18636        UserStartedState state = mStartedUsers.get(userId);
18637        if (state == null) {
18638            return false;
18639        }
18640        if (orStopped) {
18641            return true;
18642        }
18643        return state.mState != UserStartedState.STATE_STOPPING
18644                && state.mState != UserStartedState.STATE_SHUTDOWN;
18645    }
18646
18647    @Override
18648    public int[] getRunningUserIds() {
18649        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18650                != PackageManager.PERMISSION_GRANTED) {
18651            String msg = "Permission Denial: isUserRunning() from pid="
18652                    + Binder.getCallingPid()
18653                    + ", uid=" + Binder.getCallingUid()
18654                    + " requires " + INTERACT_ACROSS_USERS;
18655            Slog.w(TAG, msg);
18656            throw new SecurityException(msg);
18657        }
18658        synchronized (this) {
18659            return mStartedUserArray;
18660        }
18661    }
18662
18663    private void updateStartedUserArrayLocked() {
18664        int num = 0;
18665        for (int i=0; i<mStartedUsers.size();  i++) {
18666            UserStartedState uss = mStartedUsers.valueAt(i);
18667            // This list does not include stopping users.
18668            if (uss.mState != UserStartedState.STATE_STOPPING
18669                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18670                num++;
18671            }
18672        }
18673        mStartedUserArray = new int[num];
18674        num = 0;
18675        for (int i=0; i<mStartedUsers.size();  i++) {
18676            UserStartedState uss = mStartedUsers.valueAt(i);
18677            if (uss.mState != UserStartedState.STATE_STOPPING
18678                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18679                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18680                num++;
18681            }
18682        }
18683    }
18684
18685    @Override
18686    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18687        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18688                != PackageManager.PERMISSION_GRANTED) {
18689            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18690                    + Binder.getCallingPid()
18691                    + ", uid=" + Binder.getCallingUid()
18692                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18693            Slog.w(TAG, msg);
18694            throw new SecurityException(msg);
18695        }
18696
18697        mUserSwitchObservers.register(observer);
18698    }
18699
18700    @Override
18701    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18702        mUserSwitchObservers.unregister(observer);
18703    }
18704
18705    private boolean userExists(int userId) {
18706        if (userId == 0) {
18707            return true;
18708        }
18709        UserManagerService ums = getUserManagerLocked();
18710        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18711    }
18712
18713    int[] getUsersLocked() {
18714        UserManagerService ums = getUserManagerLocked();
18715        return ums != null ? ums.getUserIds() : new int[] { 0 };
18716    }
18717
18718    UserManagerService getUserManagerLocked() {
18719        if (mUserManager == null) {
18720            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18721            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18722        }
18723        return mUserManager;
18724    }
18725
18726    private int applyUserId(int uid, int userId) {
18727        return UserHandle.getUid(userId, uid);
18728    }
18729
18730    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18731        if (info == null) return null;
18732        ApplicationInfo newInfo = new ApplicationInfo(info);
18733        newInfo.uid = applyUserId(info.uid, userId);
18734        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18735                + info.packageName;
18736        return newInfo;
18737    }
18738
18739    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18740        if (aInfo == null
18741                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18742            return aInfo;
18743        }
18744
18745        ActivityInfo info = new ActivityInfo(aInfo);
18746        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18747        return info;
18748    }
18749
18750    private final class LocalService extends ActivityManagerInternal {
18751        @Override
18752        public void goingToSleep() {
18753            ActivityManagerService.this.goingToSleep();
18754        }
18755
18756        @Override
18757        public void wakingUp() {
18758            ActivityManagerService.this.wakingUp();
18759        }
18760
18761        @Override
18762        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18763                String processName, String abiOverride, int uid, Runnable crashHandler) {
18764            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18765                    processName, abiOverride, uid, crashHandler);
18766        }
18767    }
18768
18769    /**
18770     * An implementation of IAppTask, that allows an app to manage its own tasks via
18771     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18772     * only the process that calls getAppTasks() can call the AppTask methods.
18773     */
18774    class AppTaskImpl extends IAppTask.Stub {
18775        private int mTaskId;
18776        private int mCallingUid;
18777
18778        public AppTaskImpl(int taskId, int callingUid) {
18779            mTaskId = taskId;
18780            mCallingUid = callingUid;
18781        }
18782
18783        private void checkCaller() {
18784            if (mCallingUid != Binder.getCallingUid()) {
18785                throw new SecurityException("Caller " + mCallingUid
18786                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18787            }
18788        }
18789
18790        @Override
18791        public void finishAndRemoveTask() {
18792            checkCaller();
18793
18794            synchronized (ActivityManagerService.this) {
18795                long origId = Binder.clearCallingIdentity();
18796                try {
18797                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18798                    if (tr == null) {
18799                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18800                    }
18801                    // Only kill the process if we are not a new document
18802                    int flags = tr.getBaseIntent().getFlags();
18803                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18804                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18805                    removeTaskByIdLocked(mTaskId,
18806                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18807                } finally {
18808                    Binder.restoreCallingIdentity(origId);
18809                }
18810            }
18811        }
18812
18813        @Override
18814        public ActivityManager.RecentTaskInfo getTaskInfo() {
18815            checkCaller();
18816
18817            synchronized (ActivityManagerService.this) {
18818                long origId = Binder.clearCallingIdentity();
18819                try {
18820                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18821                    if (tr == null) {
18822                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18823                    }
18824                    return createRecentTaskInfoFromTaskRecord(tr);
18825                } finally {
18826                    Binder.restoreCallingIdentity(origId);
18827                }
18828            }
18829        }
18830
18831        @Override
18832        public void moveToFront() {
18833            checkCaller();
18834
18835            final TaskRecord tr;
18836            synchronized (ActivityManagerService.this) {
18837                tr = recentTaskForIdLocked(mTaskId);
18838                if (tr == null) {
18839                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18840                }
18841                if (tr.getRootActivity() != null) {
18842                    long origId = Binder.clearCallingIdentity();
18843                    try {
18844                        moveTaskToFrontLocked(tr.taskId, 0, null);
18845                        return;
18846                    } finally {
18847                        Binder.restoreCallingIdentity(origId);
18848                    }
18849                }
18850            }
18851
18852            startActivityFromRecentsInner(tr.taskId, null);
18853        }
18854
18855        @Override
18856        public int startActivity(IBinder whoThread, String callingPackage,
18857                Intent intent, String resolvedType, Bundle options) {
18858            checkCaller();
18859
18860            int callingUser = UserHandle.getCallingUserId();
18861            TaskRecord tr;
18862            IApplicationThread appThread;
18863            synchronized (ActivityManagerService.this) {
18864                tr = recentTaskForIdLocked(mTaskId);
18865                if (tr == null) {
18866                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18867                }
18868                appThread = ApplicationThreadNative.asInterface(whoThread);
18869                if (appThread == null) {
18870                    throw new IllegalArgumentException("Bad app thread " + appThread);
18871                }
18872            }
18873            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18874                    resolvedType, null, null, null, null, 0, 0, null, null,
18875                    null, options, callingUser, null, tr);
18876        }
18877
18878        @Override
18879        public void setExcludeFromRecents(boolean exclude) {
18880            checkCaller();
18881
18882            synchronized (ActivityManagerService.this) {
18883                long origId = Binder.clearCallingIdentity();
18884                try {
18885                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18886                    if (tr == null) {
18887                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18888                    }
18889                    Intent intent = tr.getBaseIntent();
18890                    if (exclude) {
18891                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18892                    } else {
18893                        intent.setFlags(intent.getFlags()
18894                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18895                    }
18896                } finally {
18897                    Binder.restoreCallingIdentity(origId);
18898                }
18899            }
18900        }
18901    }
18902}
18903