ActivityManagerService.java revision 2ade126e626d5d6d2d2e82fce4060458a0ca21c5
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.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199import dalvik.system.VMRuntime;
200
201import java.io.BufferedInputStream;
202import java.io.BufferedOutputStream;
203import java.io.DataInputStream;
204import java.io.DataOutputStream;
205import java.io.File;
206import java.io.FileDescriptor;
207import java.io.FileInputStream;
208import java.io.FileNotFoundException;
209import java.io.FileOutputStream;
210import java.io.IOException;
211import java.io.InputStreamReader;
212import java.io.PrintWriter;
213import java.io.StringWriter;
214import java.lang.ref.WeakReference;
215import java.util.ArrayList;
216import java.util.Arrays;
217import java.util.Collections;
218import java.util.Comparator;
219import java.util.HashMap;
220import java.util.HashSet;
221import java.util.Iterator;
222import java.util.List;
223import java.util.Locale;
224import java.util.Map;
225import java.util.Set;
226import java.util.concurrent.atomic.AtomicBoolean;
227import java.util.concurrent.atomic.AtomicLong;
228
229public final class ActivityManagerService extends ActivityManagerNative
230        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
231
232    private static final String USER_DATA_DIR = "/data/user/";
233    // File that stores last updated system version and called preboot receivers
234    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
235
236    static final String TAG = "ActivityManager";
237    static final String TAG_MU = "ActivityManagerServiceMU";
238    static final boolean DEBUG = false;
239    static final boolean localLOGV = DEBUG;
240    static final boolean DEBUG_BACKUP = localLOGV || false;
241    static final boolean DEBUG_BROADCAST = localLOGV || false;
242    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
244    static final boolean DEBUG_CLEANUP = localLOGV || false;
245    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
246    static final boolean DEBUG_FOCUS = false;
247    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
248    static final boolean DEBUG_MU = localLOGV || false;
249    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
250    static final boolean DEBUG_LRU = localLOGV || false;
251    static final boolean DEBUG_PAUSE = localLOGV || false;
252    static final boolean DEBUG_POWER = localLOGV || false;
253    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
254    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
255    static final boolean DEBUG_PROCESSES = localLOGV || false;
256    static final boolean DEBUG_PROVIDER = localLOGV || false;
257    static final boolean DEBUG_RESULTS = localLOGV || false;
258    static final boolean DEBUG_SERVICE = localLOGV || false;
259    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
260    static final boolean DEBUG_STACK = localLOGV || false;
261    static final boolean DEBUG_SWITCH = localLOGV || false;
262    static final boolean DEBUG_TASKS = localLOGV || false;
263    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
264    static final boolean DEBUG_TRANSITION = localLOGV || false;
265    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
266    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
267    static final boolean DEBUG_VISBILITY = localLOGV || false;
268    static final boolean DEBUG_PSS = localLOGV || false;
269    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
270    static final boolean DEBUG_RECENTS = localLOGV || false;
271    static final boolean VALIDATE_TOKENS = false;
272    static final boolean SHOW_ACTIVITY_START_TIME = true;
273
274    // Control over CPU and battery monitoring.
275    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
276    static final boolean MONITOR_CPU_USAGE = true;
277    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
278    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
279    static final boolean MONITOR_THREAD_CPU_USAGE = false;
280
281    // The flags that are set for all calls we make to the package manager.
282    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
283
284    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
285
286    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
287
288    // Maximum number recent bitmaps to keep in memory.
289    static final int MAX_RECENT_BITMAPS = 5;
290
291    // Amount of time after a call to stopAppSwitches() during which we will
292    // prevent further untrusted switches from happening.
293    static final long APP_SWITCH_DELAY_TIME = 5*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real.
297    static final int PROC_START_TIMEOUT = 10*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real, when the process was
301    // started with a wrapper for instrumentation (such as Valgrind) because it
302    // could take much longer than usual.
303    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
304
305    // How long to wait after going idle before forcing apps to GC.
306    static final int GC_TIMEOUT = 5*1000;
307
308    // The minimum amount of time between successive GC requests for a process.
309    static final int GC_MIN_INTERVAL = 60*1000;
310
311    // The minimum amount of time between successive PSS requests for a process.
312    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process
315    // when the request is due to the memory state being lowered.
316    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
317
318    // The rate at which we check for apps using excessive power -- 15 mins.
319    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on wake locks to start killing things.
323    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on CPU usage to start killing things.
327    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // How long we allow a receiver to run before giving up on it.
330    static final int BROADCAST_FG_TIMEOUT = 10*1000;
331    static final int BROADCAST_BG_TIMEOUT = 60*1000;
332
333    // How long we wait until we timeout on key dispatching.
334    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
335
336    // How long we wait until we timeout on key dispatching during instrumentation.
337    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
338
339    // Amount of time we wait for observers to handle a user switch before
340    // giving up on them and unfreezing the screen.
341    static final int USER_SWITCH_TIMEOUT = 2*1000;
342
343    // Maximum number of users we allow to be running at a time.
344    static final int MAX_RUNNING_USERS = 3;
345
346    // How long to wait in getAssistContextExtras for the activity and foreground services
347    // to respond with the result.
348    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
349
350    // Maximum number of persisted Uri grants a package is allowed
351    static final int MAX_PERSISTED_URI_GRANTS = 128;
352
353    static final int MY_PID = Process.myPid();
354
355    static final String[] EMPTY_STRING_ARRAY = new String[0];
356
357    // How many bytes to write into the dropbox log before truncating
358    static final int DROPBOX_MAX_SIZE = 256 * 1024;
359
360    // Access modes for handleIncomingUser.
361    static final int ALLOW_NON_FULL = 0;
362    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
363    static final int ALLOW_FULL_ONLY = 2;
364
365    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
366
367    /** All system services */
368    SystemServiceManager mSystemServiceManager;
369
370    /** Run all ActivityStacks through this */
371    ActivityStackSupervisor mStackSupervisor;
372
373    public IntentFirewall mIntentFirewall;
374
375    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
376    // default actuion automatically.  Important for devices without direct input
377    // devices.
378    private boolean mShowDialogs = true;
379
380    BroadcastQueue mFgBroadcastQueue;
381    BroadcastQueue mBgBroadcastQueue;
382    // Convenient for easy iteration over the queues. Foreground is first
383    // so that dispatch of foreground broadcasts gets precedence.
384    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
385
386    BroadcastQueue broadcastQueueForIntent(Intent intent) {
387        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
388        if (DEBUG_BACKGROUND_BROADCAST) {
389            Slog.i(TAG, "Broadcast intent " + intent + " on "
390                    + (isFg ? "foreground" : "background")
391                    + " queue");
392        }
393        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
394    }
395
396    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
397        for (BroadcastQueue queue : mBroadcastQueues) {
398            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
399            if (r != null) {
400                return r;
401            }
402        }
403        return null;
404    }
405
406    /**
407     * Activity we have told the window manager to have key focus.
408     */
409    ActivityRecord mFocusedActivity = null;
410
411    /**
412     * List of intents that were used to start the most recent tasks.
413     */
414    ArrayList<TaskRecord> mRecentTasks;
415    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
416
417    /**
418     * For addAppTask: cached of the last activity component that was added.
419     */
420    ComponentName mLastAddedTaskComponent;
421
422    /**
423     * For addAppTask: cached of the last activity uid that was added.
424     */
425    int mLastAddedTaskUid;
426
427    /**
428     * For addAppTask: cached of the last ActivityInfo that was added.
429     */
430    ActivityInfo mLastAddedTaskActivity;
431
432    public class PendingAssistExtras extends Binder implements Runnable {
433        public final ActivityRecord activity;
434        public boolean haveResult = false;
435        public Bundle result = null;
436        public PendingAssistExtras(ActivityRecord _activity) {
437            activity = _activity;
438        }
439        @Override
440        public void run() {
441            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
442            synchronized (this) {
443                haveResult = true;
444                notifyAll();
445            }
446        }
447    }
448
449    final ArrayList<PendingAssistExtras> mPendingAssistExtras
450            = new ArrayList<PendingAssistExtras>();
451
452    /**
453     * Process management.
454     */
455    final ProcessList mProcessList = new ProcessList();
456
457    /**
458     * All of the applications we currently have running organized by name.
459     * The keys are strings of the application package name (as
460     * returned by the package manager), and the keys are ApplicationRecord
461     * objects.
462     */
463    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
464
465    /**
466     * Tracking long-term execution of processes to look for abuse and other
467     * bad app behavior.
468     */
469    final ProcessStatsService mProcessStats;
470
471    /**
472     * The currently running isolated processes.
473     */
474    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
475
476    /**
477     * Counter for assigning isolated process uids, to avoid frequently reusing the
478     * same ones.
479     */
480    int mNextIsolatedProcessUid = 0;
481
482    /**
483     * The currently running heavy-weight process, if any.
484     */
485    ProcessRecord mHeavyWeightProcess = null;
486
487    /**
488     * The last time that various processes have crashed.
489     */
490    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
491
492    /**
493     * Information about a process that is currently marked as bad.
494     */
495    static final class BadProcessInfo {
496        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
497            this.time = time;
498            this.shortMsg = shortMsg;
499            this.longMsg = longMsg;
500            this.stack = stack;
501        }
502
503        final long time;
504        final String shortMsg;
505        final String longMsg;
506        final String stack;
507    }
508
509    /**
510     * Set of applications that we consider to be bad, and will reject
511     * incoming broadcasts from (which the user has no control over).
512     * Processes are added to this set when they have crashed twice within
513     * a minimum amount of time; they are removed from it when they are
514     * later restarted (hopefully due to some user action).  The value is the
515     * time it was added to the list.
516     */
517    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
518
519    /**
520     * All of the processes we currently have running organized by pid.
521     * The keys are the pid running the application.
522     *
523     * <p>NOTE: This object is protected by its own lock, NOT the global
524     * activity manager lock!
525     */
526    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
527
528    /**
529     * All of the processes that have been forced to be foreground.  The key
530     * is the pid of the caller who requested it (we hold a death
531     * link on it).
532     */
533    abstract class ForegroundToken implements IBinder.DeathRecipient {
534        int pid;
535        IBinder token;
536    }
537    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
538
539    /**
540     * List of records for processes that someone had tried to start before the
541     * system was ready.  We don't start them at that point, but ensure they
542     * are started by the time booting is complete.
543     */
544    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
545
546    /**
547     * List of persistent applications that are in the process
548     * of being started.
549     */
550    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
551
552    /**
553     * Processes that are being forcibly torn down.
554     */
555    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * List of running applications, sorted by recent usage.
559     * The first entry in the list is the least recently used.
560     */
561    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Where in mLruProcesses that the processes hosting activities start.
565     */
566    int mLruProcessActivityStart = 0;
567
568    /**
569     * Where in mLruProcesses that the processes hosting services start.
570     * This is after (lower index) than mLruProcessesActivityStart.
571     */
572    int mLruProcessServiceStart = 0;
573
574    /**
575     * List of processes that should gc as soon as things are idle.
576     */
577    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
578
579    /**
580     * Processes we want to collect PSS data from.
581     */
582    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
583
584    /**
585     * Last time we requested PSS data of all processes.
586     */
587    long mLastFullPssTime = SystemClock.uptimeMillis();
588
589    /**
590     * If set, the next time we collect PSS data we should do a full collection
591     * with data from native processes and the kernel.
592     */
593    boolean mFullPssPending = false;
594
595    /**
596     * This is the process holding what we currently consider to be
597     * the "home" activity.
598     */
599    ProcessRecord mHomeProcess;
600
601    /**
602     * This is the process holding the activity the user last visited that
603     * is in a different process from the one they are currently in.
604     */
605    ProcessRecord mPreviousProcess;
606
607    /**
608     * The time at which the previous process was last visible.
609     */
610    long mPreviousProcessVisibleTime;
611
612    /**
613     * Which uses have been started, so are allowed to run code.
614     */
615    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
616
617    /**
618     * LRU list of history of current users.  Most recently current is at the end.
619     */
620    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
621
622    /**
623     * Constant array of the users that are currently started.
624     */
625    int[] mStartedUserArray = new int[] { 0 };
626
627    /**
628     * Registered observers of the user switching mechanics.
629     */
630    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
631            = new RemoteCallbackList<IUserSwitchObserver>();
632
633    /**
634     * Currently active user switch.
635     */
636    Object mCurUserSwitchCallback;
637
638    /**
639     * Packages that the user has asked to have run in screen size
640     * compatibility mode instead of filling the screen.
641     */
642    final CompatModePackages mCompatModePackages;
643
644    /**
645     * Set of IntentSenderRecord objects that are currently active.
646     */
647    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
648            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
649
650    /**
651     * Fingerprints (hashCode()) of stack traces that we've
652     * already logged DropBox entries for.  Guarded by itself.  If
653     * something (rogue user app) forces this over
654     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
655     */
656    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
657    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
658
659    /**
660     * Strict Mode background batched logging state.
661     *
662     * The string buffer is guarded by itself, and its lock is also
663     * used to determine if another batched write is already
664     * in-flight.
665     */
666    private final StringBuilder mStrictModeBuffer = new StringBuilder();
667
668    /**
669     * Keeps track of all IIntentReceivers that have been registered for
670     * broadcasts.  Hash keys are the receiver IBinder, hash value is
671     * a ReceiverList.
672     */
673    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
674            new HashMap<IBinder, ReceiverList>();
675
676    /**
677     * Resolver for broadcast intents to registered receivers.
678     * Holds BroadcastFilter (subclass of IntentFilter).
679     */
680    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
681            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
682        @Override
683        protected boolean allowFilterResult(
684                BroadcastFilter filter, List<BroadcastFilter> dest) {
685            IBinder target = filter.receiverList.receiver.asBinder();
686            for (int i=dest.size()-1; i>=0; i--) {
687                if (dest.get(i).receiverList.receiver.asBinder() == target) {
688                    return false;
689                }
690            }
691            return true;
692        }
693
694        @Override
695        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
696            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
697                    || userId == filter.owningUserId) {
698                return super.newResult(filter, match, userId);
699            }
700            return null;
701        }
702
703        @Override
704        protected BroadcastFilter[] newArray(int size) {
705            return new BroadcastFilter[size];
706        }
707
708        @Override
709        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
710            return packageName.equals(filter.packageName);
711        }
712    };
713
714    /**
715     * State of all active sticky broadcasts per user.  Keys are the action of the
716     * sticky Intent, values are an ArrayList of all broadcasted intents with
717     * that action (which should usually be one).  The SparseArray is keyed
718     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
719     * for stickies that are sent to all users.
720     */
721    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
722            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
723
724    final ActiveServices mServices;
725
726    /**
727     * Backup/restore process management
728     */
729    String mBackupAppName = null;
730    BackupRecord mBackupTarget = null;
731
732    final ProviderMap mProviderMap;
733
734    /**
735     * List of content providers who have clients waiting for them.  The
736     * application is currently being launched and the provider will be
737     * removed from this list once it is published.
738     */
739    final ArrayList<ContentProviderRecord> mLaunchingProviders
740            = new ArrayList<ContentProviderRecord>();
741
742    /**
743     * File storing persisted {@link #mGrantedUriPermissions}.
744     */
745    private final AtomicFile mGrantFile;
746
747    /** XML constants used in {@link #mGrantFile} */
748    private static final String TAG_URI_GRANTS = "uri-grants";
749    private static final String TAG_URI_GRANT = "uri-grant";
750    private static final String ATTR_USER_HANDLE = "userHandle";
751    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
752    private static final String ATTR_TARGET_USER_ID = "targetUserId";
753    private static final String ATTR_SOURCE_PKG = "sourcePkg";
754    private static final String ATTR_TARGET_PKG = "targetPkg";
755    private static final String ATTR_URI = "uri";
756    private static final String ATTR_MODE_FLAGS = "modeFlags";
757    private static final String ATTR_CREATED_TIME = "createdTime";
758    private static final String ATTR_PREFIX = "prefix";
759
760    /**
761     * Global set of specific {@link Uri} permissions that have been granted.
762     * This optimized lookup structure maps from {@link UriPermission#targetUid}
763     * to {@link UriPermission#uri} to {@link UriPermission}.
764     */
765    @GuardedBy("this")
766    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
767            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
768
769    public static class GrantUri {
770        public final int sourceUserId;
771        public final Uri uri;
772        public boolean prefix;
773
774        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
775            this.sourceUserId = sourceUserId;
776            this.uri = uri;
777            this.prefix = prefix;
778        }
779
780        @Override
781        public int hashCode() {
782            return toString().hashCode();
783        }
784
785        @Override
786        public boolean equals(Object o) {
787            if (o instanceof GrantUri) {
788                GrantUri other = (GrantUri) o;
789                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
790                        && prefix == other.prefix;
791            }
792            return false;
793        }
794
795        @Override
796        public String toString() {
797            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
798            if (prefix) result += " [prefix]";
799            return result;
800        }
801
802        public String toSafeString() {
803            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
804            if (prefix) result += " [prefix]";
805            return result;
806        }
807
808        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
809            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
810                    ContentProvider.getUriWithoutUserId(uri), false);
811        }
812    }
813
814    CoreSettingsObserver mCoreSettingsObserver;
815
816    /**
817     * Thread-local storage used to carry caller permissions over through
818     * indirect content-provider access.
819     */
820    private class Identity {
821        public int pid;
822        public int uid;
823
824        Identity(int _pid, int _uid) {
825            pid = _pid;
826            uid = _uid;
827        }
828    }
829
830    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
831
832    /**
833     * All information we have collected about the runtime performance of
834     * any user id that can impact battery performance.
835     */
836    final BatteryStatsService mBatteryStatsService;
837
838    /**
839     * Information about component usage
840     */
841    UsageStatsManagerInternal mUsageStatsService;
842
843    /**
844     * Information about and control over application operations
845     */
846    final AppOpsService mAppOpsService;
847
848    /**
849     * Save recent tasks information across reboots.
850     */
851    final TaskPersister mTaskPersister;
852
853    /**
854     * Current configuration information.  HistoryRecord objects are given
855     * a reference to this object to indicate which configuration they are
856     * currently running in, so this object must be kept immutable.
857     */
858    Configuration mConfiguration = new Configuration();
859
860    /**
861     * Current sequencing integer of the configuration, for skipping old
862     * configurations.
863     */
864    int mConfigurationSeq = 0;
865
866    /**
867     * Hardware-reported OpenGLES version.
868     */
869    final int GL_ES_VERSION;
870
871    /**
872     * List of initialization arguments to pass to all processes when binding applications to them.
873     * For example, references to the commonly used services.
874     */
875    HashMap<String, IBinder> mAppBindArgs;
876
877    /**
878     * Temporary to avoid allocations.  Protected by main lock.
879     */
880    final StringBuilder mStringBuilder = new StringBuilder(256);
881
882    /**
883     * Used to control how we initialize the service.
884     */
885    ComponentName mTopComponent;
886    String mTopAction = Intent.ACTION_MAIN;
887    String mTopData;
888    boolean mProcessesReady = false;
889    boolean mSystemReady = false;
890    boolean mBooting = false;
891    boolean mWaitingUpdate = false;
892    boolean mDidUpdate = false;
893    boolean mOnBattery = false;
894    boolean mLaunchWarningShown = false;
895
896    Context mContext;
897
898    int mFactoryTest;
899
900    boolean mCheckedForSetup;
901
902    /**
903     * The time at which we will allow normal application switches again,
904     * after a call to {@link #stopAppSwitches()}.
905     */
906    long mAppSwitchesAllowedTime;
907
908    /**
909     * This is set to true after the first switch after mAppSwitchesAllowedTime
910     * is set; any switches after that will clear the time.
911     */
912    boolean mDidAppSwitch;
913
914    /**
915     * Last time (in realtime) at which we checked for power usage.
916     */
917    long mLastPowerCheckRealtime;
918
919    /**
920     * Last time (in uptime) at which we checked for power usage.
921     */
922    long mLastPowerCheckUptime;
923
924    /**
925     * Set while we are wanting to sleep, to prevent any
926     * activities from being started/resumed.
927     */
928    private boolean mSleeping = false;
929
930    /**
931     * Set while we are running a voice interaction.  This overrides
932     * sleeping while it is active.
933     */
934    private boolean mRunningVoice = false;
935
936    /**
937     * State of external calls telling us if the device is asleep.
938     */
939    private boolean mWentToSleep = false;
940
941    /**
942     * State of external call telling us if the lock screen is shown.
943     */
944    private boolean mLockScreenShown = false;
945
946    /**
947     * Set if we are shutting down the system, similar to sleeping.
948     */
949    boolean mShuttingDown = false;
950
951    /**
952     * Current sequence id for oom_adj computation traversal.
953     */
954    int mAdjSeq = 0;
955
956    /**
957     * Current sequence id for process LRU updating.
958     */
959    int mLruSeq = 0;
960
961    /**
962     * Keep track of the non-cached/empty process we last found, to help
963     * determine how to distribute cached/empty processes next time.
964     */
965    int mNumNonCachedProcs = 0;
966
967    /**
968     * Keep track of the number of cached hidden procs, to balance oom adj
969     * distribution between those and empty procs.
970     */
971    int mNumCachedHiddenProcs = 0;
972
973    /**
974     * Keep track of the number of service processes we last found, to
975     * determine on the next iteration which should be B services.
976     */
977    int mNumServiceProcs = 0;
978    int mNewNumAServiceProcs = 0;
979    int mNewNumServiceProcs = 0;
980
981    /**
982     * Allow the current computed overall memory level of the system to go down?
983     * This is set to false when we are killing processes for reasons other than
984     * memory management, so that the now smaller process list will not be taken as
985     * an indication that memory is tighter.
986     */
987    boolean mAllowLowerMemLevel = false;
988
989    /**
990     * The last computed memory level, for holding when we are in a state that
991     * processes are going away for other reasons.
992     */
993    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
994
995    /**
996     * The last total number of process we have, to determine if changes actually look
997     * like a shrinking number of process due to lower RAM.
998     */
999    int mLastNumProcesses;
1000
1001    /**
1002     * The uptime of the last time we performed idle maintenance.
1003     */
1004    long mLastIdleTime = SystemClock.uptimeMillis();
1005
1006    /**
1007     * Total time spent with RAM that has been added in the past since the last idle time.
1008     */
1009    long mLowRamTimeSinceLastIdle = 0;
1010
1011    /**
1012     * If RAM is currently low, when that horrible situation started.
1013     */
1014    long mLowRamStartTime = 0;
1015
1016    /**
1017     * For reporting to battery stats the current top application.
1018     */
1019    private String mCurResumedPackage = null;
1020    private int mCurResumedUid = -1;
1021
1022    /**
1023     * For reporting to battery stats the apps currently running foreground
1024     * service.  The ProcessMap is package/uid tuples; each of these contain
1025     * an array of the currently foreground processes.
1026     */
1027    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1028            = new ProcessMap<ArrayList<ProcessRecord>>();
1029
1030    /**
1031     * This is set if we had to do a delayed dexopt of an app before launching
1032     * it, to increase the ANR timeouts in that case.
1033     */
1034    boolean mDidDexOpt;
1035
1036    /**
1037     * Set if the systemServer made a call to enterSafeMode.
1038     */
1039    boolean mSafeMode;
1040
1041    String mDebugApp = null;
1042    boolean mWaitForDebugger = false;
1043    boolean mDebugTransient = false;
1044    String mOrigDebugApp = null;
1045    boolean mOrigWaitForDebugger = false;
1046    boolean mAlwaysFinishActivities = false;
1047    IActivityController mController = null;
1048    String mProfileApp = null;
1049    ProcessRecord mProfileProc = null;
1050    String mProfileFile;
1051    ParcelFileDescriptor mProfileFd;
1052    int mSamplingInterval = 0;
1053    boolean mAutoStopProfiler = false;
1054    int mProfileType = 0;
1055    String mOpenGlTraceApp = null;
1056
1057    static class ProcessChangeItem {
1058        static final int CHANGE_ACTIVITIES = 1<<0;
1059        static final int CHANGE_PROCESS_STATE = 1<<1;
1060        int changes;
1061        int uid;
1062        int pid;
1063        int processState;
1064        boolean foregroundActivities;
1065    }
1066
1067    final RemoteCallbackList<IProcessObserver> mProcessObservers
1068            = new RemoteCallbackList<IProcessObserver>();
1069    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1070
1071    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1072            = new ArrayList<ProcessChangeItem>();
1073    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1074            = new ArrayList<ProcessChangeItem>();
1075
1076    /**
1077     * Runtime CPU use collection thread.  This object's lock is used to
1078     * protect all related state.
1079     */
1080    final Thread mProcessCpuThread;
1081
1082    /**
1083     * Used to collect process stats when showing not responding dialog.
1084     * Protected by mProcessCpuThread.
1085     */
1086    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1087            MONITOR_THREAD_CPU_USAGE);
1088    final AtomicLong mLastCpuTime = new AtomicLong(0);
1089    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1090
1091    long mLastWriteTime = 0;
1092
1093    /**
1094     * Used to retain an update lock when the foreground activity is in
1095     * immersive mode.
1096     */
1097    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1098
1099    /**
1100     * Set to true after the system has finished booting.
1101     */
1102    boolean mBooted = false;
1103
1104    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1105    int mProcessLimitOverride = -1;
1106
1107    WindowManagerService mWindowManager;
1108
1109    final ActivityThread mSystemThread;
1110
1111    // Holds the current foreground user's id
1112    int mCurrentUserId = 0;
1113    // Holds the target user's id during a user switch
1114    int mTargetUserId = UserHandle.USER_NULL;
1115    // If there are multiple profiles for the current user, their ids are here
1116    // Currently only the primary user can have managed profiles
1117    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1118
1119    /**
1120     * Mapping from each known user ID to the profile group ID it is associated with.
1121     */
1122    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1123
1124    private UserManagerService mUserManager;
1125
1126    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1127        final ProcessRecord mApp;
1128        final int mPid;
1129        final IApplicationThread mAppThread;
1130
1131        AppDeathRecipient(ProcessRecord app, int pid,
1132                IApplicationThread thread) {
1133            if (localLOGV) Slog.v(
1134                TAG, "New death recipient " + this
1135                + " for thread " + thread.asBinder());
1136            mApp = app;
1137            mPid = pid;
1138            mAppThread = thread;
1139        }
1140
1141        @Override
1142        public void binderDied() {
1143            if (localLOGV) Slog.v(
1144                TAG, "Death received in " + this
1145                + " for thread " + mAppThread.asBinder());
1146            synchronized(ActivityManagerService.this) {
1147                appDiedLocked(mApp, mPid, mAppThread);
1148            }
1149        }
1150    }
1151
1152    static final int SHOW_ERROR_MSG = 1;
1153    static final int SHOW_NOT_RESPONDING_MSG = 2;
1154    static final int SHOW_FACTORY_ERROR_MSG = 3;
1155    static final int UPDATE_CONFIGURATION_MSG = 4;
1156    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1157    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1158    static final int SERVICE_TIMEOUT_MSG = 12;
1159    static final int UPDATE_TIME_ZONE = 13;
1160    static final int SHOW_UID_ERROR_MSG = 14;
1161    static final int IM_FEELING_LUCKY_MSG = 15;
1162    static final int PROC_START_TIMEOUT_MSG = 20;
1163    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1164    static final int KILL_APPLICATION_MSG = 22;
1165    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1166    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1167    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1168    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1169    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1170    static final int CLEAR_DNS_CACHE_MSG = 28;
1171    static final int UPDATE_HTTP_PROXY_MSG = 29;
1172    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1173    static final int DISPATCH_PROCESSES_CHANGED = 31;
1174    static final int DISPATCH_PROCESS_DIED = 32;
1175    static final int REPORT_MEM_USAGE_MSG = 33;
1176    static final int REPORT_USER_SWITCH_MSG = 34;
1177    static final int CONTINUE_USER_SWITCH_MSG = 35;
1178    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1179    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1180    static final int PERSIST_URI_GRANTS_MSG = 38;
1181    static final int REQUEST_ALL_PSS_MSG = 39;
1182    static final int START_PROFILES_MSG = 40;
1183    static final int UPDATE_TIME = 41;
1184    static final int SYSTEM_USER_START_MSG = 42;
1185    static final int SYSTEM_USER_CURRENT_MSG = 43;
1186    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1187    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1188    static final int START_USER_SWITCH_MSG = 46;
1189
1190    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1191    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1192    static final int FIRST_COMPAT_MODE_MSG = 300;
1193    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1194
1195    AlertDialog mUidAlert;
1196    CompatModeDialog mCompatModeDialog;
1197    long mLastMemUsageReportTime = 0;
1198
1199    private LockToAppRequestDialog mLockToAppRequest;
1200
1201    /**
1202     * Flag whether the current user is a "monkey", i.e. whether
1203     * the UI is driven by a UI automation tool.
1204     */
1205    private boolean mUserIsMonkey;
1206
1207    /** Flag whether the device has a Recents UI */
1208    boolean mHasRecents;
1209
1210    /** The dimensions of the thumbnails in the Recents UI. */
1211    int mThumbnailWidth;
1212    int mThumbnailHeight;
1213
1214    final ServiceThread mHandlerThread;
1215    final MainHandler mHandler;
1216
1217    final class MainHandler extends Handler {
1218        public MainHandler(Looper looper) {
1219            super(looper, null, true);
1220        }
1221
1222        @Override
1223        public void handleMessage(Message msg) {
1224            switch (msg.what) {
1225            case SHOW_ERROR_MSG: {
1226                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1227                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1228                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1229                synchronized (ActivityManagerService.this) {
1230                    ProcessRecord proc = (ProcessRecord)data.get("app");
1231                    AppErrorResult res = (AppErrorResult) data.get("result");
1232                    if (proc != null && proc.crashDialog != null) {
1233                        Slog.e(TAG, "App already has crash dialog: " + proc);
1234                        if (res != null) {
1235                            res.set(0);
1236                        }
1237                        return;
1238                    }
1239                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1240                            >= Process.FIRST_APPLICATION_UID
1241                            && proc.pid != MY_PID);
1242                    for (int userId : mCurrentProfileIds) {
1243                        isBackground &= (proc.userId != userId);
1244                    }
1245                    if (isBackground && !showBackground) {
1246                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1247                        if (res != null) {
1248                            res.set(0);
1249                        }
1250                        return;
1251                    }
1252                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1253                        Dialog d = new AppErrorDialog(mContext,
1254                                ActivityManagerService.this, res, proc);
1255                        d.show();
1256                        proc.crashDialog = d;
1257                    } else {
1258                        // The device is asleep, so just pretend that the user
1259                        // saw a crash dialog and hit "force quit".
1260                        if (res != null) {
1261                            res.set(0);
1262                        }
1263                    }
1264                }
1265
1266                ensureBootCompleted();
1267            } break;
1268            case SHOW_NOT_RESPONDING_MSG: {
1269                synchronized (ActivityManagerService.this) {
1270                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1271                    ProcessRecord proc = (ProcessRecord)data.get("app");
1272                    if (proc != null && proc.anrDialog != null) {
1273                        Slog.e(TAG, "App already has anr dialog: " + proc);
1274                        return;
1275                    }
1276
1277                    Intent intent = new Intent("android.intent.action.ANR");
1278                    if (!mProcessesReady) {
1279                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1280                                | Intent.FLAG_RECEIVER_FOREGROUND);
1281                    }
1282                    broadcastIntentLocked(null, null, intent,
1283                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1284                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1285
1286                    if (mShowDialogs) {
1287                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1288                                mContext, proc, (ActivityRecord)data.get("activity"),
1289                                msg.arg1 != 0);
1290                        d.show();
1291                        proc.anrDialog = d;
1292                    } else {
1293                        // Just kill the app if there is no dialog to be shown.
1294                        killAppAtUsersRequest(proc, null);
1295                    }
1296                }
1297
1298                ensureBootCompleted();
1299            } break;
1300            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1301                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1302                synchronized (ActivityManagerService.this) {
1303                    ProcessRecord proc = (ProcessRecord) data.get("app");
1304                    if (proc == null) {
1305                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1306                        break;
1307                    }
1308                    if (proc.crashDialog != null) {
1309                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1310                        return;
1311                    }
1312                    AppErrorResult res = (AppErrorResult) data.get("result");
1313                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1314                        Dialog d = new StrictModeViolationDialog(mContext,
1315                                ActivityManagerService.this, res, proc);
1316                        d.show();
1317                        proc.crashDialog = d;
1318                    } else {
1319                        // The device is asleep, so just pretend that the user
1320                        // saw a crash dialog and hit "force quit".
1321                        res.set(0);
1322                    }
1323                }
1324                ensureBootCompleted();
1325            } break;
1326            case SHOW_FACTORY_ERROR_MSG: {
1327                Dialog d = new FactoryErrorDialog(
1328                    mContext, msg.getData().getCharSequence("msg"));
1329                d.show();
1330                ensureBootCompleted();
1331            } break;
1332            case UPDATE_CONFIGURATION_MSG: {
1333                final ContentResolver resolver = mContext.getContentResolver();
1334                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1335            } break;
1336            case GC_BACKGROUND_PROCESSES_MSG: {
1337                synchronized (ActivityManagerService.this) {
1338                    performAppGcsIfAppropriateLocked();
1339                }
1340            } break;
1341            case WAIT_FOR_DEBUGGER_MSG: {
1342                synchronized (ActivityManagerService.this) {
1343                    ProcessRecord app = (ProcessRecord)msg.obj;
1344                    if (msg.arg1 != 0) {
1345                        if (!app.waitedForDebugger) {
1346                            Dialog d = new AppWaitingForDebuggerDialog(
1347                                    ActivityManagerService.this,
1348                                    mContext, app);
1349                            app.waitDialog = d;
1350                            app.waitedForDebugger = true;
1351                            d.show();
1352                        }
1353                    } else {
1354                        if (app.waitDialog != null) {
1355                            app.waitDialog.dismiss();
1356                            app.waitDialog = null;
1357                        }
1358                    }
1359                }
1360            } break;
1361            case SERVICE_TIMEOUT_MSG: {
1362                if (mDidDexOpt) {
1363                    mDidDexOpt = false;
1364                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1365                    nmsg.obj = msg.obj;
1366                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1367                    return;
1368                }
1369                mServices.serviceTimeout((ProcessRecord)msg.obj);
1370            } break;
1371            case UPDATE_TIME_ZONE: {
1372                synchronized (ActivityManagerService.this) {
1373                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1374                        ProcessRecord r = mLruProcesses.get(i);
1375                        if (r.thread != null) {
1376                            try {
1377                                r.thread.updateTimeZone();
1378                            } catch (RemoteException ex) {
1379                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1380                            }
1381                        }
1382                    }
1383                }
1384            } break;
1385            case CLEAR_DNS_CACHE_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1388                        ProcessRecord r = mLruProcesses.get(i);
1389                        if (r.thread != null) {
1390                            try {
1391                                r.thread.clearDnsCache();
1392                            } catch (RemoteException ex) {
1393                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1394                            }
1395                        }
1396                    }
1397                }
1398            } break;
1399            case UPDATE_HTTP_PROXY_MSG: {
1400                ProxyInfo proxy = (ProxyInfo)msg.obj;
1401                String host = "";
1402                String port = "";
1403                String exclList = "";
1404                Uri pacFileUrl = Uri.EMPTY;
1405                if (proxy != null) {
1406                    host = proxy.getHost();
1407                    port = Integer.toString(proxy.getPort());
1408                    exclList = proxy.getExclusionListAsString();
1409                    pacFileUrl = proxy.getPacFileUrl();
1410                }
1411                synchronized (ActivityManagerService.this) {
1412                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1413                        ProcessRecord r = mLruProcesses.get(i);
1414                        if (r.thread != null) {
1415                            try {
1416                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1417                            } catch (RemoteException ex) {
1418                                Slog.w(TAG, "Failed to update http proxy for: " +
1419                                        r.info.processName);
1420                            }
1421                        }
1422                    }
1423                }
1424            } break;
1425            case SHOW_UID_ERROR_MSG: {
1426                String title = "System UIDs Inconsistent";
1427                String text = "UIDs on the system are inconsistent, you need to wipe your"
1428                        + " data partition or your device will be unstable.";
1429                Log.e(TAG, title + ": " + text);
1430                if (mShowDialogs) {
1431                    // XXX This is a temporary dialog, no need to localize.
1432                    AlertDialog d = new BaseErrorDialog(mContext);
1433                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1434                    d.setCancelable(false);
1435                    d.setTitle(title);
1436                    d.setMessage(text);
1437                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1438                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1439                    mUidAlert = d;
1440                    d.show();
1441                }
1442            } break;
1443            case IM_FEELING_LUCKY_MSG: {
1444                if (mUidAlert != null) {
1445                    mUidAlert.dismiss();
1446                    mUidAlert = null;
1447                }
1448            } break;
1449            case PROC_START_TIMEOUT_MSG: {
1450                if (mDidDexOpt) {
1451                    mDidDexOpt = false;
1452                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1453                    nmsg.obj = msg.obj;
1454                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1455                    return;
1456                }
1457                ProcessRecord app = (ProcessRecord)msg.obj;
1458                synchronized (ActivityManagerService.this) {
1459                    processStartTimedOutLocked(app);
1460                }
1461            } break;
1462            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1463                synchronized (ActivityManagerService.this) {
1464                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1465                }
1466            } break;
1467            case KILL_APPLICATION_MSG: {
1468                synchronized (ActivityManagerService.this) {
1469                    int appid = msg.arg1;
1470                    boolean restart = (msg.arg2 == 1);
1471                    Bundle bundle = (Bundle)msg.obj;
1472                    String pkg = bundle.getString("pkg");
1473                    String reason = bundle.getString("reason");
1474                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1475                            false, UserHandle.USER_ALL, reason);
1476                }
1477            } break;
1478            case FINALIZE_PENDING_INTENT_MSG: {
1479                ((PendingIntentRecord)msg.obj).completeFinalize();
1480            } break;
1481            case POST_HEAVY_NOTIFICATION_MSG: {
1482                INotificationManager inm = NotificationManager.getService();
1483                if (inm == null) {
1484                    return;
1485                }
1486
1487                ActivityRecord root = (ActivityRecord)msg.obj;
1488                ProcessRecord process = root.app;
1489                if (process == null) {
1490                    return;
1491                }
1492
1493                try {
1494                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1495                    String text = mContext.getString(R.string.heavy_weight_notification,
1496                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1497                    Notification notification = new Notification();
1498                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1499                    notification.when = 0;
1500                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1501                    notification.tickerText = text;
1502                    notification.defaults = 0; // please be quiet
1503                    notification.sound = null;
1504                    notification.vibrate = null;
1505                    notification.color = mContext.getResources().getColor(
1506                            com.android.internal.R.color.system_notification_accent_color);
1507                    notification.setLatestEventInfo(context, text,
1508                            mContext.getText(R.string.heavy_weight_notification_detail),
1509                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1510                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1511                                    new UserHandle(root.userId)));
1512
1513                    try {
1514                        int[] outId = new int[1];
1515                        inm.enqueueNotificationWithTag("android", "android", null,
1516                                R.string.heavy_weight_notification,
1517                                notification, outId, root.userId);
1518                    } catch (RuntimeException e) {
1519                        Slog.w(ActivityManagerService.TAG,
1520                                "Error showing notification for heavy-weight app", e);
1521                    } catch (RemoteException e) {
1522                    }
1523                } catch (NameNotFoundException e) {
1524                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1525                }
1526            } break;
1527            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1528                INotificationManager inm = NotificationManager.getService();
1529                if (inm == null) {
1530                    return;
1531                }
1532                try {
1533                    inm.cancelNotificationWithTag("android", null,
1534                            R.string.heavy_weight_notification,  msg.arg1);
1535                } catch (RuntimeException e) {
1536                    Slog.w(ActivityManagerService.TAG,
1537                            "Error canceling notification for service", e);
1538                } catch (RemoteException e) {
1539                }
1540            } break;
1541            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1542                synchronized (ActivityManagerService.this) {
1543                    checkExcessivePowerUsageLocked(true);
1544                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1545                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1546                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1547                }
1548            } break;
1549            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1550                synchronized (ActivityManagerService.this) {
1551                    ActivityRecord ar = (ActivityRecord)msg.obj;
1552                    if (mCompatModeDialog != null) {
1553                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1554                                ar.info.applicationInfo.packageName)) {
1555                            return;
1556                        }
1557                        mCompatModeDialog.dismiss();
1558                        mCompatModeDialog = null;
1559                    }
1560                    if (ar != null && false) {
1561                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1562                                ar.packageName)) {
1563                            int mode = mCompatModePackages.computeCompatModeLocked(
1564                                    ar.info.applicationInfo);
1565                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1566                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1567                                mCompatModeDialog = new CompatModeDialog(
1568                                        ActivityManagerService.this, mContext,
1569                                        ar.info.applicationInfo);
1570                                mCompatModeDialog.show();
1571                            }
1572                        }
1573                    }
1574                }
1575                break;
1576            }
1577            case DISPATCH_PROCESSES_CHANGED: {
1578                dispatchProcessesChanged();
1579                break;
1580            }
1581            case DISPATCH_PROCESS_DIED: {
1582                final int pid = msg.arg1;
1583                final int uid = msg.arg2;
1584                dispatchProcessDied(pid, uid);
1585                break;
1586            }
1587            case REPORT_MEM_USAGE_MSG: {
1588                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1589                Thread thread = new Thread() {
1590                    @Override public void run() {
1591                        final SparseArray<ProcessMemInfo> infoMap
1592                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1593                        for (int i=0, N=memInfos.size(); i<N; i++) {
1594                            ProcessMemInfo mi = memInfos.get(i);
1595                            infoMap.put(mi.pid, mi);
1596                        }
1597                        updateCpuStatsNow();
1598                        synchronized (mProcessCpuThread) {
1599                            final int N = mProcessCpuTracker.countStats();
1600                            for (int i=0; i<N; i++) {
1601                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1602                                if (st.vsize > 0) {
1603                                    long pss = Debug.getPss(st.pid, null);
1604                                    if (pss > 0) {
1605                                        if (infoMap.indexOfKey(st.pid) < 0) {
1606                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1607                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1608                                            mi.pss = pss;
1609                                            memInfos.add(mi);
1610                                        }
1611                                    }
1612                                }
1613                            }
1614                        }
1615
1616                        long totalPss = 0;
1617                        for (int i=0, N=memInfos.size(); i<N; i++) {
1618                            ProcessMemInfo mi = memInfos.get(i);
1619                            if (mi.pss == 0) {
1620                                mi.pss = Debug.getPss(mi.pid, null);
1621                            }
1622                            totalPss += mi.pss;
1623                        }
1624                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1625                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1626                                if (lhs.oomAdj != rhs.oomAdj) {
1627                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1628                                }
1629                                if (lhs.pss != rhs.pss) {
1630                                    return lhs.pss < rhs.pss ? 1 : -1;
1631                                }
1632                                return 0;
1633                            }
1634                        });
1635
1636                        StringBuilder tag = new StringBuilder(128);
1637                        StringBuilder stack = new StringBuilder(128);
1638                        tag.append("Low on memory -- ");
1639                        appendMemBucket(tag, totalPss, "total", false);
1640                        appendMemBucket(stack, totalPss, "total", true);
1641
1642                        StringBuilder logBuilder = new StringBuilder(1024);
1643                        logBuilder.append("Low on memory:\n");
1644
1645                        boolean firstLine = true;
1646                        int lastOomAdj = Integer.MIN_VALUE;
1647                        for (int i=0, N=memInfos.size(); i<N; i++) {
1648                            ProcessMemInfo mi = memInfos.get(i);
1649
1650                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1651                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1652                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1653                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1654                                if (lastOomAdj != mi.oomAdj) {
1655                                    lastOomAdj = mi.oomAdj;
1656                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1657                                        tag.append(" / ");
1658                                    }
1659                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1660                                        if (firstLine) {
1661                                            stack.append(":");
1662                                            firstLine = false;
1663                                        }
1664                                        stack.append("\n\t at ");
1665                                    } else {
1666                                        stack.append("$");
1667                                    }
1668                                } else {
1669                                    tag.append(" ");
1670                                    stack.append("$");
1671                                }
1672                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1673                                    appendMemBucket(tag, mi.pss, mi.name, false);
1674                                }
1675                                appendMemBucket(stack, mi.pss, mi.name, true);
1676                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1677                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1678                                    stack.append("(");
1679                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1680                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1681                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1682                                            stack.append(":");
1683                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1684                                        }
1685                                    }
1686                                    stack.append(")");
1687                                }
1688                            }
1689
1690                            logBuilder.append("  ");
1691                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1692                            logBuilder.append(' ');
1693                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1694                            logBuilder.append(' ');
1695                            ProcessList.appendRamKb(logBuilder, mi.pss);
1696                            logBuilder.append(" kB: ");
1697                            logBuilder.append(mi.name);
1698                            logBuilder.append(" (");
1699                            logBuilder.append(mi.pid);
1700                            logBuilder.append(") ");
1701                            logBuilder.append(mi.adjType);
1702                            logBuilder.append('\n');
1703                            if (mi.adjReason != null) {
1704                                logBuilder.append("                      ");
1705                                logBuilder.append(mi.adjReason);
1706                                logBuilder.append('\n');
1707                            }
1708                        }
1709
1710                        logBuilder.append("           ");
1711                        ProcessList.appendRamKb(logBuilder, totalPss);
1712                        logBuilder.append(" kB: TOTAL\n");
1713
1714                        long[] infos = new long[Debug.MEMINFO_COUNT];
1715                        Debug.getMemInfo(infos);
1716                        logBuilder.append("  MemInfo: ");
1717                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1718                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1719                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1720                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1721                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1722                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1723                            logBuilder.append("  ZRAM: ");
1724                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1725                            logBuilder.append(" kB RAM, ");
1726                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1727                            logBuilder.append(" kB swap total, ");
1728                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1729                            logBuilder.append(" kB swap free\n");
1730                        }
1731                        Slog.i(TAG, logBuilder.toString());
1732
1733                        StringBuilder dropBuilder = new StringBuilder(1024);
1734                        /*
1735                        StringWriter oomSw = new StringWriter();
1736                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1737                        StringWriter catSw = new StringWriter();
1738                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1739                        String[] emptyArgs = new String[] { };
1740                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1741                        oomPw.flush();
1742                        String oomString = oomSw.toString();
1743                        */
1744                        dropBuilder.append(stack);
1745                        dropBuilder.append('\n');
1746                        dropBuilder.append('\n');
1747                        dropBuilder.append(logBuilder);
1748                        dropBuilder.append('\n');
1749                        /*
1750                        dropBuilder.append(oomString);
1751                        dropBuilder.append('\n');
1752                        */
1753                        StringWriter catSw = new StringWriter();
1754                        synchronized (ActivityManagerService.this) {
1755                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1756                            String[] emptyArgs = new String[] { };
1757                            catPw.println();
1758                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1759                            catPw.println();
1760                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1761                                    false, false, null);
1762                            catPw.println();
1763                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1764                            catPw.flush();
1765                        }
1766                        dropBuilder.append(catSw.toString());
1767                        addErrorToDropBox("lowmem", null, "system_server", null,
1768                                null, tag.toString(), dropBuilder.toString(), null, null);
1769                        //Slog.i(TAG, "Sent to dropbox:");
1770                        //Slog.i(TAG, dropBuilder.toString());
1771                        synchronized (ActivityManagerService.this) {
1772                            long now = SystemClock.uptimeMillis();
1773                            if (mLastMemUsageReportTime < now) {
1774                                mLastMemUsageReportTime = now;
1775                            }
1776                        }
1777                    }
1778                };
1779                thread.start();
1780                break;
1781            }
1782            case START_USER_SWITCH_MSG: {
1783                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1784                break;
1785            }
1786            case REPORT_USER_SWITCH_MSG: {
1787                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1788                break;
1789            }
1790            case CONTINUE_USER_SWITCH_MSG: {
1791                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1792                break;
1793            }
1794            case USER_SWITCH_TIMEOUT_MSG: {
1795                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1796                break;
1797            }
1798            case IMMERSIVE_MODE_LOCK_MSG: {
1799                final boolean nextState = (msg.arg1 != 0);
1800                if (mUpdateLock.isHeld() != nextState) {
1801                    if (DEBUG_IMMERSIVE) {
1802                        final ActivityRecord r = (ActivityRecord) msg.obj;
1803                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1804                    }
1805                    if (nextState) {
1806                        mUpdateLock.acquire();
1807                    } else {
1808                        mUpdateLock.release();
1809                    }
1810                }
1811                break;
1812            }
1813            case PERSIST_URI_GRANTS_MSG: {
1814                writeGrantedUriPermissions();
1815                break;
1816            }
1817            case REQUEST_ALL_PSS_MSG: {
1818                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1819                break;
1820            }
1821            case START_PROFILES_MSG: {
1822                synchronized (ActivityManagerService.this) {
1823                    startProfilesLocked();
1824                }
1825                break;
1826            }
1827            case UPDATE_TIME: {
1828                synchronized (ActivityManagerService.this) {
1829                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1830                        ProcessRecord r = mLruProcesses.get(i);
1831                        if (r.thread != null) {
1832                            try {
1833                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1834                            } catch (RemoteException ex) {
1835                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1836                            }
1837                        }
1838                    }
1839                }
1840                break;
1841            }
1842            case SYSTEM_USER_START_MSG: {
1843                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1844                        Integer.toString(msg.arg1), msg.arg1);
1845                mSystemServiceManager.startUser(msg.arg1);
1846                break;
1847            }
1848            case SYSTEM_USER_CURRENT_MSG: {
1849                mBatteryStatsService.noteEvent(
1850                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1851                        Integer.toString(msg.arg2), msg.arg2);
1852                mBatteryStatsService.noteEvent(
1853                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1854                        Integer.toString(msg.arg1), msg.arg1);
1855                mSystemServiceManager.switchUser(msg.arg1);
1856                mLockToAppRequest.clearPrompt();
1857                break;
1858            }
1859            case ENTER_ANIMATION_COMPLETE_MSG: {
1860                synchronized (ActivityManagerService.this) {
1861                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1862                    if (r != null && r.app != null && r.app.thread != null) {
1863                        try {
1864                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1865                        } catch (RemoteException e) {
1866                        }
1867                    }
1868                }
1869                break;
1870            }
1871            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1872                enableScreenAfterBoot();
1873                break;
1874            }
1875            }
1876        }
1877    };
1878
1879    static final int COLLECT_PSS_BG_MSG = 1;
1880
1881    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1882        @Override
1883        public void handleMessage(Message msg) {
1884            switch (msg.what) {
1885            case COLLECT_PSS_BG_MSG: {
1886                long start = SystemClock.uptimeMillis();
1887                MemInfoReader memInfo = null;
1888                synchronized (ActivityManagerService.this) {
1889                    if (mFullPssPending) {
1890                        mFullPssPending = false;
1891                        memInfo = new MemInfoReader();
1892                    }
1893                }
1894                if (memInfo != null) {
1895                    updateCpuStatsNow();
1896                    long nativeTotalPss = 0;
1897                    synchronized (mProcessCpuThread) {
1898                        final int N = mProcessCpuTracker.countStats();
1899                        for (int j=0; j<N; j++) {
1900                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1901                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1902                                // This is definitely an application process; skip it.
1903                                continue;
1904                            }
1905                            synchronized (mPidsSelfLocked) {
1906                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1907                                    // This is one of our own processes; skip it.
1908                                    continue;
1909                                }
1910                            }
1911                            nativeTotalPss += Debug.getPss(st.pid, null);
1912                        }
1913                    }
1914                    memInfo.readMemInfo();
1915                    synchronized (this) {
1916                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1917                                + (SystemClock.uptimeMillis()-start) + "ms");
1918                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1919                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1920                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1921                                        +memInfo.getSlabSizeKb(),
1922                                nativeTotalPss);
1923                    }
1924                }
1925
1926                int i=0, num=0;
1927                long[] tmp = new long[1];
1928                do {
1929                    ProcessRecord proc;
1930                    int procState;
1931                    int pid;
1932                    synchronized (ActivityManagerService.this) {
1933                        if (i >= mPendingPssProcesses.size()) {
1934                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1935                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1936                            mPendingPssProcesses.clear();
1937                            return;
1938                        }
1939                        proc = mPendingPssProcesses.get(i);
1940                        procState = proc.pssProcState;
1941                        if (proc.thread != null && procState == proc.setProcState) {
1942                            pid = proc.pid;
1943                        } else {
1944                            proc = null;
1945                            pid = 0;
1946                        }
1947                        i++;
1948                    }
1949                    if (proc != null) {
1950                        long pss = Debug.getPss(pid, tmp);
1951                        synchronized (ActivityManagerService.this) {
1952                            if (proc.thread != null && proc.setProcState == procState
1953                                    && proc.pid == pid) {
1954                                num++;
1955                                proc.lastPssTime = SystemClock.uptimeMillis();
1956                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1957                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1958                                        + ": " + pss + " lastPss=" + proc.lastPss
1959                                        + " state=" + ProcessList.makeProcStateString(procState));
1960                                if (proc.initialIdlePss == 0) {
1961                                    proc.initialIdlePss = pss;
1962                                }
1963                                proc.lastPss = pss;
1964                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1965                                    proc.lastCachedPss = pss;
1966                                }
1967                            }
1968                        }
1969                    }
1970                } while (true);
1971            }
1972            }
1973        }
1974    };
1975
1976    /**
1977     * Monitor for package changes and update our internal state.
1978     */
1979    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1980        @Override
1981        public void onPackageRemoved(String packageName, int uid) {
1982            // Remove all tasks with activities in the specified package from the list of recent tasks
1983            synchronized (ActivityManagerService.this) {
1984                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1985                    TaskRecord tr = mRecentTasks.get(i);
1986                    ComponentName cn = tr.intent.getComponent();
1987                    if (cn != null && cn.getPackageName().equals(packageName)) {
1988                        // If the package name matches, remove the task and kill the process
1989                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1990                    }
1991                }
1992            }
1993        }
1994
1995        @Override
1996        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1997            onPackageModified(packageName);
1998            return true;
1999        }
2000
2001        @Override
2002        public void onPackageModified(String packageName) {
2003            final PackageManager pm = mContext.getPackageManager();
2004            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2005                    new ArrayList<Pair<Intent, Integer>>();
2006            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2007            // Copy the list of recent tasks so that we don't hold onto the lock on
2008            // ActivityManagerService for long periods while checking if components exist.
2009            synchronized (ActivityManagerService.this) {
2010                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2011                    TaskRecord tr = mRecentTasks.get(i);
2012                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2013                }
2014            }
2015            // Check the recent tasks and filter out all tasks with components that no longer exist.
2016            Intent tmpI = new Intent();
2017            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2018                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2019                ComponentName cn = p.first.getComponent();
2020                if (cn != null && cn.getPackageName().equals(packageName)) {
2021                    try {
2022                        // Add the task to the list to remove if the component no longer exists
2023                        tmpI.setComponent(cn);
2024                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2025                            tasksToRemove.add(p.second);
2026                        }
2027                    } catch (Exception e) {}
2028                }
2029            }
2030            // Prune all the tasks with removed components from the list of recent tasks
2031            synchronized (ActivityManagerService.this) {
2032                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2033                    // Remove the task but don't kill the process (since other components in that
2034                    // package may still be running and in the background)
2035                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2036                }
2037            }
2038        }
2039
2040        @Override
2041        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2042            // Force stop the specified packages
2043            if (packages != null) {
2044                for (String pkg : packages) {
2045                    synchronized (ActivityManagerService.this) {
2046                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2047                                "finished booting")) {
2048                            return true;
2049                        }
2050                    }
2051                }
2052            }
2053            return false;
2054        }
2055    };
2056
2057    public void setSystemProcess() {
2058        try {
2059            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2060            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2061            ServiceManager.addService("meminfo", new MemBinder(this));
2062            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2063            ServiceManager.addService("dbinfo", new DbBinder(this));
2064            if (MONITOR_CPU_USAGE) {
2065                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2066            }
2067            ServiceManager.addService("permission", new PermissionController(this));
2068
2069            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2070                    "android", STOCK_PM_FLAGS);
2071            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2072
2073            synchronized (this) {
2074                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2075                app.persistent = true;
2076                app.pid = MY_PID;
2077                app.maxAdj = ProcessList.SYSTEM_ADJ;
2078                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2079                mProcessNames.put(app.processName, app.uid, app);
2080                synchronized (mPidsSelfLocked) {
2081                    mPidsSelfLocked.put(app.pid, app);
2082                }
2083                updateLruProcessLocked(app, false, null);
2084                updateOomAdjLocked();
2085            }
2086        } catch (PackageManager.NameNotFoundException e) {
2087            throw new RuntimeException(
2088                    "Unable to find android system package", e);
2089        }
2090    }
2091
2092    public void setWindowManager(WindowManagerService wm) {
2093        mWindowManager = wm;
2094        mStackSupervisor.setWindowManager(wm);
2095    }
2096
2097    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2098        mUsageStatsService = usageStatsManager;
2099    }
2100
2101    public void startObservingNativeCrashes() {
2102        final NativeCrashListener ncl = new NativeCrashListener(this);
2103        ncl.start();
2104    }
2105
2106    public IAppOpsService getAppOpsService() {
2107        return mAppOpsService;
2108    }
2109
2110    static class MemBinder extends Binder {
2111        ActivityManagerService mActivityManagerService;
2112        MemBinder(ActivityManagerService activityManagerService) {
2113            mActivityManagerService = activityManagerService;
2114        }
2115
2116        @Override
2117        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2118            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2119                    != PackageManager.PERMISSION_GRANTED) {
2120                pw.println("Permission Denial: can't dump meminfo from from pid="
2121                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2122                        + " without permission " + android.Manifest.permission.DUMP);
2123                return;
2124            }
2125
2126            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2127        }
2128    }
2129
2130    static class GraphicsBinder extends Binder {
2131        ActivityManagerService mActivityManagerService;
2132        GraphicsBinder(ActivityManagerService activityManagerService) {
2133            mActivityManagerService = activityManagerService;
2134        }
2135
2136        @Override
2137        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2138            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2139                    != PackageManager.PERMISSION_GRANTED) {
2140                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2141                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2142                        + " without permission " + android.Manifest.permission.DUMP);
2143                return;
2144            }
2145
2146            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2147        }
2148    }
2149
2150    static class DbBinder extends Binder {
2151        ActivityManagerService mActivityManagerService;
2152        DbBinder(ActivityManagerService activityManagerService) {
2153            mActivityManagerService = activityManagerService;
2154        }
2155
2156        @Override
2157        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2158            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2159                    != PackageManager.PERMISSION_GRANTED) {
2160                pw.println("Permission Denial: can't dump dbinfo from from pid="
2161                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2162                        + " without permission " + android.Manifest.permission.DUMP);
2163                return;
2164            }
2165
2166            mActivityManagerService.dumpDbInfo(fd, pw, args);
2167        }
2168    }
2169
2170    static class CpuBinder extends Binder {
2171        ActivityManagerService mActivityManagerService;
2172        CpuBinder(ActivityManagerService activityManagerService) {
2173            mActivityManagerService = activityManagerService;
2174        }
2175
2176        @Override
2177        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2178            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2179                    != PackageManager.PERMISSION_GRANTED) {
2180                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2181                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2182                        + " without permission " + android.Manifest.permission.DUMP);
2183                return;
2184            }
2185
2186            synchronized (mActivityManagerService.mProcessCpuThread) {
2187                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2188                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2189                        SystemClock.uptimeMillis()));
2190            }
2191        }
2192    }
2193
2194    public static final class Lifecycle extends SystemService {
2195        private final ActivityManagerService mService;
2196
2197        public Lifecycle(Context context) {
2198            super(context);
2199            mService = new ActivityManagerService(context);
2200        }
2201
2202        @Override
2203        public void onStart() {
2204            mService.start();
2205        }
2206
2207        public ActivityManagerService getService() {
2208            return mService;
2209        }
2210    }
2211
2212    // Note: This method is invoked on the main thread but may need to attach various
2213    // handlers to other threads.  So take care to be explicit about the looper.
2214    public ActivityManagerService(Context systemContext) {
2215        mContext = systemContext;
2216        mFactoryTest = FactoryTest.getMode();
2217        mSystemThread = ActivityThread.currentActivityThread();
2218
2219        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2220
2221        mHandlerThread = new ServiceThread(TAG,
2222                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2223        mHandlerThread.start();
2224        mHandler = new MainHandler(mHandlerThread.getLooper());
2225
2226        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2227                "foreground", BROADCAST_FG_TIMEOUT, false);
2228        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2229                "background", BROADCAST_BG_TIMEOUT, true);
2230        mBroadcastQueues[0] = mFgBroadcastQueue;
2231        mBroadcastQueues[1] = mBgBroadcastQueue;
2232
2233        mServices = new ActiveServices(this);
2234        mProviderMap = new ProviderMap(this);
2235
2236        // TODO: Move creation of battery stats service outside of activity manager service.
2237        File dataDir = Environment.getDataDirectory();
2238        File systemDir = new File(dataDir, "system");
2239        systemDir.mkdirs();
2240        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2241        mBatteryStatsService.getActiveStatistics().readLocked();
2242        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2243        mOnBattery = DEBUG_POWER ? true
2244                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2245        mBatteryStatsService.getActiveStatistics().setCallback(this);
2246
2247        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2248
2249        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2250
2251        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2252
2253        // User 0 is the first and only user that runs at boot.
2254        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2255        mUserLru.add(Integer.valueOf(0));
2256        updateStartedUserArrayLocked();
2257
2258        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2259            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2260
2261        mConfiguration.setToDefaults();
2262        mConfiguration.setLocale(Locale.getDefault());
2263
2264        mConfigurationSeq = mConfiguration.seq = 1;
2265        mProcessCpuTracker.init();
2266
2267        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2268        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2269        mStackSupervisor = new ActivityStackSupervisor(this);
2270        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2271
2272        mProcessCpuThread = new Thread("CpuTracker") {
2273            @Override
2274            public void run() {
2275                while (true) {
2276                    try {
2277                        try {
2278                            synchronized(this) {
2279                                final long now = SystemClock.uptimeMillis();
2280                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2281                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2282                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2283                                //        + ", write delay=" + nextWriteDelay);
2284                                if (nextWriteDelay < nextCpuDelay) {
2285                                    nextCpuDelay = nextWriteDelay;
2286                                }
2287                                if (nextCpuDelay > 0) {
2288                                    mProcessCpuMutexFree.set(true);
2289                                    this.wait(nextCpuDelay);
2290                                }
2291                            }
2292                        } catch (InterruptedException e) {
2293                        }
2294                        updateCpuStatsNow();
2295                    } catch (Exception e) {
2296                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2297                    }
2298                }
2299            }
2300        };
2301
2302        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2303
2304        Watchdog.getInstance().addMonitor(this);
2305        Watchdog.getInstance().addThread(mHandler);
2306    }
2307
2308    public void setSystemServiceManager(SystemServiceManager mgr) {
2309        mSystemServiceManager = mgr;
2310    }
2311
2312    private void start() {
2313        Process.removeAllProcessGroups();
2314        mProcessCpuThread.start();
2315
2316        mBatteryStatsService.publish(mContext);
2317        mAppOpsService.publish(mContext);
2318        Slog.d("AppOps", "AppOpsService published");
2319        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2320    }
2321
2322    public void initPowerManagement() {
2323        mStackSupervisor.initPowerManagement();
2324        mBatteryStatsService.initPowerManagement();
2325    }
2326
2327    @Override
2328    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2329            throws RemoteException {
2330        if (code == SYSPROPS_TRANSACTION) {
2331            // We need to tell all apps about the system property change.
2332            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2333            synchronized(this) {
2334                final int NP = mProcessNames.getMap().size();
2335                for (int ip=0; ip<NP; ip++) {
2336                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2337                    final int NA = apps.size();
2338                    for (int ia=0; ia<NA; ia++) {
2339                        ProcessRecord app = apps.valueAt(ia);
2340                        if (app.thread != null) {
2341                            procs.add(app.thread.asBinder());
2342                        }
2343                    }
2344                }
2345            }
2346
2347            int N = procs.size();
2348            for (int i=0; i<N; i++) {
2349                Parcel data2 = Parcel.obtain();
2350                try {
2351                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2352                } catch (RemoteException e) {
2353                }
2354                data2.recycle();
2355            }
2356        }
2357        try {
2358            return super.onTransact(code, data, reply, flags);
2359        } catch (RuntimeException e) {
2360            // The activity manager only throws security exceptions, so let's
2361            // log all others.
2362            if (!(e instanceof SecurityException)) {
2363                Slog.wtf(TAG, "Activity Manager Crash", e);
2364            }
2365            throw e;
2366        }
2367    }
2368
2369    void updateCpuStats() {
2370        final long now = SystemClock.uptimeMillis();
2371        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2372            return;
2373        }
2374        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2375            synchronized (mProcessCpuThread) {
2376                mProcessCpuThread.notify();
2377            }
2378        }
2379    }
2380
2381    void updateCpuStatsNow() {
2382        synchronized (mProcessCpuThread) {
2383            mProcessCpuMutexFree.set(false);
2384            final long now = SystemClock.uptimeMillis();
2385            boolean haveNewCpuStats = false;
2386
2387            if (MONITOR_CPU_USAGE &&
2388                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2389                mLastCpuTime.set(now);
2390                haveNewCpuStats = true;
2391                mProcessCpuTracker.update();
2392                //Slog.i(TAG, mProcessCpu.printCurrentState());
2393                //Slog.i(TAG, "Total CPU usage: "
2394                //        + mProcessCpu.getTotalCpuPercent() + "%");
2395
2396                // Slog the cpu usage if the property is set.
2397                if ("true".equals(SystemProperties.get("events.cpu"))) {
2398                    int user = mProcessCpuTracker.getLastUserTime();
2399                    int system = mProcessCpuTracker.getLastSystemTime();
2400                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2401                    int irq = mProcessCpuTracker.getLastIrqTime();
2402                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2403                    int idle = mProcessCpuTracker.getLastIdleTime();
2404
2405                    int total = user + system + iowait + irq + softIrq + idle;
2406                    if (total == 0) total = 1;
2407
2408                    EventLog.writeEvent(EventLogTags.CPU,
2409                            ((user+system+iowait+irq+softIrq) * 100) / total,
2410                            (user * 100) / total,
2411                            (system * 100) / total,
2412                            (iowait * 100) / total,
2413                            (irq * 100) / total,
2414                            (softIrq * 100) / total);
2415                }
2416            }
2417
2418            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2419            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2420            synchronized(bstats) {
2421                synchronized(mPidsSelfLocked) {
2422                    if (haveNewCpuStats) {
2423                        if (mOnBattery) {
2424                            int perc = bstats.startAddingCpuLocked();
2425                            int totalUTime = 0;
2426                            int totalSTime = 0;
2427                            final int N = mProcessCpuTracker.countStats();
2428                            for (int i=0; i<N; i++) {
2429                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2430                                if (!st.working) {
2431                                    continue;
2432                                }
2433                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2434                                int otherUTime = (st.rel_utime*perc)/100;
2435                                int otherSTime = (st.rel_stime*perc)/100;
2436                                totalUTime += otherUTime;
2437                                totalSTime += otherSTime;
2438                                if (pr != null) {
2439                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2440                                    if (ps == null || !ps.isActive()) {
2441                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2442                                                pr.info.uid, pr.processName);
2443                                    }
2444                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2445                                            st.rel_stime-otherSTime);
2446                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2447                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2448                                } else {
2449                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2450                                    if (ps == null || !ps.isActive()) {
2451                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2452                                                bstats.mapUid(st.uid), st.name);
2453                                    }
2454                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2455                                            st.rel_stime-otherSTime);
2456                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2457                                }
2458                            }
2459                            bstats.finishAddingCpuLocked(perc, totalUTime,
2460                                    totalSTime, cpuSpeedTimes);
2461                        }
2462                    }
2463                }
2464
2465                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2466                    mLastWriteTime = now;
2467                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2468                }
2469            }
2470        }
2471    }
2472
2473    @Override
2474    public void batteryNeedsCpuUpdate() {
2475        updateCpuStatsNow();
2476    }
2477
2478    @Override
2479    public void batteryPowerChanged(boolean onBattery) {
2480        // When plugging in, update the CPU stats first before changing
2481        // the plug state.
2482        updateCpuStatsNow();
2483        synchronized (this) {
2484            synchronized(mPidsSelfLocked) {
2485                mOnBattery = DEBUG_POWER ? true : onBattery;
2486            }
2487        }
2488    }
2489
2490    /**
2491     * Initialize the application bind args. These are passed to each
2492     * process when the bindApplication() IPC is sent to the process. They're
2493     * lazily setup to make sure the services are running when they're asked for.
2494     */
2495    private HashMap<String, IBinder> getCommonServicesLocked() {
2496        if (mAppBindArgs == null) {
2497            mAppBindArgs = new HashMap<String, IBinder>();
2498
2499            // Setup the application init args
2500            mAppBindArgs.put("package", ServiceManager.getService("package"));
2501            mAppBindArgs.put("window", ServiceManager.getService("window"));
2502            mAppBindArgs.put(Context.ALARM_SERVICE,
2503                    ServiceManager.getService(Context.ALARM_SERVICE));
2504        }
2505        return mAppBindArgs;
2506    }
2507
2508    final void setFocusedActivityLocked(ActivityRecord r) {
2509        if (mFocusedActivity != r) {
2510            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2511            mFocusedActivity = r;
2512            if (r.task != null && r.task.voiceInteractor != null) {
2513                startRunningVoiceLocked();
2514            } else {
2515                finishRunningVoiceLocked();
2516            }
2517            mStackSupervisor.setFocusedStack(r);
2518            if (r != null) {
2519                mWindowManager.setFocusedApp(r.appToken, true);
2520            }
2521            applyUpdateLockStateLocked(r);
2522        }
2523    }
2524
2525    final void clearFocusedActivity(ActivityRecord r) {
2526        if (mFocusedActivity == r) {
2527            mFocusedActivity = null;
2528        }
2529    }
2530
2531    @Override
2532    public void setFocusedStack(int stackId) {
2533        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2534        synchronized (ActivityManagerService.this) {
2535            ActivityStack stack = mStackSupervisor.getStack(stackId);
2536            if (stack != null) {
2537                ActivityRecord r = stack.topRunningActivityLocked(null);
2538                if (r != null) {
2539                    setFocusedActivityLocked(r);
2540                }
2541            }
2542        }
2543    }
2544
2545    @Override
2546    public void notifyActivityDrawn(IBinder token) {
2547        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2548        synchronized (this) {
2549            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2550            if (r != null) {
2551                r.task.stack.notifyActivityDrawnLocked(r);
2552            }
2553        }
2554    }
2555
2556    final void applyUpdateLockStateLocked(ActivityRecord r) {
2557        // Modifications to the UpdateLock state are done on our handler, outside
2558        // the activity manager's locks.  The new state is determined based on the
2559        // state *now* of the relevant activity record.  The object is passed to
2560        // the handler solely for logging detail, not to be consulted/modified.
2561        final boolean nextState = r != null && r.immersive;
2562        mHandler.sendMessage(
2563                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2564    }
2565
2566    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2567        Message msg = Message.obtain();
2568        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2569        msg.obj = r.task.askedCompatMode ? null : r;
2570        mHandler.sendMessage(msg);
2571    }
2572
2573    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2574            String what, Object obj, ProcessRecord srcApp) {
2575        app.lastActivityTime = now;
2576
2577        if (app.activities.size() > 0) {
2578            // Don't want to touch dependent processes that are hosting activities.
2579            return index;
2580        }
2581
2582        int lrui = mLruProcesses.lastIndexOf(app);
2583        if (lrui < 0) {
2584            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2585                    + what + " " + obj + " from " + srcApp);
2586            return index;
2587        }
2588
2589        if (lrui >= index) {
2590            // Don't want to cause this to move dependent processes *back* in the
2591            // list as if they were less frequently used.
2592            return index;
2593        }
2594
2595        if (lrui >= mLruProcessActivityStart) {
2596            // Don't want to touch dependent processes that are hosting activities.
2597            return index;
2598        }
2599
2600        mLruProcesses.remove(lrui);
2601        if (index > 0) {
2602            index--;
2603        }
2604        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2605                + " in LRU list: " + app);
2606        mLruProcesses.add(index, app);
2607        return index;
2608    }
2609
2610    final void removeLruProcessLocked(ProcessRecord app) {
2611        int lrui = mLruProcesses.lastIndexOf(app);
2612        if (lrui >= 0) {
2613            if (lrui <= mLruProcessActivityStart) {
2614                mLruProcessActivityStart--;
2615            }
2616            if (lrui <= mLruProcessServiceStart) {
2617                mLruProcessServiceStart--;
2618            }
2619            mLruProcesses.remove(lrui);
2620        }
2621    }
2622
2623    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2624            ProcessRecord client) {
2625        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2626                || app.treatLikeActivity;
2627        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2628        if (!activityChange && hasActivity) {
2629            // The process has activities, so we are only allowing activity-based adjustments
2630            // to move it.  It should be kept in the front of the list with other
2631            // processes that have activities, and we don't want those to change their
2632            // order except due to activity operations.
2633            return;
2634        }
2635
2636        mLruSeq++;
2637        final long now = SystemClock.uptimeMillis();
2638        app.lastActivityTime = now;
2639
2640        // First a quick reject: if the app is already at the position we will
2641        // put it, then there is nothing to do.
2642        if (hasActivity) {
2643            final int N = mLruProcesses.size();
2644            if (N > 0 && mLruProcesses.get(N-1) == app) {
2645                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2646                return;
2647            }
2648        } else {
2649            if (mLruProcessServiceStart > 0
2650                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2651                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2652                return;
2653            }
2654        }
2655
2656        int lrui = mLruProcesses.lastIndexOf(app);
2657
2658        if (app.persistent && lrui >= 0) {
2659            // We don't care about the position of persistent processes, as long as
2660            // they are in the list.
2661            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2662            return;
2663        }
2664
2665        /* In progress: compute new position first, so we can avoid doing work
2666           if the process is not actually going to move.  Not yet working.
2667        int addIndex;
2668        int nextIndex;
2669        boolean inActivity = false, inService = false;
2670        if (hasActivity) {
2671            // Process has activities, put it at the very tipsy-top.
2672            addIndex = mLruProcesses.size();
2673            nextIndex = mLruProcessServiceStart;
2674            inActivity = true;
2675        } else if (hasService) {
2676            // Process has services, put it at the top of the service list.
2677            addIndex = mLruProcessActivityStart;
2678            nextIndex = mLruProcessServiceStart;
2679            inActivity = true;
2680            inService = true;
2681        } else  {
2682            // Process not otherwise of interest, it goes to the top of the non-service area.
2683            addIndex = mLruProcessServiceStart;
2684            if (client != null) {
2685                int clientIndex = mLruProcesses.lastIndexOf(client);
2686                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2687                        + app);
2688                if (clientIndex >= 0 && addIndex > clientIndex) {
2689                    addIndex = clientIndex;
2690                }
2691            }
2692            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2693        }
2694
2695        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2696                + mLruProcessActivityStart + "): " + app);
2697        */
2698
2699        if (lrui >= 0) {
2700            if (lrui < mLruProcessActivityStart) {
2701                mLruProcessActivityStart--;
2702            }
2703            if (lrui < mLruProcessServiceStart) {
2704                mLruProcessServiceStart--;
2705            }
2706            /*
2707            if (addIndex > lrui) {
2708                addIndex--;
2709            }
2710            if (nextIndex > lrui) {
2711                nextIndex--;
2712            }
2713            */
2714            mLruProcesses.remove(lrui);
2715        }
2716
2717        /*
2718        mLruProcesses.add(addIndex, app);
2719        if (inActivity) {
2720            mLruProcessActivityStart++;
2721        }
2722        if (inService) {
2723            mLruProcessActivityStart++;
2724        }
2725        */
2726
2727        int nextIndex;
2728        if (hasActivity) {
2729            final int N = mLruProcesses.size();
2730            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2731                // Process doesn't have activities, but has clients with
2732                // activities...  move it up, but one below the top (the top
2733                // should always have a real activity).
2734                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2735                mLruProcesses.add(N-1, app);
2736                // To keep it from spamming the LRU list (by making a bunch of clients),
2737                // we will push down any other entries owned by the app.
2738                final int uid = app.info.uid;
2739                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2740                    ProcessRecord subProc = mLruProcesses.get(i);
2741                    if (subProc.info.uid == uid) {
2742                        // We want to push this one down the list.  If the process after
2743                        // it is for the same uid, however, don't do so, because we don't
2744                        // want them internally to be re-ordered.
2745                        if (mLruProcesses.get(i-1).info.uid != uid) {
2746                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2747                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2748                            ProcessRecord tmp = mLruProcesses.get(i);
2749                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2750                            mLruProcesses.set(i-1, tmp);
2751                            i--;
2752                        }
2753                    } else {
2754                        // A gap, we can stop here.
2755                        break;
2756                    }
2757                }
2758            } else {
2759                // Process has activities, put it at the very tipsy-top.
2760                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2761                mLruProcesses.add(app);
2762            }
2763            nextIndex = mLruProcessServiceStart;
2764        } else if (hasService) {
2765            // Process has services, put it at the top of the service list.
2766            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2767            mLruProcesses.add(mLruProcessActivityStart, app);
2768            nextIndex = mLruProcessServiceStart;
2769            mLruProcessActivityStart++;
2770        } else  {
2771            // Process not otherwise of interest, it goes to the top of the non-service area.
2772            int index = mLruProcessServiceStart;
2773            if (client != null) {
2774                // If there is a client, don't allow the process to be moved up higher
2775                // in the list than that client.
2776                int clientIndex = mLruProcesses.lastIndexOf(client);
2777                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2778                        + " when updating " + app);
2779                if (clientIndex <= lrui) {
2780                    // Don't allow the client index restriction to push it down farther in the
2781                    // list than it already is.
2782                    clientIndex = lrui;
2783                }
2784                if (clientIndex >= 0 && index > clientIndex) {
2785                    index = clientIndex;
2786                }
2787            }
2788            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2789            mLruProcesses.add(index, app);
2790            nextIndex = index-1;
2791            mLruProcessActivityStart++;
2792            mLruProcessServiceStart++;
2793        }
2794
2795        // If the app is currently using a content provider or service,
2796        // bump those processes as well.
2797        for (int j=app.connections.size()-1; j>=0; j--) {
2798            ConnectionRecord cr = app.connections.valueAt(j);
2799            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2800                    && cr.binding.service.app != null
2801                    && cr.binding.service.app.lruSeq != mLruSeq
2802                    && !cr.binding.service.app.persistent) {
2803                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2804                        "service connection", cr, app);
2805            }
2806        }
2807        for (int j=app.conProviders.size()-1; j>=0; j--) {
2808            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2809            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2810                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2811                        "provider reference", cpr, app);
2812            }
2813        }
2814    }
2815
2816    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2817        if (uid == Process.SYSTEM_UID) {
2818            // The system gets to run in any process.  If there are multiple
2819            // processes with the same uid, just pick the first (this
2820            // should never happen).
2821            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2822            if (procs == null) return null;
2823            final int N = procs.size();
2824            for (int i = 0; i < N; i++) {
2825                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2826            }
2827        }
2828        ProcessRecord proc = mProcessNames.get(processName, uid);
2829        if (false && proc != null && !keepIfLarge
2830                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2831                && proc.lastCachedPss >= 4000) {
2832            // Turn this condition on to cause killing to happen regularly, for testing.
2833            if (proc.baseProcessTracker != null) {
2834                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2835            }
2836            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2837        } else if (proc != null && !keepIfLarge
2838                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2839                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2840            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2841            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2842                if (proc.baseProcessTracker != null) {
2843                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2844                }
2845                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2846            }
2847        }
2848        return proc;
2849    }
2850
2851    void ensurePackageDexOpt(String packageName) {
2852        IPackageManager pm = AppGlobals.getPackageManager();
2853        try {
2854            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2855                mDidDexOpt = true;
2856            }
2857        } catch (RemoteException e) {
2858        }
2859    }
2860
2861    boolean isNextTransitionForward() {
2862        int transit = mWindowManager.getPendingAppTransition();
2863        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_OPEN
2865                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2866    }
2867
2868    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2869            String processName, String abiOverride, int uid, Runnable crashHandler) {
2870        synchronized(this) {
2871            ApplicationInfo info = new ApplicationInfo();
2872            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2873            // For isolated processes, the former contains the parent's uid and the latter the
2874            // actual uid of the isolated process.
2875            // In the special case introduced by this method (which is, starting an isolated
2876            // process directly from the SystemServer without an actual parent app process) the
2877            // closest thing to a parent's uid is SYSTEM_UID.
2878            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2879            // the |isolated| logic in the ProcessRecord constructor.
2880            info.uid = Process.SYSTEM_UID;
2881            info.processName = processName;
2882            info.className = entryPoint;
2883            info.packageName = "android";
2884            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2885                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2886                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2887                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2888                    crashHandler);
2889            return proc != null ? proc.pid : 0;
2890        }
2891    }
2892
2893    final ProcessRecord startProcessLocked(String processName,
2894            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2895            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2896            boolean isolated, boolean keepIfLarge) {
2897        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2898                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2899                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2900                null /* crashHandler */);
2901    }
2902
2903    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2904            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2905            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2906            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2907        long startTime = SystemClock.elapsedRealtime();
2908        ProcessRecord app;
2909        if (!isolated) {
2910            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2911            checkTime(startTime, "startProcess: after getProcessRecord");
2912        } else {
2913            // If this is an isolated process, it can't re-use an existing process.
2914            app = null;
2915        }
2916        // We don't have to do anything more if:
2917        // (1) There is an existing application record; and
2918        // (2) The caller doesn't think it is dead, OR there is no thread
2919        //     object attached to it so we know it couldn't have crashed; and
2920        // (3) There is a pid assigned to it, so it is either starting or
2921        //     already running.
2922        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2923                + " app=" + app + " knownToBeDead=" + knownToBeDead
2924                + " thread=" + (app != null ? app.thread : null)
2925                + " pid=" + (app != null ? app.pid : -1));
2926        if (app != null && app.pid > 0) {
2927            if (!knownToBeDead || app.thread == null) {
2928                // We already have the app running, or are waiting for it to
2929                // come up (we have a pid but not yet its thread), so keep it.
2930                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2931                // If this is a new package in the process, add the package to the list
2932                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2933                checkTime(startTime, "startProcess: done, added package to proc");
2934                return app;
2935            }
2936
2937            // An application record is attached to a previous process,
2938            // clean it up now.
2939            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2940            checkTime(startTime, "startProcess: bad proc running, killing");
2941            Process.killProcessGroup(app.info.uid, app.pid);
2942            handleAppDiedLocked(app, true, true);
2943            checkTime(startTime, "startProcess: done killing old proc");
2944        }
2945
2946        String hostingNameStr = hostingName != null
2947                ? hostingName.flattenToShortString() : null;
2948
2949        if (!isolated) {
2950            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2951                // If we are in the background, then check to see if this process
2952                // is bad.  If so, we will just silently fail.
2953                if (mBadProcesses.get(info.processName, info.uid) != null) {
2954                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2955                            + "/" + info.processName);
2956                    return null;
2957                }
2958            } else {
2959                // When the user is explicitly starting a process, then clear its
2960                // crash count so that we won't make it bad until they see at
2961                // least one crash dialog again, and make the process good again
2962                // if it had been bad.
2963                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2964                        + "/" + info.processName);
2965                mProcessCrashTimes.remove(info.processName, info.uid);
2966                if (mBadProcesses.get(info.processName, info.uid) != null) {
2967                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2968                            UserHandle.getUserId(info.uid), info.uid,
2969                            info.processName);
2970                    mBadProcesses.remove(info.processName, info.uid);
2971                    if (app != null) {
2972                        app.bad = false;
2973                    }
2974                }
2975            }
2976        }
2977
2978        if (app == null) {
2979            checkTime(startTime, "startProcess: creating new process record");
2980            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2981            app.crashHandler = crashHandler;
2982            if (app == null) {
2983                Slog.w(TAG, "Failed making new process record for "
2984                        + processName + "/" + info.uid + " isolated=" + isolated);
2985                return null;
2986            }
2987            mProcessNames.put(processName, app.uid, app);
2988            if (isolated) {
2989                mIsolatedProcesses.put(app.uid, app);
2990            }
2991            checkTime(startTime, "startProcess: done creating new process record");
2992        } else {
2993            // If this is a new package in the process, add the package to the list
2994            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2995            checkTime(startTime, "startProcess: added package to existing proc");
2996        }
2997
2998        // If the system is not ready yet, then hold off on starting this
2999        // process until it is.
3000        if (!mProcessesReady
3001                && !isAllowedWhileBooting(info)
3002                && !allowWhileBooting) {
3003            if (!mProcessesOnHold.contains(app)) {
3004                mProcessesOnHold.add(app);
3005            }
3006            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3007            checkTime(startTime, "startProcess: returning with proc on hold");
3008            return app;
3009        }
3010
3011        checkTime(startTime, "startProcess: stepping in to startProcess");
3012        startProcessLocked(
3013                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3014        checkTime(startTime, "startProcess: done starting proc!");
3015        return (app.pid != 0) ? app : null;
3016    }
3017
3018    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3019        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3020    }
3021
3022    private final void startProcessLocked(ProcessRecord app,
3023            String hostingType, String hostingNameStr) {
3024        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3025                null /* entryPoint */, null /* entryPointArgs */);
3026    }
3027
3028    private final void startProcessLocked(ProcessRecord app, String hostingType,
3029            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3030        long startTime = SystemClock.elapsedRealtime();
3031        if (app.pid > 0 && app.pid != MY_PID) {
3032            checkTime(startTime, "startProcess: removing from pids map");
3033            synchronized (mPidsSelfLocked) {
3034                mPidsSelfLocked.remove(app.pid);
3035                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3036            }
3037            checkTime(startTime, "startProcess: done removing from pids map");
3038            app.setPid(0);
3039        }
3040
3041        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3042                "startProcessLocked removing on hold: " + app);
3043        mProcessesOnHold.remove(app);
3044
3045        checkTime(startTime, "startProcess: starting to update cpu stats");
3046        updateCpuStats();
3047        checkTime(startTime, "startProcess: done updating cpu stats");
3048
3049        try {
3050            int uid = app.uid;
3051
3052            int[] gids = null;
3053            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3054            if (!app.isolated) {
3055                int[] permGids = null;
3056                try {
3057                    checkTime(startTime, "startProcess: getting gids from package manager");
3058                    final PackageManager pm = mContext.getPackageManager();
3059                    permGids = pm.getPackageGids(app.info.packageName);
3060
3061                    if (Environment.isExternalStorageEmulated()) {
3062                        checkTime(startTime, "startProcess: checking external storage perm");
3063                        if (pm.checkPermission(
3064                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3065                                app.info.packageName) == PERMISSION_GRANTED) {
3066                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3067                        } else {
3068                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3069                        }
3070                    }
3071                } catch (PackageManager.NameNotFoundException e) {
3072                    Slog.w(TAG, "Unable to retrieve gids", e);
3073                }
3074
3075                /*
3076                 * Add shared application and profile GIDs so applications can share some
3077                 * resources like shared libraries and access user-wide resources
3078                 */
3079                if (permGids == null) {
3080                    gids = new int[2];
3081                } else {
3082                    gids = new int[permGids.length + 2];
3083                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3084                }
3085                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3086                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3087            }
3088            checkTime(startTime, "startProcess: building args");
3089            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3090                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3091                        && mTopComponent != null
3092                        && app.processName.equals(mTopComponent.getPackageName())) {
3093                    uid = 0;
3094                }
3095                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3096                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3097                    uid = 0;
3098                }
3099            }
3100            int debugFlags = 0;
3101            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3102                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3103                // Also turn on CheckJNI for debuggable apps. It's quite
3104                // awkward to turn on otherwise.
3105                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3106            }
3107            // Run the app in safe mode if its manifest requests so or the
3108            // system is booted in safe mode.
3109            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3110                mSafeMode == true) {
3111                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3112            }
3113            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3114                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3115            }
3116            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3117                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3118            }
3119            if ("1".equals(SystemProperties.get("debug.assert"))) {
3120                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3121            }
3122
3123            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3124            if (requiredAbi == null) {
3125                requiredAbi = Build.SUPPORTED_ABIS[0];
3126            }
3127
3128            String instructionSet = null;
3129            if (app.info.primaryCpuAbi != null) {
3130                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3131            }
3132
3133            // Start the process.  It will either succeed and return a result containing
3134            // the PID of the new process, or else throw a RuntimeException.
3135            boolean isActivityProcess = (entryPoint == null);
3136            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3137            checkTime(startTime, "startProcess: asking zygote to start proc");
3138            Process.ProcessStartResult startResult = Process.start(entryPoint,
3139                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3140                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3141                    entryPointArgs);
3142            checkTime(startTime, "startProcess: returned from zygote!");
3143
3144            if (app.isolated) {
3145                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3146            }
3147            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3148            checkTime(startTime, "startProcess: done updating battery stats");
3149
3150            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3151                    UserHandle.getUserId(uid), startResult.pid, uid,
3152                    app.processName, hostingType,
3153                    hostingNameStr != null ? hostingNameStr : "");
3154
3155            if (app.persistent) {
3156                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3157            }
3158
3159            checkTime(startTime, "startProcess: building log message");
3160            StringBuilder buf = mStringBuilder;
3161            buf.setLength(0);
3162            buf.append("Start proc ");
3163            buf.append(app.processName);
3164            if (!isActivityProcess) {
3165                buf.append(" [");
3166                buf.append(entryPoint);
3167                buf.append("]");
3168            }
3169            buf.append(" for ");
3170            buf.append(hostingType);
3171            if (hostingNameStr != null) {
3172                buf.append(" ");
3173                buf.append(hostingNameStr);
3174            }
3175            buf.append(": pid=");
3176            buf.append(startResult.pid);
3177            buf.append(" uid=");
3178            buf.append(uid);
3179            buf.append(" gids={");
3180            if (gids != null) {
3181                for (int gi=0; gi<gids.length; gi++) {
3182                    if (gi != 0) buf.append(", ");
3183                    buf.append(gids[gi]);
3184
3185                }
3186            }
3187            buf.append("}");
3188            if (requiredAbi != null) {
3189                buf.append(" abi=");
3190                buf.append(requiredAbi);
3191            }
3192            Slog.i(TAG, buf.toString());
3193            app.setPid(startResult.pid);
3194            app.usingWrapper = startResult.usingWrapper;
3195            app.removed = false;
3196            app.killedByAm = false;
3197            checkTime(startTime, "startProcess: starting to update pids map");
3198            synchronized (mPidsSelfLocked) {
3199                this.mPidsSelfLocked.put(startResult.pid, app);
3200                if (isActivityProcess) {
3201                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3202                    msg.obj = app;
3203                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3204                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3205                }
3206            }
3207            checkTime(startTime, "startProcess: done updating pids map");
3208        } catch (RuntimeException e) {
3209            // XXX do better error recovery.
3210            app.setPid(0);
3211            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3212            if (app.isolated) {
3213                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3214            }
3215            Slog.e(TAG, "Failure starting process " + app.processName, e);
3216        }
3217    }
3218
3219    void updateUsageStats(ActivityRecord component, boolean resumed) {
3220        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3221        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3222        if (resumed) {
3223            if (mUsageStatsService != null) {
3224                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3225                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3226            }
3227            synchronized (stats) {
3228                stats.noteActivityResumedLocked(component.app.uid);
3229            }
3230        } else {
3231            if (mUsageStatsService != null) {
3232                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3233                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3234            }
3235            synchronized (stats) {
3236                stats.noteActivityPausedLocked(component.app.uid);
3237            }
3238        }
3239    }
3240
3241    Intent getHomeIntent() {
3242        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3243        intent.setComponent(mTopComponent);
3244        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3245            intent.addCategory(Intent.CATEGORY_HOME);
3246        }
3247        return intent;
3248    }
3249
3250    boolean startHomeActivityLocked(int userId) {
3251        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3252                && mTopAction == null) {
3253            // We are running in factory test mode, but unable to find
3254            // the factory test app, so just sit around displaying the
3255            // error message and don't try to start anything.
3256            return false;
3257        }
3258        Intent intent = getHomeIntent();
3259        ActivityInfo aInfo =
3260            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3261        if (aInfo != null) {
3262            intent.setComponent(new ComponentName(
3263                    aInfo.applicationInfo.packageName, aInfo.name));
3264            // Don't do this if the home app is currently being
3265            // instrumented.
3266            aInfo = new ActivityInfo(aInfo);
3267            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3268            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3269                    aInfo.applicationInfo.uid, true);
3270            if (app == null || app.instrumentationClass == null) {
3271                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3272                mStackSupervisor.startHomeActivity(intent, aInfo);
3273            }
3274        }
3275
3276        return true;
3277    }
3278
3279    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3280        ActivityInfo ai = null;
3281        ComponentName comp = intent.getComponent();
3282        try {
3283            if (comp != null) {
3284                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3285            } else {
3286                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3287                        intent,
3288                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3289                            flags, userId);
3290
3291                if (info != null) {
3292                    ai = info.activityInfo;
3293                }
3294            }
3295        } catch (RemoteException e) {
3296            // ignore
3297        }
3298
3299        return ai;
3300    }
3301
3302    /**
3303     * Starts the "new version setup screen" if appropriate.
3304     */
3305    void startSetupActivityLocked() {
3306        // Only do this once per boot.
3307        if (mCheckedForSetup) {
3308            return;
3309        }
3310
3311        // We will show this screen if the current one is a different
3312        // version than the last one shown, and we are not running in
3313        // low-level factory test mode.
3314        final ContentResolver resolver = mContext.getContentResolver();
3315        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3316                Settings.Global.getInt(resolver,
3317                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3318            mCheckedForSetup = true;
3319
3320            // See if we should be showing the platform update setup UI.
3321            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3322            List<ResolveInfo> ris = mContext.getPackageManager()
3323                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3324
3325            // We don't allow third party apps to replace this.
3326            ResolveInfo ri = null;
3327            for (int i=0; ris != null && i<ris.size(); i++) {
3328                if ((ris.get(i).activityInfo.applicationInfo.flags
3329                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3330                    ri = ris.get(i);
3331                    break;
3332                }
3333            }
3334
3335            if (ri != null) {
3336                String vers = ri.activityInfo.metaData != null
3337                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3338                        : null;
3339                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3340                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3341                            Intent.METADATA_SETUP_VERSION);
3342                }
3343                String lastVers = Settings.Secure.getString(
3344                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3345                if (vers != null && !vers.equals(lastVers)) {
3346                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3347                    intent.setComponent(new ComponentName(
3348                            ri.activityInfo.packageName, ri.activityInfo.name));
3349                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3350                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3351                            null);
3352                }
3353            }
3354        }
3355    }
3356
3357    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3358        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3359    }
3360
3361    void enforceNotIsolatedCaller(String caller) {
3362        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3363            throw new SecurityException("Isolated process not allowed to call " + caller);
3364        }
3365    }
3366
3367    @Override
3368    public int getFrontActivityScreenCompatMode() {
3369        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3370        synchronized (this) {
3371            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3372        }
3373    }
3374
3375    @Override
3376    public void setFrontActivityScreenCompatMode(int mode) {
3377        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3378                "setFrontActivityScreenCompatMode");
3379        synchronized (this) {
3380            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3381        }
3382    }
3383
3384    @Override
3385    public int getPackageScreenCompatMode(String packageName) {
3386        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3387        synchronized (this) {
3388            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3389        }
3390    }
3391
3392    @Override
3393    public void setPackageScreenCompatMode(String packageName, int mode) {
3394        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3395                "setPackageScreenCompatMode");
3396        synchronized (this) {
3397            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3398        }
3399    }
3400
3401    @Override
3402    public boolean getPackageAskScreenCompat(String packageName) {
3403        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3404        synchronized (this) {
3405            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3406        }
3407    }
3408
3409    @Override
3410    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3411        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3412                "setPackageAskScreenCompat");
3413        synchronized (this) {
3414            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3415        }
3416    }
3417
3418    private void dispatchProcessesChanged() {
3419        int N;
3420        synchronized (this) {
3421            N = mPendingProcessChanges.size();
3422            if (mActiveProcessChanges.length < N) {
3423                mActiveProcessChanges = new ProcessChangeItem[N];
3424            }
3425            mPendingProcessChanges.toArray(mActiveProcessChanges);
3426            mAvailProcessChanges.addAll(mPendingProcessChanges);
3427            mPendingProcessChanges.clear();
3428            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3429        }
3430
3431        int i = mProcessObservers.beginBroadcast();
3432        while (i > 0) {
3433            i--;
3434            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3435            if (observer != null) {
3436                try {
3437                    for (int j=0; j<N; j++) {
3438                        ProcessChangeItem item = mActiveProcessChanges[j];
3439                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3440                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3441                                    + item.pid + " uid=" + item.uid + ": "
3442                                    + item.foregroundActivities);
3443                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3444                                    item.foregroundActivities);
3445                        }
3446                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3447                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3448                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3449                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3450                        }
3451                    }
3452                } catch (RemoteException e) {
3453                }
3454            }
3455        }
3456        mProcessObservers.finishBroadcast();
3457    }
3458
3459    private void dispatchProcessDied(int pid, int uid) {
3460        int i = mProcessObservers.beginBroadcast();
3461        while (i > 0) {
3462            i--;
3463            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3464            if (observer != null) {
3465                try {
3466                    observer.onProcessDied(pid, uid);
3467                } catch (RemoteException e) {
3468                }
3469            }
3470        }
3471        mProcessObservers.finishBroadcast();
3472    }
3473
3474    @Override
3475    public final int startActivity(IApplicationThread caller, String callingPackage,
3476            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3477            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3478        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3479            resultWho, requestCode, startFlags, profilerInfo, options,
3480            UserHandle.getCallingUserId());
3481    }
3482
3483    @Override
3484    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3485            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3486            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3487        enforceNotIsolatedCaller("startActivity");
3488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3489                false, ALLOW_FULL_ONLY, "startActivity", null);
3490        // TODO: Switch to user app stacks here.
3491        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3492                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3493                profilerInfo, null, null, options, userId, null, null);
3494    }
3495
3496    @Override
3497    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3498            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3499            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3500
3501        // This is very dangerous -- it allows you to perform a start activity (including
3502        // permission grants) as any app that may launch one of your own activities.  So
3503        // we will only allow this to be done from activities that are part of the core framework,
3504        // and then only when they are running as the system.
3505        final ActivityRecord sourceRecord;
3506        final int targetUid;
3507        final String targetPackage;
3508        synchronized (this) {
3509            if (resultTo == null) {
3510                throw new SecurityException("Must be called from an activity");
3511            }
3512            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3513            if (sourceRecord == null) {
3514                throw new SecurityException("Called with bad activity token: " + resultTo);
3515            }
3516            if (!sourceRecord.info.packageName.equals("android")) {
3517                throw new SecurityException(
3518                        "Must be called from an activity that is declared in the android package");
3519            }
3520            if (sourceRecord.app == null) {
3521                throw new SecurityException("Called without a process attached to activity");
3522            }
3523            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3524                // This is still okay, as long as this activity is running under the
3525                // uid of the original calling activity.
3526                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3527                    throw new SecurityException(
3528                            "Calling activity in uid " + sourceRecord.app.uid
3529                                    + " must be system uid or original calling uid "
3530                                    + sourceRecord.launchedFromUid);
3531                }
3532            }
3533            targetUid = sourceRecord.launchedFromUid;
3534            targetPackage = sourceRecord.launchedFromPackage;
3535        }
3536
3537        // TODO: Switch to user app stacks here.
3538        try {
3539            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3540                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3541                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3542            return ret;
3543        } catch (SecurityException e) {
3544            // XXX need to figure out how to propagate to original app.
3545            // A SecurityException here is generally actually a fault of the original
3546            // calling activity (such as a fairly granting permissions), so propagate it
3547            // back to them.
3548            /*
3549            StringBuilder msg = new StringBuilder();
3550            msg.append("While launching");
3551            msg.append(intent.toString());
3552            msg.append(": ");
3553            msg.append(e.getMessage());
3554            */
3555            throw e;
3556        }
3557    }
3558
3559    @Override
3560    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3561            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3562            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3563        enforceNotIsolatedCaller("startActivityAndWait");
3564        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3565                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3566        WaitResult res = new WaitResult();
3567        // TODO: Switch to user app stacks here.
3568        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3569                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3570                options, userId, null, null);
3571        return res;
3572    }
3573
3574    @Override
3575    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3576            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3577            int startFlags, Configuration config, Bundle options, int userId) {
3578        enforceNotIsolatedCaller("startActivityWithConfig");
3579        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3580                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3581        // TODO: Switch to user app stacks here.
3582        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3583                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3584                null, null, config, options, userId, null, null);
3585        return ret;
3586    }
3587
3588    @Override
3589    public int startActivityIntentSender(IApplicationThread caller,
3590            IntentSender intent, Intent fillInIntent, String resolvedType,
3591            IBinder resultTo, String resultWho, int requestCode,
3592            int flagsMask, int flagsValues, Bundle options) {
3593        enforceNotIsolatedCaller("startActivityIntentSender");
3594        // Refuse possible leaked file descriptors
3595        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3596            throw new IllegalArgumentException("File descriptors passed in Intent");
3597        }
3598
3599        IIntentSender sender = intent.getTarget();
3600        if (!(sender instanceof PendingIntentRecord)) {
3601            throw new IllegalArgumentException("Bad PendingIntent object");
3602        }
3603
3604        PendingIntentRecord pir = (PendingIntentRecord)sender;
3605
3606        synchronized (this) {
3607            // If this is coming from the currently resumed activity, it is
3608            // effectively saying that app switches are allowed at this point.
3609            final ActivityStack stack = getFocusedStack();
3610            if (stack.mResumedActivity != null &&
3611                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3612                mAppSwitchesAllowedTime = 0;
3613            }
3614        }
3615        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3616                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3617        return ret;
3618    }
3619
3620    @Override
3621    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3622            Intent intent, String resolvedType, IVoiceInteractionSession session,
3623            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3624            Bundle options, int userId) {
3625        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3626                != PackageManager.PERMISSION_GRANTED) {
3627            String msg = "Permission Denial: startVoiceActivity() from pid="
3628                    + Binder.getCallingPid()
3629                    + ", uid=" + Binder.getCallingUid()
3630                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3631            Slog.w(TAG, msg);
3632            throw new SecurityException(msg);
3633        }
3634        if (session == null || interactor == null) {
3635            throw new NullPointerException("null session or interactor");
3636        }
3637        userId = handleIncomingUser(callingPid, callingUid, userId,
3638                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3639        // TODO: Switch to user app stacks here.
3640        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3641                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3642                null, options, userId, null, null);
3643    }
3644
3645    @Override
3646    public boolean startNextMatchingActivity(IBinder callingActivity,
3647            Intent intent, Bundle options) {
3648        // Refuse possible leaked file descriptors
3649        if (intent != null && intent.hasFileDescriptors() == true) {
3650            throw new IllegalArgumentException("File descriptors passed in Intent");
3651        }
3652
3653        synchronized (this) {
3654            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3655            if (r == null) {
3656                ActivityOptions.abort(options);
3657                return false;
3658            }
3659            if (r.app == null || r.app.thread == null) {
3660                // The caller is not running...  d'oh!
3661                ActivityOptions.abort(options);
3662                return false;
3663            }
3664            intent = new Intent(intent);
3665            // The caller is not allowed to change the data.
3666            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3667            // And we are resetting to find the next component...
3668            intent.setComponent(null);
3669
3670            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3671
3672            ActivityInfo aInfo = null;
3673            try {
3674                List<ResolveInfo> resolves =
3675                    AppGlobals.getPackageManager().queryIntentActivities(
3676                            intent, r.resolvedType,
3677                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3678                            UserHandle.getCallingUserId());
3679
3680                // Look for the original activity in the list...
3681                final int N = resolves != null ? resolves.size() : 0;
3682                for (int i=0; i<N; i++) {
3683                    ResolveInfo rInfo = resolves.get(i);
3684                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3685                            && rInfo.activityInfo.name.equals(r.info.name)) {
3686                        // We found the current one...  the next matching is
3687                        // after it.
3688                        i++;
3689                        if (i<N) {
3690                            aInfo = resolves.get(i).activityInfo;
3691                        }
3692                        if (debug) {
3693                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3694                                    + "/" + r.info.name);
3695                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3696                                    + "/" + aInfo.name);
3697                        }
3698                        break;
3699                    }
3700                }
3701            } catch (RemoteException e) {
3702            }
3703
3704            if (aInfo == null) {
3705                // Nobody who is next!
3706                ActivityOptions.abort(options);
3707                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3708                return false;
3709            }
3710
3711            intent.setComponent(new ComponentName(
3712                    aInfo.applicationInfo.packageName, aInfo.name));
3713            intent.setFlags(intent.getFlags()&~(
3714                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3715                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3716                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3717                    Intent.FLAG_ACTIVITY_NEW_TASK));
3718
3719            // Okay now we need to start the new activity, replacing the
3720            // currently running activity.  This is a little tricky because
3721            // we want to start the new one as if the current one is finished,
3722            // but not finish the current one first so that there is no flicker.
3723            // And thus...
3724            final boolean wasFinishing = r.finishing;
3725            r.finishing = true;
3726
3727            // Propagate reply information over to the new activity.
3728            final ActivityRecord resultTo = r.resultTo;
3729            final String resultWho = r.resultWho;
3730            final int requestCode = r.requestCode;
3731            r.resultTo = null;
3732            if (resultTo != null) {
3733                resultTo.removeResultsLocked(r, resultWho, requestCode);
3734            }
3735
3736            final long origId = Binder.clearCallingIdentity();
3737            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3738                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3739                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3740                    options, false, null, null, null);
3741            Binder.restoreCallingIdentity(origId);
3742
3743            r.finishing = wasFinishing;
3744            if (res != ActivityManager.START_SUCCESS) {
3745                return false;
3746            }
3747            return true;
3748        }
3749    }
3750
3751    @Override
3752    public final int startActivityFromRecents(int taskId, Bundle options) {
3753        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3754            String msg = "Permission Denial: startActivityFromRecents called without " +
3755                    START_TASKS_FROM_RECENTS;
3756            Slog.w(TAG, msg);
3757            throw new SecurityException(msg);
3758        }
3759        return startActivityFromRecentsInner(taskId, options);
3760    }
3761
3762    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3763        final TaskRecord task;
3764        final int callingUid;
3765        final String callingPackage;
3766        final Intent intent;
3767        final int userId;
3768        synchronized (this) {
3769            task = recentTaskForIdLocked(taskId);
3770            if (task == null) {
3771                throw new IllegalArgumentException("Task " + taskId + " not found.");
3772            }
3773            callingUid = task.mCallingUid;
3774            callingPackage = task.mCallingPackage;
3775            intent = task.intent;
3776            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3777            userId = task.userId;
3778        }
3779        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3780                options, userId, null, task);
3781    }
3782
3783    final int startActivityInPackage(int uid, String callingPackage,
3784            Intent intent, String resolvedType, IBinder resultTo,
3785            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3786            IActivityContainer container, TaskRecord inTask) {
3787
3788        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3789                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3790
3791        // TODO: Switch to user app stacks here.
3792        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3793                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3794                null, null, null, options, userId, container, inTask);
3795        return ret;
3796    }
3797
3798    @Override
3799    public final int startActivities(IApplicationThread caller, String callingPackage,
3800            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3801            int userId) {
3802        enforceNotIsolatedCaller("startActivities");
3803        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3804                false, ALLOW_FULL_ONLY, "startActivity", null);
3805        // TODO: Switch to user app stacks here.
3806        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3807                resolvedTypes, resultTo, options, userId);
3808        return ret;
3809    }
3810
3811    final int startActivitiesInPackage(int uid, String callingPackage,
3812            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3813            Bundle options, int userId) {
3814
3815        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3816                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3817        // TODO: Switch to user app stacks here.
3818        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3819                resultTo, options, userId);
3820        return ret;
3821    }
3822
3823    //explicitly remove thd old information in mRecentTasks when removing existing user.
3824    private void removeRecentTasksForUserLocked(int userId) {
3825        if(userId <= 0) {
3826            Slog.i(TAG, "Can't remove recent task on user " + userId);
3827            return;
3828        }
3829
3830        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3831            TaskRecord tr = mRecentTasks.get(i);
3832            if (tr.userId == userId) {
3833                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3834                        + " when finishing user" + userId);
3835                mRecentTasks.remove(i);
3836                tr.removedFromRecents(mTaskPersister);
3837            }
3838        }
3839
3840        // Remove tasks from persistent storage.
3841        mTaskPersister.wakeup(null, true);
3842    }
3843
3844    // Sort by taskId
3845    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3846        @Override
3847        public int compare(TaskRecord lhs, TaskRecord rhs) {
3848            return rhs.taskId - lhs.taskId;
3849        }
3850    };
3851
3852    // Extract the affiliates of the chain containing mRecentTasks[start].
3853    private int processNextAffiliateChain(int start) {
3854        final TaskRecord startTask = mRecentTasks.get(start);
3855        final int affiliateId = startTask.mAffiliatedTaskId;
3856
3857        // Quick identification of isolated tasks. I.e. those not launched behind.
3858        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3859                startTask.mNextAffiliate == null) {
3860            // There is still a slim chance that there are other tasks that point to this task
3861            // and that the chain is so messed up that this task no longer points to them but
3862            // the gain of this optimization outweighs the risk.
3863            startTask.inRecents = true;
3864            return start + 1;
3865        }
3866
3867        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3868        mTmpRecents.clear();
3869        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3870            final TaskRecord task = mRecentTasks.get(i);
3871            if (task.mAffiliatedTaskId == affiliateId) {
3872                mRecentTasks.remove(i);
3873                mTmpRecents.add(task);
3874            }
3875        }
3876
3877        // Sort them all by taskId. That is the order they were create in and that order will
3878        // always be correct.
3879        Collections.sort(mTmpRecents, mTaskRecordComparator);
3880
3881        // Go through and fix up the linked list.
3882        // The first one is the end of the chain and has no next.
3883        final TaskRecord first = mTmpRecents.get(0);
3884        first.inRecents = true;
3885        if (first.mNextAffiliate != null) {
3886            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3887            first.setNextAffiliate(null);
3888            mTaskPersister.wakeup(first, false);
3889        }
3890        // Everything in the middle is doubly linked from next to prev.
3891        final int tmpSize = mTmpRecents.size();
3892        for (int i = 0; i < tmpSize - 1; ++i) {
3893            final TaskRecord next = mTmpRecents.get(i);
3894            final TaskRecord prev = mTmpRecents.get(i + 1);
3895            if (next.mPrevAffiliate != prev) {
3896                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3897                        " setting prev=" + prev);
3898                next.setPrevAffiliate(prev);
3899                mTaskPersister.wakeup(next, false);
3900            }
3901            if (prev.mNextAffiliate != next) {
3902                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3903                        " setting next=" + next);
3904                prev.setNextAffiliate(next);
3905                mTaskPersister.wakeup(prev, false);
3906            }
3907            prev.inRecents = true;
3908        }
3909        // The last one is the beginning of the list and has no prev.
3910        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3911        if (last.mPrevAffiliate != null) {
3912            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3913            last.setPrevAffiliate(null);
3914            mTaskPersister.wakeup(last, false);
3915        }
3916
3917        // Insert the group back into mRecentTasks at start.
3918        mRecentTasks.addAll(start, mTmpRecents);
3919
3920        // Let the caller know where we left off.
3921        return start + tmpSize;
3922    }
3923
3924    /**
3925     * Update the recent tasks lists: make sure tasks should still be here (their
3926     * applications / activities still exist), update their availability, fixup ordering
3927     * of affiliations.
3928     */
3929    void cleanupRecentTasksLocked(int userId) {
3930        if (mRecentTasks == null) {
3931            // Happens when called from the packagemanager broadcast before boot.
3932            return;
3933        }
3934
3935        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3936        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3937        final IPackageManager pm = AppGlobals.getPackageManager();
3938        final ActivityInfo dummyAct = new ActivityInfo();
3939        final ApplicationInfo dummyApp = new ApplicationInfo();
3940
3941        int N = mRecentTasks.size();
3942
3943        int[] users = userId == UserHandle.USER_ALL
3944                ? getUsersLocked() : new int[] { userId };
3945        for (int user : users) {
3946            for (int i = 0; i < N; i++) {
3947                TaskRecord task = mRecentTasks.get(i);
3948                if (task.userId != user) {
3949                    // Only look at tasks for the user ID of interest.
3950                    continue;
3951                }
3952                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3953                    // This situation is broken, and we should just get rid of it now.
3954                    mRecentTasks.remove(i);
3955                    task.removedFromRecents(mTaskPersister);
3956                    i--;
3957                    N--;
3958                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3959                    continue;
3960                }
3961                // Check whether this activity is currently available.
3962                if (task.realActivity != null) {
3963                    ActivityInfo ai = availActCache.get(task.realActivity);
3964                    if (ai == null) {
3965                        try {
3966                            ai = pm.getActivityInfo(task.realActivity,
3967                                    PackageManager.GET_UNINSTALLED_PACKAGES
3968                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3969                        } catch (RemoteException e) {
3970                            // Will never happen.
3971                            continue;
3972                        }
3973                        if (ai == null) {
3974                            ai = dummyAct;
3975                        }
3976                        availActCache.put(task.realActivity, ai);
3977                    }
3978                    if (ai == dummyAct) {
3979                        // This could be either because the activity no longer exists, or the
3980                        // app is temporarily gone.  For the former we want to remove the recents
3981                        // entry; for the latter we want to mark it as unavailable.
3982                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3983                        if (app == null) {
3984                            try {
3985                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3986                                        PackageManager.GET_UNINSTALLED_PACKAGES
3987                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3988                            } catch (RemoteException e) {
3989                                // Will never happen.
3990                                continue;
3991                            }
3992                            if (app == null) {
3993                                app = dummyApp;
3994                            }
3995                            availAppCache.put(task.realActivity.getPackageName(), app);
3996                        }
3997                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3998                            // Doesn't exist any more!  Good-bye.
3999                            mRecentTasks.remove(i);
4000                            task.removedFromRecents(mTaskPersister);
4001                            i--;
4002                            N--;
4003                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4004                            continue;
4005                        } else {
4006                            // Otherwise just not available for now.
4007                            if (task.isAvailable) {
4008                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4009                                        + task);
4010                            }
4011                            task.isAvailable = false;
4012                        }
4013                    } else {
4014                        if (!ai.enabled || !ai.applicationInfo.enabled
4015                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4016                            if (task.isAvailable) {
4017                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4018                                        + task + " (enabled=" + ai.enabled + "/"
4019                                        + ai.applicationInfo.enabled +  " flags="
4020                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4021                            }
4022                            task.isAvailable = false;
4023                        } else {
4024                            if (!task.isAvailable) {
4025                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4026                                        + task);
4027                            }
4028                            task.isAvailable = true;
4029                        }
4030                    }
4031                }
4032            }
4033        }
4034
4035        // Verify the affiliate chain for each task.
4036        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4037        }
4038
4039        mTmpRecents.clear();
4040        // mRecentTasks is now in sorted, affiliated order.
4041    }
4042
4043    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4044        int N = mRecentTasks.size();
4045        TaskRecord top = task;
4046        int topIndex = taskIndex;
4047        while (top.mNextAffiliate != null && topIndex > 0) {
4048            top = top.mNextAffiliate;
4049            topIndex--;
4050        }
4051        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4052                + topIndex + " from intial " + taskIndex);
4053        // Find the end of the chain, doing a sanity check along the way.
4054        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4055        int endIndex = topIndex;
4056        TaskRecord prev = top;
4057        while (endIndex < N) {
4058            TaskRecord cur = mRecentTasks.get(endIndex);
4059            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4060                    + endIndex + " " + cur);
4061            if (cur == top) {
4062                // Verify start of the chain.
4063                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4064                    Slog.wtf(TAG, "Bad chain @" + endIndex
4065                            + ": first task has next affiliate: " + prev);
4066                    sane = false;
4067                    break;
4068                }
4069            } else {
4070                // Verify middle of the chain's next points back to the one before.
4071                if (cur.mNextAffiliate != prev
4072                        || cur.mNextAffiliateTaskId != prev.taskId) {
4073                    Slog.wtf(TAG, "Bad chain @" + endIndex
4074                            + ": middle task " + cur + " @" + endIndex
4075                            + " has bad next affiliate "
4076                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4077                            + ", expected " + prev);
4078                    sane = false;
4079                    break;
4080                }
4081            }
4082            if (cur.mPrevAffiliateTaskId == -1) {
4083                // Chain ends here.
4084                if (cur.mPrevAffiliate != null) {
4085                    Slog.wtf(TAG, "Bad chain @" + endIndex
4086                            + ": last task " + cur + " has previous affiliate "
4087                            + cur.mPrevAffiliate);
4088                    sane = false;
4089                }
4090                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4091                break;
4092            } else {
4093                // Verify middle of the chain's prev points to a valid item.
4094                if (cur.mPrevAffiliate == null) {
4095                    Slog.wtf(TAG, "Bad chain @" + endIndex
4096                            + ": task " + cur + " has previous affiliate "
4097                            + cur.mPrevAffiliate + " but should be id "
4098                            + cur.mPrevAffiliate);
4099                    sane = false;
4100                    break;
4101                }
4102            }
4103            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4104                Slog.wtf(TAG, "Bad chain @" + endIndex
4105                        + ": task " + cur + " has affiliated id "
4106                        + cur.mAffiliatedTaskId + " but should be "
4107                        + task.mAffiliatedTaskId);
4108                sane = false;
4109                break;
4110            }
4111            prev = cur;
4112            endIndex++;
4113            if (endIndex >= N) {
4114                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4115                        + ": last task " + prev);
4116                sane = false;
4117                break;
4118            }
4119        }
4120        if (sane) {
4121            if (endIndex < taskIndex) {
4122                Slog.wtf(TAG, "Bad chain @" + endIndex
4123                        + ": did not extend to task " + task + " @" + taskIndex);
4124                sane = false;
4125            }
4126        }
4127        if (sane) {
4128            // All looks good, we can just move all of the affiliated tasks
4129            // to the top.
4130            for (int i=topIndex; i<=endIndex; i++) {
4131                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4132                        + " from " + i + " to " + (i-topIndex));
4133                TaskRecord cur = mRecentTasks.remove(i);
4134                mRecentTasks.add(i-topIndex, cur);
4135            }
4136            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4137                    + " to " + endIndex);
4138            return true;
4139        }
4140
4141        // Whoops, couldn't do it.
4142        return false;
4143    }
4144
4145    final void addRecentTaskLocked(TaskRecord task) {
4146        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4147                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4148
4149        int N = mRecentTasks.size();
4150        // Quick case: check if the top-most recent task is the same.
4151        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4152            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4153            return;
4154        }
4155        // Another quick case: check if this is part of a set of affiliated
4156        // tasks that are at the top.
4157        if (isAffiliated && N > 0 && task.inRecents
4158                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4159            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4160                    + " at top when adding " + task);
4161            return;
4162        }
4163        // Another quick case: never add voice sessions.
4164        if (task.voiceSession != null) {
4165            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4166            return;
4167        }
4168
4169        boolean needAffiliationFix = false;
4170
4171        // Slightly less quick case: the task is already in recents, so all we need
4172        // to do is move it.
4173        if (task.inRecents) {
4174            int taskIndex = mRecentTasks.indexOf(task);
4175            if (taskIndex >= 0) {
4176                if (!isAffiliated) {
4177                    // Simple case: this is not an affiliated task, so we just move it to the front.
4178                    mRecentTasks.remove(taskIndex);
4179                    mRecentTasks.add(0, task);
4180                    notifyTaskPersisterLocked(task, false);
4181                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4182                            + " from " + taskIndex);
4183                    return;
4184                } else {
4185                    // More complicated: need to keep all affiliated tasks together.
4186                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4187                        // All went well.
4188                        return;
4189                    }
4190
4191                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4192                    // everything and then go through our general path of adding a new task.
4193                    needAffiliationFix = true;
4194                }
4195            } else {
4196                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4197                needAffiliationFix = true;
4198            }
4199        }
4200
4201        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4202        trimRecentsForTask(task, true);
4203
4204        N = mRecentTasks.size();
4205        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4206            final TaskRecord tr = mRecentTasks.remove(N - 1);
4207            tr.removedFromRecents(mTaskPersister);
4208            N--;
4209        }
4210        task.inRecents = true;
4211        if (!isAffiliated || needAffiliationFix) {
4212            // If this is a simple non-affiliated task, or we had some failure trying to
4213            // handle it as part of an affilated task, then just place it at the top.
4214            mRecentTasks.add(0, task);
4215        } else if (isAffiliated) {
4216            // If this is a new affiliated task, then move all of the affiliated tasks
4217            // to the front and insert this new one.
4218            TaskRecord other = task.mNextAffiliate;
4219            if (other == null) {
4220                other = task.mPrevAffiliate;
4221            }
4222            if (other != null) {
4223                int otherIndex = mRecentTasks.indexOf(other);
4224                if (otherIndex >= 0) {
4225                    // Insert new task at appropriate location.
4226                    int taskIndex;
4227                    if (other == task.mNextAffiliate) {
4228                        // We found the index of our next affiliation, which is who is
4229                        // before us in the list, so add after that point.
4230                        taskIndex = otherIndex+1;
4231                    } else {
4232                        // We found the index of our previous affiliation, which is who is
4233                        // after us in the list, so add at their position.
4234                        taskIndex = otherIndex;
4235                    }
4236                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4237                            + taskIndex + ": " + task);
4238                    mRecentTasks.add(taskIndex, task);
4239
4240                    // Now move everything to the front.
4241                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4242                        // All went well.
4243                        return;
4244                    }
4245
4246                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4247                    // everything and then go through our general path of adding a new task.
4248                    needAffiliationFix = true;
4249                } else {
4250                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4251                            + other);
4252                    needAffiliationFix = true;
4253                }
4254            } else {
4255                if (DEBUG_RECENTS) Slog.d(TAG,
4256                        "addRecent: adding affiliated task without next/prev:" + task);
4257                needAffiliationFix = true;
4258            }
4259        }
4260        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4261
4262        if (needAffiliationFix) {
4263            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4264            cleanupRecentTasksLocked(task.userId);
4265        }
4266    }
4267
4268    /**
4269     * If needed, remove oldest existing entries in recents that are for the same kind
4270     * of task as the given one.
4271     */
4272    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4273        int N = mRecentTasks.size();
4274        final Intent intent = task.intent;
4275        final boolean document = intent != null && intent.isDocument();
4276
4277        int maxRecents = task.maxRecents - 1;
4278        for (int i=0; i<N; i++) {
4279            final TaskRecord tr = mRecentTasks.get(i);
4280            if (task != tr) {
4281                if (task.userId != tr.userId) {
4282                    continue;
4283                }
4284                if (i > MAX_RECENT_BITMAPS) {
4285                    tr.freeLastThumbnail();
4286                }
4287                final Intent trIntent = tr.intent;
4288                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4289                    (intent == null || !intent.filterEquals(trIntent))) {
4290                    continue;
4291                }
4292                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4293                if (document && trIsDocument) {
4294                    // These are the same document activity (not necessarily the same doc).
4295                    if (maxRecents > 0) {
4296                        --maxRecents;
4297                        continue;
4298                    }
4299                    // Hit the maximum number of documents for this task. Fall through
4300                    // and remove this document from recents.
4301                } else if (document || trIsDocument) {
4302                    // Only one of these is a document. Not the droid we're looking for.
4303                    continue;
4304                }
4305            }
4306
4307            if (!doTrim) {
4308                // If the caller is not actually asking for a trim, just tell them we reached
4309                // a point where the trim would happen.
4310                return i;
4311            }
4312
4313            // Either task and tr are the same or, their affinities match or their intents match
4314            // and neither of them is a document, or they are documents using the same activity
4315            // and their maxRecents has been reached.
4316            tr.disposeThumbnail();
4317            mRecentTasks.remove(i);
4318            if (task != tr) {
4319                tr.removedFromRecents(mTaskPersister);
4320            }
4321            i--;
4322            N--;
4323            if (task.intent == null) {
4324                // If the new recent task we are adding is not fully
4325                // specified, then replace it with the existing recent task.
4326                task = tr;
4327            }
4328            notifyTaskPersisterLocked(tr, false);
4329        }
4330
4331        return -1;
4332    }
4333
4334    @Override
4335    public void reportActivityFullyDrawn(IBinder token) {
4336        synchronized (this) {
4337            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4338            if (r == null) {
4339                return;
4340            }
4341            r.reportFullyDrawnLocked();
4342        }
4343    }
4344
4345    @Override
4346    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4347        synchronized (this) {
4348            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4349            if (r == null) {
4350                return;
4351            }
4352            final long origId = Binder.clearCallingIdentity();
4353            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4354            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4355                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4356            if (config != null) {
4357                r.frozenBeforeDestroy = true;
4358                if (!updateConfigurationLocked(config, r, false, false)) {
4359                    mStackSupervisor.resumeTopActivitiesLocked();
4360                }
4361            }
4362            Binder.restoreCallingIdentity(origId);
4363        }
4364    }
4365
4366    @Override
4367    public int getRequestedOrientation(IBinder token) {
4368        synchronized (this) {
4369            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4370            if (r == null) {
4371                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4372            }
4373            return mWindowManager.getAppOrientation(r.appToken);
4374        }
4375    }
4376
4377    /**
4378     * This is the internal entry point for handling Activity.finish().
4379     *
4380     * @param token The Binder token referencing the Activity we want to finish.
4381     * @param resultCode Result code, if any, from this Activity.
4382     * @param resultData Result data (Intent), if any, from this Activity.
4383     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4384     *            the root Activity in the task.
4385     *
4386     * @return Returns true if the activity successfully finished, or false if it is still running.
4387     */
4388    @Override
4389    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4390            boolean finishTask) {
4391        // Refuse possible leaked file descriptors
4392        if (resultData != null && resultData.hasFileDescriptors() == true) {
4393            throw new IllegalArgumentException("File descriptors passed in Intent");
4394        }
4395
4396        synchronized(this) {
4397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4398            if (r == null) {
4399                return true;
4400            }
4401            // Keep track of the root activity of the task before we finish it
4402            TaskRecord tr = r.task;
4403            ActivityRecord rootR = tr.getRootActivity();
4404            // Do not allow task to finish in Lock Task mode.
4405            if (tr == mStackSupervisor.mLockTaskModeTask) {
4406                if (rootR == r) {
4407                    mStackSupervisor.showLockTaskToast();
4408                    return false;
4409                }
4410            }
4411            if (mController != null) {
4412                // Find the first activity that is not finishing.
4413                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4414                if (next != null) {
4415                    // ask watcher if this is allowed
4416                    boolean resumeOK = true;
4417                    try {
4418                        resumeOK = mController.activityResuming(next.packageName);
4419                    } catch (RemoteException e) {
4420                        mController = null;
4421                        Watchdog.getInstance().setActivityController(null);
4422                    }
4423
4424                    if (!resumeOK) {
4425                        return false;
4426                    }
4427                }
4428            }
4429            final long origId = Binder.clearCallingIdentity();
4430            try {
4431                boolean res;
4432                if (finishTask && r == rootR) {
4433                    // If requested, remove the task that is associated to this activity only if it
4434                    // was the root activity in the task.  The result code and data is ignored because
4435                    // we don't support returning them across task boundaries.
4436                    res = removeTaskByIdLocked(tr.taskId, 0);
4437                } else {
4438                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4439                            resultData, "app-request", true);
4440                }
4441                return res;
4442            } finally {
4443                Binder.restoreCallingIdentity(origId);
4444            }
4445        }
4446    }
4447
4448    @Override
4449    public final void finishHeavyWeightApp() {
4450        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4451                != PackageManager.PERMISSION_GRANTED) {
4452            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4453                    + Binder.getCallingPid()
4454                    + ", uid=" + Binder.getCallingUid()
4455                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4456            Slog.w(TAG, msg);
4457            throw new SecurityException(msg);
4458        }
4459
4460        synchronized(this) {
4461            if (mHeavyWeightProcess == null) {
4462                return;
4463            }
4464
4465            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4466                    mHeavyWeightProcess.activities);
4467            for (int i=0; i<activities.size(); i++) {
4468                ActivityRecord r = activities.get(i);
4469                if (!r.finishing) {
4470                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4471                            null, "finish-heavy", true);
4472                }
4473            }
4474
4475            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4476                    mHeavyWeightProcess.userId, 0));
4477            mHeavyWeightProcess = null;
4478        }
4479    }
4480
4481    @Override
4482    public void crashApplication(int uid, int initialPid, String packageName,
4483            String message) {
4484        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4485                != PackageManager.PERMISSION_GRANTED) {
4486            String msg = "Permission Denial: crashApplication() from pid="
4487                    + Binder.getCallingPid()
4488                    + ", uid=" + Binder.getCallingUid()
4489                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4490            Slog.w(TAG, msg);
4491            throw new SecurityException(msg);
4492        }
4493
4494        synchronized(this) {
4495            ProcessRecord proc = null;
4496
4497            // Figure out which process to kill.  We don't trust that initialPid
4498            // still has any relation to current pids, so must scan through the
4499            // list.
4500            synchronized (mPidsSelfLocked) {
4501                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4502                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4503                    if (p.uid != uid) {
4504                        continue;
4505                    }
4506                    if (p.pid == initialPid) {
4507                        proc = p;
4508                        break;
4509                    }
4510                    if (p.pkgList.containsKey(packageName)) {
4511                        proc = p;
4512                    }
4513                }
4514            }
4515
4516            if (proc == null) {
4517                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4518                        + " initialPid=" + initialPid
4519                        + " packageName=" + packageName);
4520                return;
4521            }
4522
4523            if (proc.thread != null) {
4524                if (proc.pid == Process.myPid()) {
4525                    Log.w(TAG, "crashApplication: trying to crash self!");
4526                    return;
4527                }
4528                long ident = Binder.clearCallingIdentity();
4529                try {
4530                    proc.thread.scheduleCrash(message);
4531                } catch (RemoteException e) {
4532                }
4533                Binder.restoreCallingIdentity(ident);
4534            }
4535        }
4536    }
4537
4538    @Override
4539    public final void finishSubActivity(IBinder token, String resultWho,
4540            int requestCode) {
4541        synchronized(this) {
4542            final long origId = Binder.clearCallingIdentity();
4543            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4544            if (r != null) {
4545                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4546            }
4547            Binder.restoreCallingIdentity(origId);
4548        }
4549    }
4550
4551    @Override
4552    public boolean finishActivityAffinity(IBinder token) {
4553        synchronized(this) {
4554            final long origId = Binder.clearCallingIdentity();
4555            try {
4556                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4557
4558                ActivityRecord rootR = r.task.getRootActivity();
4559                // Do not allow task to finish in Lock Task mode.
4560                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4561                    if (rootR == r) {
4562                        mStackSupervisor.showLockTaskToast();
4563                        return false;
4564                    }
4565                }
4566                boolean res = false;
4567                if (r != null) {
4568                    res = r.task.stack.finishActivityAffinityLocked(r);
4569                }
4570                return res;
4571            } finally {
4572                Binder.restoreCallingIdentity(origId);
4573            }
4574        }
4575    }
4576
4577    @Override
4578    public void finishVoiceTask(IVoiceInteractionSession session) {
4579        synchronized(this) {
4580            final long origId = Binder.clearCallingIdentity();
4581            try {
4582                mStackSupervisor.finishVoiceTask(session);
4583            } finally {
4584                Binder.restoreCallingIdentity(origId);
4585            }
4586        }
4587
4588    }
4589
4590    @Override
4591    public boolean releaseActivityInstance(IBinder token) {
4592        synchronized(this) {
4593            final long origId = Binder.clearCallingIdentity();
4594            try {
4595                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4596                if (r.task == null || r.task.stack == null) {
4597                    return false;
4598                }
4599                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4600            } finally {
4601                Binder.restoreCallingIdentity(origId);
4602            }
4603        }
4604    }
4605
4606    @Override
4607    public void releaseSomeActivities(IApplicationThread appInt) {
4608        synchronized(this) {
4609            final long origId = Binder.clearCallingIdentity();
4610            try {
4611                ProcessRecord app = getRecordForAppLocked(appInt);
4612                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4613            } finally {
4614                Binder.restoreCallingIdentity(origId);
4615            }
4616        }
4617    }
4618
4619    @Override
4620    public boolean willActivityBeVisible(IBinder token) {
4621        synchronized(this) {
4622            ActivityStack stack = ActivityRecord.getStackLocked(token);
4623            if (stack != null) {
4624                return stack.willActivityBeVisibleLocked(token);
4625            }
4626            return false;
4627        }
4628    }
4629
4630    @Override
4631    public void overridePendingTransition(IBinder token, String packageName,
4632            int enterAnim, int exitAnim) {
4633        synchronized(this) {
4634            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4635            if (self == null) {
4636                return;
4637            }
4638
4639            final long origId = Binder.clearCallingIdentity();
4640
4641            if (self.state == ActivityState.RESUMED
4642                    || self.state == ActivityState.PAUSING) {
4643                mWindowManager.overridePendingAppTransition(packageName,
4644                        enterAnim, exitAnim, null);
4645            }
4646
4647            Binder.restoreCallingIdentity(origId);
4648        }
4649    }
4650
4651    /**
4652     * Main function for removing an existing process from the activity manager
4653     * as a result of that process going away.  Clears out all connections
4654     * to the process.
4655     */
4656    private final void handleAppDiedLocked(ProcessRecord app,
4657            boolean restarting, boolean allowRestart) {
4658        int pid = app.pid;
4659        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4660        if (!restarting) {
4661            removeLruProcessLocked(app);
4662            if (pid > 0) {
4663                ProcessList.remove(pid);
4664            }
4665        }
4666
4667        if (mProfileProc == app) {
4668            clearProfilerLocked();
4669        }
4670
4671        // Remove this application's activities from active lists.
4672        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4673
4674        app.activities.clear();
4675
4676        if (app.instrumentationClass != null) {
4677            Slog.w(TAG, "Crash of app " + app.processName
4678                  + " running instrumentation " + app.instrumentationClass);
4679            Bundle info = new Bundle();
4680            info.putString("shortMsg", "Process crashed.");
4681            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4682        }
4683
4684        if (!restarting) {
4685            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4686                // If there was nothing to resume, and we are not already
4687                // restarting this process, but there is a visible activity that
4688                // is hosted by the process...  then make sure all visible
4689                // activities are running, taking care of restarting this
4690                // process.
4691                if (hasVisibleActivities) {
4692                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4693                }
4694            }
4695        }
4696    }
4697
4698    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4699        IBinder threadBinder = thread.asBinder();
4700        // Find the application record.
4701        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4702            ProcessRecord rec = mLruProcesses.get(i);
4703            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4704                return i;
4705            }
4706        }
4707        return -1;
4708    }
4709
4710    final ProcessRecord getRecordForAppLocked(
4711            IApplicationThread thread) {
4712        if (thread == null) {
4713            return null;
4714        }
4715
4716        int appIndex = getLRURecordIndexForAppLocked(thread);
4717        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4718    }
4719
4720    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4721        // If there are no longer any background processes running,
4722        // and the app that died was not running instrumentation,
4723        // then tell everyone we are now low on memory.
4724        boolean haveBg = false;
4725        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4726            ProcessRecord rec = mLruProcesses.get(i);
4727            if (rec.thread != null
4728                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4729                haveBg = true;
4730                break;
4731            }
4732        }
4733
4734        if (!haveBg) {
4735            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4736            if (doReport) {
4737                long now = SystemClock.uptimeMillis();
4738                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4739                    doReport = false;
4740                } else {
4741                    mLastMemUsageReportTime = now;
4742                }
4743            }
4744            final ArrayList<ProcessMemInfo> memInfos
4745                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4746            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4747            long now = SystemClock.uptimeMillis();
4748            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4749                ProcessRecord rec = mLruProcesses.get(i);
4750                if (rec == dyingProc || rec.thread == null) {
4751                    continue;
4752                }
4753                if (doReport) {
4754                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4755                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4756                }
4757                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4758                    // The low memory report is overriding any current
4759                    // state for a GC request.  Make sure to do
4760                    // heavy/important/visible/foreground processes first.
4761                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4762                        rec.lastRequestedGc = 0;
4763                    } else {
4764                        rec.lastRequestedGc = rec.lastLowMemory;
4765                    }
4766                    rec.reportLowMemory = true;
4767                    rec.lastLowMemory = now;
4768                    mProcessesToGc.remove(rec);
4769                    addProcessToGcListLocked(rec);
4770                }
4771            }
4772            if (doReport) {
4773                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4774                mHandler.sendMessage(msg);
4775            }
4776            scheduleAppGcsLocked();
4777        }
4778    }
4779
4780    final void appDiedLocked(ProcessRecord app) {
4781       appDiedLocked(app, app.pid, app.thread);
4782    }
4783
4784    final void appDiedLocked(ProcessRecord app, int pid,
4785            IApplicationThread thread) {
4786
4787        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4788        synchronized (stats) {
4789            stats.noteProcessDiedLocked(app.info.uid, pid);
4790        }
4791
4792        Process.killProcessGroup(app.info.uid, pid);
4793
4794        // Clean up already done if the process has been re-started.
4795        if (app.pid == pid && app.thread != null &&
4796                app.thread.asBinder() == thread.asBinder()) {
4797            boolean doLowMem = app.instrumentationClass == null;
4798            boolean doOomAdj = doLowMem;
4799            if (!app.killedByAm) {
4800                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4801                        + ") has died.");
4802                mAllowLowerMemLevel = true;
4803            } else {
4804                // Note that we always want to do oom adj to update our state with the
4805                // new number of procs.
4806                mAllowLowerMemLevel = false;
4807                doLowMem = false;
4808            }
4809            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4810            if (DEBUG_CLEANUP) Slog.v(
4811                TAG, "Dying app: " + app + ", pid: " + pid
4812                + ", thread: " + thread.asBinder());
4813            handleAppDiedLocked(app, false, true);
4814
4815            if (doOomAdj) {
4816                updateOomAdjLocked();
4817            }
4818            if (doLowMem) {
4819                doLowMemReportIfNeededLocked(app);
4820            }
4821        } else if (app.pid != pid) {
4822            // A new process has already been started.
4823            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4824                    + ") has died and restarted (pid " + app.pid + ").");
4825            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4826        } else if (DEBUG_PROCESSES) {
4827            Slog.d(TAG, "Received spurious death notification for thread "
4828                    + thread.asBinder());
4829        }
4830    }
4831
4832    /**
4833     * If a stack trace dump file is configured, dump process stack traces.
4834     * @param clearTraces causes the dump file to be erased prior to the new
4835     *    traces being written, if true; when false, the new traces will be
4836     *    appended to any existing file content.
4837     * @param firstPids of dalvik VM processes to dump stack traces for first
4838     * @param lastPids of dalvik VM processes to dump stack traces for last
4839     * @param nativeProcs optional list of native process names to dump stack crawls
4840     * @return file containing stack traces, or null if no dump file is configured
4841     */
4842    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4843            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4844        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4845        if (tracesPath == null || tracesPath.length() == 0) {
4846            return null;
4847        }
4848
4849        File tracesFile = new File(tracesPath);
4850        try {
4851            File tracesDir = tracesFile.getParentFile();
4852            if (!tracesDir.exists()) {
4853                tracesFile.mkdirs();
4854                if (!SELinux.restorecon(tracesDir)) {
4855                    return null;
4856                }
4857            }
4858            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4859
4860            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4861            tracesFile.createNewFile();
4862            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4863        } catch (IOException e) {
4864            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4865            return null;
4866        }
4867
4868        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4869        return tracesFile;
4870    }
4871
4872    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4873            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4874        // Use a FileObserver to detect when traces finish writing.
4875        // The order of traces is considered important to maintain for legibility.
4876        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4877            @Override
4878            public synchronized void onEvent(int event, String path) { notify(); }
4879        };
4880
4881        try {
4882            observer.startWatching();
4883
4884            // First collect all of the stacks of the most important pids.
4885            if (firstPids != null) {
4886                try {
4887                    int num = firstPids.size();
4888                    for (int i = 0; i < num; i++) {
4889                        synchronized (observer) {
4890                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4891                            observer.wait(200);  // Wait for write-close, give up after 200msec
4892                        }
4893                    }
4894                } catch (InterruptedException e) {
4895                    Log.wtf(TAG, e);
4896                }
4897            }
4898
4899            // Next collect the stacks of the native pids
4900            if (nativeProcs != null) {
4901                int[] pids = Process.getPidsForCommands(nativeProcs);
4902                if (pids != null) {
4903                    for (int pid : pids) {
4904                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4905                    }
4906                }
4907            }
4908
4909            // Lastly, measure CPU usage.
4910            if (processCpuTracker != null) {
4911                processCpuTracker.init();
4912                System.gc();
4913                processCpuTracker.update();
4914                try {
4915                    synchronized (processCpuTracker) {
4916                        processCpuTracker.wait(500); // measure over 1/2 second.
4917                    }
4918                } catch (InterruptedException e) {
4919                }
4920                processCpuTracker.update();
4921
4922                // We'll take the stack crawls of just the top apps using CPU.
4923                final int N = processCpuTracker.countWorkingStats();
4924                int numProcs = 0;
4925                for (int i=0; i<N && numProcs<5; i++) {
4926                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4927                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4928                        numProcs++;
4929                        try {
4930                            synchronized (observer) {
4931                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4932                                observer.wait(200);  // Wait for write-close, give up after 200msec
4933                            }
4934                        } catch (InterruptedException e) {
4935                            Log.wtf(TAG, e);
4936                        }
4937
4938                    }
4939                }
4940            }
4941        } finally {
4942            observer.stopWatching();
4943        }
4944    }
4945
4946    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4947        if (true || IS_USER_BUILD) {
4948            return;
4949        }
4950        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4951        if (tracesPath == null || tracesPath.length() == 0) {
4952            return;
4953        }
4954
4955        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4956        StrictMode.allowThreadDiskWrites();
4957        try {
4958            final File tracesFile = new File(tracesPath);
4959            final File tracesDir = tracesFile.getParentFile();
4960            final File tracesTmp = new File(tracesDir, "__tmp__");
4961            try {
4962                if (!tracesDir.exists()) {
4963                    tracesFile.mkdirs();
4964                    if (!SELinux.restorecon(tracesDir.getPath())) {
4965                        return;
4966                    }
4967                }
4968                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4969
4970                if (tracesFile.exists()) {
4971                    tracesTmp.delete();
4972                    tracesFile.renameTo(tracesTmp);
4973                }
4974                StringBuilder sb = new StringBuilder();
4975                Time tobj = new Time();
4976                tobj.set(System.currentTimeMillis());
4977                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4978                sb.append(": ");
4979                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4980                sb.append(" since ");
4981                sb.append(msg);
4982                FileOutputStream fos = new FileOutputStream(tracesFile);
4983                fos.write(sb.toString().getBytes());
4984                if (app == null) {
4985                    fos.write("\n*** No application process!".getBytes());
4986                }
4987                fos.close();
4988                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4989            } catch (IOException e) {
4990                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4991                return;
4992            }
4993
4994            if (app != null) {
4995                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4996                firstPids.add(app.pid);
4997                dumpStackTraces(tracesPath, firstPids, null, null, null);
4998            }
4999
5000            File lastTracesFile = null;
5001            File curTracesFile = null;
5002            for (int i=9; i>=0; i--) {
5003                String name = String.format(Locale.US, "slow%02d.txt", i);
5004                curTracesFile = new File(tracesDir, name);
5005                if (curTracesFile.exists()) {
5006                    if (lastTracesFile != null) {
5007                        curTracesFile.renameTo(lastTracesFile);
5008                    } else {
5009                        curTracesFile.delete();
5010                    }
5011                }
5012                lastTracesFile = curTracesFile;
5013            }
5014            tracesFile.renameTo(curTracesFile);
5015            if (tracesTmp.exists()) {
5016                tracesTmp.renameTo(tracesFile);
5017            }
5018        } finally {
5019            StrictMode.setThreadPolicy(oldPolicy);
5020        }
5021    }
5022
5023    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5024            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5025        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5026        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5027
5028        if (mController != null) {
5029            try {
5030                // 0 == continue, -1 = kill process immediately
5031                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5032                if (res < 0 && app.pid != MY_PID) {
5033                    app.kill("anr", true);
5034                }
5035            } catch (RemoteException e) {
5036                mController = null;
5037                Watchdog.getInstance().setActivityController(null);
5038            }
5039        }
5040
5041        long anrTime = SystemClock.uptimeMillis();
5042        if (MONITOR_CPU_USAGE) {
5043            updateCpuStatsNow();
5044        }
5045
5046        synchronized (this) {
5047            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5048            if (mShuttingDown) {
5049                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5050                return;
5051            } else if (app.notResponding) {
5052                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5053                return;
5054            } else if (app.crashing) {
5055                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5056                return;
5057            }
5058
5059            // In case we come through here for the same app before completing
5060            // this one, mark as anring now so we will bail out.
5061            app.notResponding = true;
5062
5063            // Log the ANR to the event log.
5064            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5065                    app.processName, app.info.flags, annotation);
5066
5067            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5068            firstPids.add(app.pid);
5069
5070            int parentPid = app.pid;
5071            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5072            if (parentPid != app.pid) firstPids.add(parentPid);
5073
5074            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5075
5076            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5077                ProcessRecord r = mLruProcesses.get(i);
5078                if (r != null && r.thread != null) {
5079                    int pid = r.pid;
5080                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5081                        if (r.persistent) {
5082                            firstPids.add(pid);
5083                        } else {
5084                            lastPids.put(pid, Boolean.TRUE);
5085                        }
5086                    }
5087                }
5088            }
5089        }
5090
5091        // Log the ANR to the main log.
5092        StringBuilder info = new StringBuilder();
5093        info.setLength(0);
5094        info.append("ANR in ").append(app.processName);
5095        if (activity != null && activity.shortComponentName != null) {
5096            info.append(" (").append(activity.shortComponentName).append(")");
5097        }
5098        info.append("\n");
5099        info.append("PID: ").append(app.pid).append("\n");
5100        if (annotation != null) {
5101            info.append("Reason: ").append(annotation).append("\n");
5102        }
5103        if (parent != null && parent != activity) {
5104            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5105        }
5106
5107        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5108
5109        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5110                NATIVE_STACKS_OF_INTEREST);
5111
5112        String cpuInfo = null;
5113        if (MONITOR_CPU_USAGE) {
5114            updateCpuStatsNow();
5115            synchronized (mProcessCpuThread) {
5116                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5117            }
5118            info.append(processCpuTracker.printCurrentLoad());
5119            info.append(cpuInfo);
5120        }
5121
5122        info.append(processCpuTracker.printCurrentState(anrTime));
5123
5124        Slog.e(TAG, info.toString());
5125        if (tracesFile == null) {
5126            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5127            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5128        }
5129
5130        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5131                cpuInfo, tracesFile, null);
5132
5133        if (mController != null) {
5134            try {
5135                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5136                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5137                if (res != 0) {
5138                    if (res < 0 && app.pid != MY_PID) {
5139                        app.kill("anr", true);
5140                    } else {
5141                        synchronized (this) {
5142                            mServices.scheduleServiceTimeoutLocked(app);
5143                        }
5144                    }
5145                    return;
5146                }
5147            } catch (RemoteException e) {
5148                mController = null;
5149                Watchdog.getInstance().setActivityController(null);
5150            }
5151        }
5152
5153        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5154        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5155                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5156
5157        synchronized (this) {
5158            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5159                app.kill("bg anr", true);
5160                return;
5161            }
5162
5163            // Set the app's notResponding state, and look up the errorReportReceiver
5164            makeAppNotRespondingLocked(app,
5165                    activity != null ? activity.shortComponentName : null,
5166                    annotation != null ? "ANR " + annotation : "ANR",
5167                    info.toString());
5168
5169            // Bring up the infamous App Not Responding dialog
5170            Message msg = Message.obtain();
5171            HashMap<String, Object> map = new HashMap<String, Object>();
5172            msg.what = SHOW_NOT_RESPONDING_MSG;
5173            msg.obj = map;
5174            msg.arg1 = aboveSystem ? 1 : 0;
5175            map.put("app", app);
5176            if (activity != null) {
5177                map.put("activity", activity);
5178            }
5179
5180            mHandler.sendMessage(msg);
5181        }
5182    }
5183
5184    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5185        if (!mLaunchWarningShown) {
5186            mLaunchWarningShown = true;
5187            mHandler.post(new Runnable() {
5188                @Override
5189                public void run() {
5190                    synchronized (ActivityManagerService.this) {
5191                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5192                        d.show();
5193                        mHandler.postDelayed(new Runnable() {
5194                            @Override
5195                            public void run() {
5196                                synchronized (ActivityManagerService.this) {
5197                                    d.dismiss();
5198                                    mLaunchWarningShown = false;
5199                                }
5200                            }
5201                        }, 4000);
5202                    }
5203                }
5204            });
5205        }
5206    }
5207
5208    @Override
5209    public boolean clearApplicationUserData(final String packageName,
5210            final IPackageDataObserver observer, int userId) {
5211        enforceNotIsolatedCaller("clearApplicationUserData");
5212        int uid = Binder.getCallingUid();
5213        int pid = Binder.getCallingPid();
5214        userId = handleIncomingUser(pid, uid,
5215                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5216        long callingId = Binder.clearCallingIdentity();
5217        try {
5218            IPackageManager pm = AppGlobals.getPackageManager();
5219            int pkgUid = -1;
5220            synchronized(this) {
5221                try {
5222                    pkgUid = pm.getPackageUid(packageName, userId);
5223                } catch (RemoteException e) {
5224                }
5225                if (pkgUid == -1) {
5226                    Slog.w(TAG, "Invalid packageName: " + packageName);
5227                    if (observer != null) {
5228                        try {
5229                            observer.onRemoveCompleted(packageName, false);
5230                        } catch (RemoteException e) {
5231                            Slog.i(TAG, "Observer no longer exists.");
5232                        }
5233                    }
5234                    return false;
5235                }
5236                if (uid == pkgUid || checkComponentPermission(
5237                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5238                        pid, uid, -1, true)
5239                        == PackageManager.PERMISSION_GRANTED) {
5240                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5241                } else {
5242                    throw new SecurityException("PID " + pid + " does not have permission "
5243                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5244                                    + " of package " + packageName);
5245                }
5246
5247                // Remove all tasks match the cleared application package and user
5248                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5249                    final TaskRecord tr = mRecentTasks.get(i);
5250                    final String taskPackageName =
5251                            tr.getBaseIntent().getComponent().getPackageName();
5252                    if (tr.userId != userId) continue;
5253                    if (!taskPackageName.equals(packageName)) continue;
5254                    removeTaskByIdLocked(tr.taskId, 0);
5255                }
5256            }
5257
5258            try {
5259                // Clear application user data
5260                pm.clearApplicationUserData(packageName, observer, userId);
5261
5262                synchronized(this) {
5263                    // Remove all permissions granted from/to this package
5264                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5265                }
5266
5267                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5268                        Uri.fromParts("package", packageName, null));
5269                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5270                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5271                        null, null, 0, null, null, null, false, false, userId);
5272            } catch (RemoteException e) {
5273            }
5274        } finally {
5275            Binder.restoreCallingIdentity(callingId);
5276        }
5277        return true;
5278    }
5279
5280    @Override
5281    public void killBackgroundProcesses(final String packageName, int userId) {
5282        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5283                != PackageManager.PERMISSION_GRANTED &&
5284                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5285                        != PackageManager.PERMISSION_GRANTED) {
5286            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5287                    + Binder.getCallingPid()
5288                    + ", uid=" + Binder.getCallingUid()
5289                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5290            Slog.w(TAG, msg);
5291            throw new SecurityException(msg);
5292        }
5293
5294        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5295                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5296        long callingId = Binder.clearCallingIdentity();
5297        try {
5298            IPackageManager pm = AppGlobals.getPackageManager();
5299            synchronized(this) {
5300                int appId = -1;
5301                try {
5302                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5303                } catch (RemoteException e) {
5304                }
5305                if (appId == -1) {
5306                    Slog.w(TAG, "Invalid packageName: " + packageName);
5307                    return;
5308                }
5309                killPackageProcessesLocked(packageName, appId, userId,
5310                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5311            }
5312        } finally {
5313            Binder.restoreCallingIdentity(callingId);
5314        }
5315    }
5316
5317    @Override
5318    public void killAllBackgroundProcesses() {
5319        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5320                != PackageManager.PERMISSION_GRANTED) {
5321            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5322                    + Binder.getCallingPid()
5323                    + ", uid=" + Binder.getCallingUid()
5324                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5325            Slog.w(TAG, msg);
5326            throw new SecurityException(msg);
5327        }
5328
5329        long callingId = Binder.clearCallingIdentity();
5330        try {
5331            synchronized(this) {
5332                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5333                final int NP = mProcessNames.getMap().size();
5334                for (int ip=0; ip<NP; ip++) {
5335                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5336                    final int NA = apps.size();
5337                    for (int ia=0; ia<NA; ia++) {
5338                        ProcessRecord app = apps.valueAt(ia);
5339                        if (app.persistent) {
5340                            // we don't kill persistent processes
5341                            continue;
5342                        }
5343                        if (app.removed) {
5344                            procs.add(app);
5345                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5346                            app.removed = true;
5347                            procs.add(app);
5348                        }
5349                    }
5350                }
5351
5352                int N = procs.size();
5353                for (int i=0; i<N; i++) {
5354                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5355                }
5356                mAllowLowerMemLevel = true;
5357                updateOomAdjLocked();
5358                doLowMemReportIfNeededLocked(null);
5359            }
5360        } finally {
5361            Binder.restoreCallingIdentity(callingId);
5362        }
5363    }
5364
5365    @Override
5366    public void forceStopPackage(final String packageName, int userId) {
5367        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5368                != PackageManager.PERMISSION_GRANTED) {
5369            String msg = "Permission Denial: forceStopPackage() from pid="
5370                    + Binder.getCallingPid()
5371                    + ", uid=" + Binder.getCallingUid()
5372                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5373            Slog.w(TAG, msg);
5374            throw new SecurityException(msg);
5375        }
5376        final int callingPid = Binder.getCallingPid();
5377        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5378                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5379        long callingId = Binder.clearCallingIdentity();
5380        try {
5381            IPackageManager pm = AppGlobals.getPackageManager();
5382            synchronized(this) {
5383                int[] users = userId == UserHandle.USER_ALL
5384                        ? getUsersLocked() : new int[] { userId };
5385                for (int user : users) {
5386                    int pkgUid = -1;
5387                    try {
5388                        pkgUid = pm.getPackageUid(packageName, user);
5389                    } catch (RemoteException e) {
5390                    }
5391                    if (pkgUid == -1) {
5392                        Slog.w(TAG, "Invalid packageName: " + packageName);
5393                        continue;
5394                    }
5395                    try {
5396                        pm.setPackageStoppedState(packageName, true, user);
5397                    } catch (RemoteException e) {
5398                    } catch (IllegalArgumentException e) {
5399                        Slog.w(TAG, "Failed trying to unstop package "
5400                                + packageName + ": " + e);
5401                    }
5402                    if (isUserRunningLocked(user, false)) {
5403                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5404                    }
5405                }
5406            }
5407        } finally {
5408            Binder.restoreCallingIdentity(callingId);
5409        }
5410    }
5411
5412    @Override
5413    public void addPackageDependency(String packageName) {
5414        synchronized (this) {
5415            int callingPid = Binder.getCallingPid();
5416            if (callingPid == Process.myPid()) {
5417                //  Yeah, um, no.
5418                Slog.w(TAG, "Can't addPackageDependency on system process");
5419                return;
5420            }
5421            ProcessRecord proc;
5422            synchronized (mPidsSelfLocked) {
5423                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5424            }
5425            if (proc != null) {
5426                if (proc.pkgDeps == null) {
5427                    proc.pkgDeps = new ArraySet<String>(1);
5428                }
5429                proc.pkgDeps.add(packageName);
5430            }
5431        }
5432    }
5433
5434    /*
5435     * The pkg name and app id have to be specified.
5436     */
5437    @Override
5438    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5439        if (pkg == null) {
5440            return;
5441        }
5442        // Make sure the uid is valid.
5443        if (appid < 0) {
5444            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5445            return;
5446        }
5447        int callerUid = Binder.getCallingUid();
5448        // Only the system server can kill an application
5449        if (callerUid == Process.SYSTEM_UID) {
5450            // Post an aysnc message to kill the application
5451            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5452            msg.arg1 = appid;
5453            msg.arg2 = 0;
5454            Bundle bundle = new Bundle();
5455            bundle.putString("pkg", pkg);
5456            bundle.putString("reason", reason);
5457            msg.obj = bundle;
5458            mHandler.sendMessage(msg);
5459        } else {
5460            throw new SecurityException(callerUid + " cannot kill pkg: " +
5461                    pkg);
5462        }
5463    }
5464
5465    @Override
5466    public void closeSystemDialogs(String reason) {
5467        enforceNotIsolatedCaller("closeSystemDialogs");
5468
5469        final int pid = Binder.getCallingPid();
5470        final int uid = Binder.getCallingUid();
5471        final long origId = Binder.clearCallingIdentity();
5472        try {
5473            synchronized (this) {
5474                // Only allow this from foreground processes, so that background
5475                // applications can't abuse it to prevent system UI from being shown.
5476                if (uid >= Process.FIRST_APPLICATION_UID) {
5477                    ProcessRecord proc;
5478                    synchronized (mPidsSelfLocked) {
5479                        proc = mPidsSelfLocked.get(pid);
5480                    }
5481                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5482                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5483                                + " from background process " + proc);
5484                        return;
5485                    }
5486                }
5487                closeSystemDialogsLocked(reason);
5488            }
5489        } finally {
5490            Binder.restoreCallingIdentity(origId);
5491        }
5492    }
5493
5494    void closeSystemDialogsLocked(String reason) {
5495        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5496        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5497                | Intent.FLAG_RECEIVER_FOREGROUND);
5498        if (reason != null) {
5499            intent.putExtra("reason", reason);
5500        }
5501        mWindowManager.closeSystemDialogs(reason);
5502
5503        mStackSupervisor.closeSystemDialogsLocked();
5504
5505        broadcastIntentLocked(null, null, intent, null,
5506                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5507                Process.SYSTEM_UID, UserHandle.USER_ALL);
5508    }
5509
5510    @Override
5511    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5512        enforceNotIsolatedCaller("getProcessMemoryInfo");
5513        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5514        for (int i=pids.length-1; i>=0; i--) {
5515            ProcessRecord proc;
5516            int oomAdj;
5517            synchronized (this) {
5518                synchronized (mPidsSelfLocked) {
5519                    proc = mPidsSelfLocked.get(pids[i]);
5520                    oomAdj = proc != null ? proc.setAdj : 0;
5521                }
5522            }
5523            infos[i] = new Debug.MemoryInfo();
5524            Debug.getMemoryInfo(pids[i], infos[i]);
5525            if (proc != null) {
5526                synchronized (this) {
5527                    if (proc.thread != null && proc.setAdj == oomAdj) {
5528                        // Record this for posterity if the process has been stable.
5529                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5530                                infos[i].getTotalUss(), false, proc.pkgList);
5531                    }
5532                }
5533            }
5534        }
5535        return infos;
5536    }
5537
5538    @Override
5539    public long[] getProcessPss(int[] pids) {
5540        enforceNotIsolatedCaller("getProcessPss");
5541        long[] pss = new long[pids.length];
5542        for (int i=pids.length-1; i>=0; i--) {
5543            ProcessRecord proc;
5544            int oomAdj;
5545            synchronized (this) {
5546                synchronized (mPidsSelfLocked) {
5547                    proc = mPidsSelfLocked.get(pids[i]);
5548                    oomAdj = proc != null ? proc.setAdj : 0;
5549                }
5550            }
5551            long[] tmpUss = new long[1];
5552            pss[i] = Debug.getPss(pids[i], tmpUss);
5553            if (proc != null) {
5554                synchronized (this) {
5555                    if (proc.thread != null && proc.setAdj == oomAdj) {
5556                        // Record this for posterity if the process has been stable.
5557                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5558                    }
5559                }
5560            }
5561        }
5562        return pss;
5563    }
5564
5565    @Override
5566    public void killApplicationProcess(String processName, int uid) {
5567        if (processName == null) {
5568            return;
5569        }
5570
5571        int callerUid = Binder.getCallingUid();
5572        // Only the system server can kill an application
5573        if (callerUid == Process.SYSTEM_UID) {
5574            synchronized (this) {
5575                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5576                if (app != null && app.thread != null) {
5577                    try {
5578                        app.thread.scheduleSuicide();
5579                    } catch (RemoteException e) {
5580                        // If the other end already died, then our work here is done.
5581                    }
5582                } else {
5583                    Slog.w(TAG, "Process/uid not found attempting kill of "
5584                            + processName + " / " + uid);
5585                }
5586            }
5587        } else {
5588            throw new SecurityException(callerUid + " cannot kill app process: " +
5589                    processName);
5590        }
5591    }
5592
5593    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5594        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5595                false, true, false, false, UserHandle.getUserId(uid), reason);
5596        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5597                Uri.fromParts("package", packageName, null));
5598        if (!mProcessesReady) {
5599            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5600                    | Intent.FLAG_RECEIVER_FOREGROUND);
5601        }
5602        intent.putExtra(Intent.EXTRA_UID, uid);
5603        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5604        broadcastIntentLocked(null, null, intent,
5605                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5606                false, false,
5607                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5608    }
5609
5610    private void forceStopUserLocked(int userId, String reason) {
5611        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5612        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5613        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5614                | Intent.FLAG_RECEIVER_FOREGROUND);
5615        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5616        broadcastIntentLocked(null, null, intent,
5617                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5618                false, false,
5619                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5620    }
5621
5622    private final boolean killPackageProcessesLocked(String packageName, int appId,
5623            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5624            boolean doit, boolean evenPersistent, String reason) {
5625        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5626
5627        // Remove all processes this package may have touched: all with the
5628        // same UID (except for the system or root user), and all whose name
5629        // matches the package name.
5630        final int NP = mProcessNames.getMap().size();
5631        for (int ip=0; ip<NP; ip++) {
5632            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5633            final int NA = apps.size();
5634            for (int ia=0; ia<NA; ia++) {
5635                ProcessRecord app = apps.valueAt(ia);
5636                if (app.persistent && !evenPersistent) {
5637                    // we don't kill persistent processes
5638                    continue;
5639                }
5640                if (app.removed) {
5641                    if (doit) {
5642                        procs.add(app);
5643                    }
5644                    continue;
5645                }
5646
5647                // Skip process if it doesn't meet our oom adj requirement.
5648                if (app.setAdj < minOomAdj) {
5649                    continue;
5650                }
5651
5652                // If no package is specified, we call all processes under the
5653                // give user id.
5654                if (packageName == null) {
5655                    if (app.userId != userId) {
5656                        continue;
5657                    }
5658                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5659                        continue;
5660                    }
5661                // Package has been specified, we want to hit all processes
5662                // that match it.  We need to qualify this by the processes
5663                // that are running under the specified app and user ID.
5664                } else {
5665                    final boolean isDep = app.pkgDeps != null
5666                            && app.pkgDeps.contains(packageName);
5667                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5668                        continue;
5669                    }
5670                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5671                        continue;
5672                    }
5673                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5674                        continue;
5675                    }
5676                }
5677
5678                // Process has passed all conditions, kill it!
5679                if (!doit) {
5680                    return true;
5681                }
5682                app.removed = true;
5683                procs.add(app);
5684            }
5685        }
5686
5687        int N = procs.size();
5688        for (int i=0; i<N; i++) {
5689            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5690        }
5691        updateOomAdjLocked();
5692        return N > 0;
5693    }
5694
5695    private final boolean forceStopPackageLocked(String name, int appId,
5696            boolean callerWillRestart, boolean purgeCache, boolean doit,
5697            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5698        int i;
5699        int N;
5700
5701        if (userId == UserHandle.USER_ALL && name == null) {
5702            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5703        }
5704
5705        if (appId < 0 && name != null) {
5706            try {
5707                appId = UserHandle.getAppId(
5708                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5709            } catch (RemoteException e) {
5710            }
5711        }
5712
5713        if (doit) {
5714            if (name != null) {
5715                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5716                        + " user=" + userId + ": " + reason);
5717            } else {
5718                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5719            }
5720
5721            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5722            for (int ip=pmap.size()-1; ip>=0; ip--) {
5723                SparseArray<Long> ba = pmap.valueAt(ip);
5724                for (i=ba.size()-1; i>=0; i--) {
5725                    boolean remove = false;
5726                    final int entUid = ba.keyAt(i);
5727                    if (name != null) {
5728                        if (userId == UserHandle.USER_ALL) {
5729                            if (UserHandle.getAppId(entUid) == appId) {
5730                                remove = true;
5731                            }
5732                        } else {
5733                            if (entUid == UserHandle.getUid(userId, appId)) {
5734                                remove = true;
5735                            }
5736                        }
5737                    } else if (UserHandle.getUserId(entUid) == userId) {
5738                        remove = true;
5739                    }
5740                    if (remove) {
5741                        ba.removeAt(i);
5742                    }
5743                }
5744                if (ba.size() == 0) {
5745                    pmap.removeAt(ip);
5746                }
5747            }
5748        }
5749
5750        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5751                -100, callerWillRestart, true, doit, evenPersistent,
5752                name == null ? ("stop user " + userId) : ("stop " + name));
5753
5754        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5755            if (!doit) {
5756                return true;
5757            }
5758            didSomething = true;
5759        }
5760
5761        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5762            if (!doit) {
5763                return true;
5764            }
5765            didSomething = true;
5766        }
5767
5768        if (name == null) {
5769            // Remove all sticky broadcasts from this user.
5770            mStickyBroadcasts.remove(userId);
5771        }
5772
5773        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5774        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5775                userId, providers)) {
5776            if (!doit) {
5777                return true;
5778            }
5779            didSomething = true;
5780        }
5781        N = providers.size();
5782        for (i=0; i<N; i++) {
5783            removeDyingProviderLocked(null, providers.get(i), true);
5784        }
5785
5786        // Remove transient permissions granted from/to this package/user
5787        removeUriPermissionsForPackageLocked(name, userId, false);
5788
5789        if (name == null || uninstalling) {
5790            // Remove pending intents.  For now we only do this when force
5791            // stopping users, because we have some problems when doing this
5792            // for packages -- app widgets are not currently cleaned up for
5793            // such packages, so they can be left with bad pending intents.
5794            if (mIntentSenderRecords.size() > 0) {
5795                Iterator<WeakReference<PendingIntentRecord>> it
5796                        = mIntentSenderRecords.values().iterator();
5797                while (it.hasNext()) {
5798                    WeakReference<PendingIntentRecord> wpir = it.next();
5799                    if (wpir == null) {
5800                        it.remove();
5801                        continue;
5802                    }
5803                    PendingIntentRecord pir = wpir.get();
5804                    if (pir == null) {
5805                        it.remove();
5806                        continue;
5807                    }
5808                    if (name == null) {
5809                        // Stopping user, remove all objects for the user.
5810                        if (pir.key.userId != userId) {
5811                            // Not the same user, skip it.
5812                            continue;
5813                        }
5814                    } else {
5815                        if (UserHandle.getAppId(pir.uid) != appId) {
5816                            // Different app id, skip it.
5817                            continue;
5818                        }
5819                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5820                            // Different user, skip it.
5821                            continue;
5822                        }
5823                        if (!pir.key.packageName.equals(name)) {
5824                            // Different package, skip it.
5825                            continue;
5826                        }
5827                    }
5828                    if (!doit) {
5829                        return true;
5830                    }
5831                    didSomething = true;
5832                    it.remove();
5833                    pir.canceled = true;
5834                    if (pir.key.activity != null) {
5835                        pir.key.activity.pendingResults.remove(pir.ref);
5836                    }
5837                }
5838            }
5839        }
5840
5841        if (doit) {
5842            if (purgeCache && name != null) {
5843                AttributeCache ac = AttributeCache.instance();
5844                if (ac != null) {
5845                    ac.removePackage(name);
5846                }
5847            }
5848            if (mBooted) {
5849                mStackSupervisor.resumeTopActivitiesLocked();
5850                mStackSupervisor.scheduleIdleLocked();
5851            }
5852        }
5853
5854        return didSomething;
5855    }
5856
5857    private final boolean removeProcessLocked(ProcessRecord app,
5858            boolean callerWillRestart, boolean allowRestart, String reason) {
5859        final String name = app.processName;
5860        final int uid = app.uid;
5861        if (DEBUG_PROCESSES) Slog.d(
5862            TAG, "Force removing proc " + app.toShortString() + " (" + name
5863            + "/" + uid + ")");
5864
5865        mProcessNames.remove(name, uid);
5866        mIsolatedProcesses.remove(app.uid);
5867        if (mHeavyWeightProcess == app) {
5868            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5869                    mHeavyWeightProcess.userId, 0));
5870            mHeavyWeightProcess = null;
5871        }
5872        boolean needRestart = false;
5873        if (app.pid > 0 && app.pid != MY_PID) {
5874            int pid = app.pid;
5875            synchronized (mPidsSelfLocked) {
5876                mPidsSelfLocked.remove(pid);
5877                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5878            }
5879            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5880            if (app.isolated) {
5881                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5882            }
5883            app.kill(reason, true);
5884            handleAppDiedLocked(app, true, allowRestart);
5885            removeLruProcessLocked(app);
5886
5887            if (app.persistent && !app.isolated) {
5888                if (!callerWillRestart) {
5889                    addAppLocked(app.info, false, null /* ABI override */);
5890                } else {
5891                    needRestart = true;
5892                }
5893            }
5894        } else {
5895            mRemovedProcesses.add(app);
5896        }
5897
5898        return needRestart;
5899    }
5900
5901    private final void processStartTimedOutLocked(ProcessRecord app) {
5902        final int pid = app.pid;
5903        boolean gone = false;
5904        synchronized (mPidsSelfLocked) {
5905            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5906            if (knownApp != null && knownApp.thread == null) {
5907                mPidsSelfLocked.remove(pid);
5908                gone = true;
5909            }
5910        }
5911
5912        if (gone) {
5913            Slog.w(TAG, "Process " + app + " failed to attach");
5914            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5915                    pid, app.uid, app.processName);
5916            mProcessNames.remove(app.processName, app.uid);
5917            mIsolatedProcesses.remove(app.uid);
5918            if (mHeavyWeightProcess == app) {
5919                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5920                        mHeavyWeightProcess.userId, 0));
5921                mHeavyWeightProcess = null;
5922            }
5923            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5924            if (app.isolated) {
5925                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5926            }
5927            // Take care of any launching providers waiting for this process.
5928            checkAppInLaunchingProvidersLocked(app, true);
5929            // Take care of any services that are waiting for the process.
5930            mServices.processStartTimedOutLocked(app);
5931            app.kill("start timeout", true);
5932            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5933                Slog.w(TAG, "Unattached app died before backup, skipping");
5934                try {
5935                    IBackupManager bm = IBackupManager.Stub.asInterface(
5936                            ServiceManager.getService(Context.BACKUP_SERVICE));
5937                    bm.agentDisconnected(app.info.packageName);
5938                } catch (RemoteException e) {
5939                    // Can't happen; the backup manager is local
5940                }
5941            }
5942            if (isPendingBroadcastProcessLocked(pid)) {
5943                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5944                skipPendingBroadcastLocked(pid);
5945            }
5946        } else {
5947            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5948        }
5949    }
5950
5951    private final boolean attachApplicationLocked(IApplicationThread thread,
5952            int pid) {
5953
5954        // Find the application record that is being attached...  either via
5955        // the pid if we are running in multiple processes, or just pull the
5956        // next app record if we are emulating process with anonymous threads.
5957        ProcessRecord app;
5958        if (pid != MY_PID && pid >= 0) {
5959            synchronized (mPidsSelfLocked) {
5960                app = mPidsSelfLocked.get(pid);
5961            }
5962        } else {
5963            app = null;
5964        }
5965
5966        if (app == null) {
5967            Slog.w(TAG, "No pending application record for pid " + pid
5968                    + " (IApplicationThread " + thread + "); dropping process");
5969            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5970            if (pid > 0 && pid != MY_PID) {
5971                Process.killProcessQuiet(pid);
5972                //TODO: Process.killProcessGroup(app.info.uid, pid);
5973            } else {
5974                try {
5975                    thread.scheduleExit();
5976                } catch (Exception e) {
5977                    // Ignore exceptions.
5978                }
5979            }
5980            return false;
5981        }
5982
5983        // If this application record is still attached to a previous
5984        // process, clean it up now.
5985        if (app.thread != null) {
5986            handleAppDiedLocked(app, true, true);
5987        }
5988
5989        // Tell the process all about itself.
5990
5991        if (localLOGV) Slog.v(
5992                TAG, "Binding process pid " + pid + " to record " + app);
5993
5994        final String processName = app.processName;
5995        try {
5996            AppDeathRecipient adr = new AppDeathRecipient(
5997                    app, pid, thread);
5998            thread.asBinder().linkToDeath(adr, 0);
5999            app.deathRecipient = adr;
6000        } catch (RemoteException e) {
6001            app.resetPackageList(mProcessStats);
6002            startProcessLocked(app, "link fail", processName);
6003            return false;
6004        }
6005
6006        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6007
6008        app.makeActive(thread, mProcessStats);
6009        app.curAdj = app.setAdj = -100;
6010        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6011        app.forcingToForeground = null;
6012        updateProcessForegroundLocked(app, false, false);
6013        app.hasShownUi = false;
6014        app.debugging = false;
6015        app.cached = false;
6016
6017        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6018
6019        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6020        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6021
6022        if (!normalMode) {
6023            Slog.i(TAG, "Launching preboot mode app: " + app);
6024        }
6025
6026        if (localLOGV) Slog.v(
6027            TAG, "New app record " + app
6028            + " thread=" + thread.asBinder() + " pid=" + pid);
6029        try {
6030            int testMode = IApplicationThread.DEBUG_OFF;
6031            if (mDebugApp != null && mDebugApp.equals(processName)) {
6032                testMode = mWaitForDebugger
6033                    ? IApplicationThread.DEBUG_WAIT
6034                    : IApplicationThread.DEBUG_ON;
6035                app.debugging = true;
6036                if (mDebugTransient) {
6037                    mDebugApp = mOrigDebugApp;
6038                    mWaitForDebugger = mOrigWaitForDebugger;
6039                }
6040            }
6041            String profileFile = app.instrumentationProfileFile;
6042            ParcelFileDescriptor profileFd = null;
6043            int samplingInterval = 0;
6044            boolean profileAutoStop = false;
6045            if (mProfileApp != null && mProfileApp.equals(processName)) {
6046                mProfileProc = app;
6047                profileFile = mProfileFile;
6048                profileFd = mProfileFd;
6049                samplingInterval = mSamplingInterval;
6050                profileAutoStop = mAutoStopProfiler;
6051            }
6052            boolean enableOpenGlTrace = false;
6053            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6054                enableOpenGlTrace = true;
6055                mOpenGlTraceApp = null;
6056            }
6057
6058            // If the app is being launched for restore or full backup, set it up specially
6059            boolean isRestrictedBackupMode = false;
6060            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6061                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6062                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6063                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6064            }
6065
6066            ensurePackageDexOpt(app.instrumentationInfo != null
6067                    ? app.instrumentationInfo.packageName
6068                    : app.info.packageName);
6069            if (app.instrumentationClass != null) {
6070                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6071            }
6072            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6073                    + processName + " with config " + mConfiguration);
6074            ApplicationInfo appInfo = app.instrumentationInfo != null
6075                    ? app.instrumentationInfo : app.info;
6076            app.compat = compatibilityInfoForPackageLocked(appInfo);
6077            if (profileFd != null) {
6078                profileFd = profileFd.dup();
6079            }
6080            ProfilerInfo profilerInfo = profileFile == null ? null
6081                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6082            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6083                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6084                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6085                    isRestrictedBackupMode || !normalMode, app.persistent,
6086                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6087                    mCoreSettingsObserver.getCoreSettingsLocked());
6088            updateLruProcessLocked(app, false, null);
6089            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6090        } catch (Exception e) {
6091            // todo: Yikes!  What should we do?  For now we will try to
6092            // start another process, but that could easily get us in
6093            // an infinite loop of restarting processes...
6094            Slog.w(TAG, "Exception thrown during bind!", e);
6095
6096            app.resetPackageList(mProcessStats);
6097            app.unlinkDeathRecipient();
6098            startProcessLocked(app, "bind fail", processName);
6099            return false;
6100        }
6101
6102        // Remove this record from the list of starting applications.
6103        mPersistentStartingProcesses.remove(app);
6104        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6105                "Attach application locked removing on hold: " + app);
6106        mProcessesOnHold.remove(app);
6107
6108        boolean badApp = false;
6109        boolean didSomething = false;
6110
6111        // See if the top visible activity is waiting to run in this process...
6112        if (normalMode) {
6113            try {
6114                if (mStackSupervisor.attachApplicationLocked(app)) {
6115                    didSomething = true;
6116                }
6117            } catch (Exception e) {
6118                badApp = true;
6119            }
6120        }
6121
6122        // Find any services that should be running in this process...
6123        if (!badApp) {
6124            try {
6125                didSomething |= mServices.attachApplicationLocked(app, processName);
6126            } catch (Exception e) {
6127                badApp = true;
6128            }
6129        }
6130
6131        // Check if a next-broadcast receiver is in this process...
6132        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6133            try {
6134                didSomething |= sendPendingBroadcastsLocked(app);
6135            } catch (Exception e) {
6136                // If the app died trying to launch the receiver we declare it 'bad'
6137                badApp = true;
6138            }
6139        }
6140
6141        // Check whether the next backup agent is in this process...
6142        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6143            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6144            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6145            try {
6146                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6147                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6148                        mBackupTarget.backupMode);
6149            } catch (Exception e) {
6150                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6151                e.printStackTrace();
6152            }
6153        }
6154
6155        if (badApp) {
6156            // todo: Also need to kill application to deal with all
6157            // kinds of exceptions.
6158            handleAppDiedLocked(app, false, true);
6159            return false;
6160        }
6161
6162        if (!didSomething) {
6163            updateOomAdjLocked();
6164        }
6165
6166        return true;
6167    }
6168
6169    @Override
6170    public final void attachApplication(IApplicationThread thread) {
6171        synchronized (this) {
6172            int callingPid = Binder.getCallingPid();
6173            final long origId = Binder.clearCallingIdentity();
6174            attachApplicationLocked(thread, callingPid);
6175            Binder.restoreCallingIdentity(origId);
6176        }
6177    }
6178
6179    @Override
6180    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6181        final long origId = Binder.clearCallingIdentity();
6182        synchronized (this) {
6183            ActivityStack stack = ActivityRecord.getStackLocked(token);
6184            if (stack != null) {
6185                ActivityRecord r =
6186                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6187                if (stopProfiling) {
6188                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6189                        try {
6190                            mProfileFd.close();
6191                        } catch (IOException e) {
6192                        }
6193                        clearProfilerLocked();
6194                    }
6195                }
6196            }
6197        }
6198        Binder.restoreCallingIdentity(origId);
6199    }
6200
6201    void postEnableScreenAfterBootLocked() {
6202        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6203    }
6204
6205    void enableScreenAfterBoot() {
6206        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6207                SystemClock.uptimeMillis());
6208        mWindowManager.enableScreenAfterBoot();
6209
6210        synchronized (this) {
6211            updateEventDispatchingLocked();
6212        }
6213    }
6214
6215    @Override
6216    public void showBootMessage(final CharSequence msg, final boolean always) {
6217        enforceNotIsolatedCaller("showBootMessage");
6218        mWindowManager.showBootMessage(msg, always);
6219    }
6220
6221    @Override
6222    public void keyguardWaitingForActivityDrawn() {
6223        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6224        final long token = Binder.clearCallingIdentity();
6225        try {
6226            synchronized (this) {
6227                if (DEBUG_LOCKSCREEN) logLockScreen("");
6228                mWindowManager.keyguardWaitingForActivityDrawn();
6229            }
6230        } finally {
6231            Binder.restoreCallingIdentity(token);
6232        }
6233    }
6234
6235    final void finishBooting() {
6236        // Register receivers to handle package update events
6237        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6238
6239        // Let system services know.
6240        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6241
6242        synchronized (this) {
6243            // Ensure that any processes we had put on hold are now started
6244            // up.
6245            final int NP = mProcessesOnHold.size();
6246            if (NP > 0) {
6247                ArrayList<ProcessRecord> procs =
6248                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6249                for (int ip=0; ip<NP; ip++) {
6250                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6251                            + procs.get(ip));
6252                    startProcessLocked(procs.get(ip), "on-hold", null);
6253                }
6254            }
6255
6256            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6257                // Start looking for apps that are abusing wake locks.
6258                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6259                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6260                // Tell anyone interested that we are done booting!
6261                SystemProperties.set("sys.boot_completed", "1");
6262                SystemProperties.set("dev.bootcomplete", "1");
6263                for (int i=0; i<mStartedUsers.size(); i++) {
6264                    UserStartedState uss = mStartedUsers.valueAt(i);
6265                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6266                        uss.mState = UserStartedState.STATE_RUNNING;
6267                        final int userId = mStartedUsers.keyAt(i);
6268                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6269                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6270                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6271                        broadcastIntentLocked(null, null, intent, null,
6272                                new IIntentReceiver.Stub() {
6273                                    @Override
6274                                    public void performReceive(Intent intent, int resultCode,
6275                                            String data, Bundle extras, boolean ordered,
6276                                            boolean sticky, int sendingUser) {
6277                                        synchronized (ActivityManagerService.this) {
6278                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6279                                                    true, false);
6280                                        }
6281                                    }
6282                                },
6283                                0, null, null,
6284                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6285                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6286                                userId);
6287                    }
6288                }
6289                scheduleStartProfilesLocked();
6290            }
6291        }
6292    }
6293
6294    final void ensureBootCompleted() {
6295        boolean booting;
6296        boolean enableScreen;
6297        synchronized (this) {
6298            booting = mBooting;
6299            mBooting = false;
6300            enableScreen = !mBooted;
6301            mBooted = true;
6302        }
6303
6304        if (booting) {
6305            finishBooting();
6306        }
6307
6308        if (enableScreen) {
6309            enableScreenAfterBoot();
6310        }
6311    }
6312
6313    @Override
6314    public final void activityResumed(IBinder token) {
6315        final long origId = Binder.clearCallingIdentity();
6316        synchronized(this) {
6317            ActivityStack stack = ActivityRecord.getStackLocked(token);
6318            if (stack != null) {
6319                ActivityRecord.activityResumedLocked(token);
6320            }
6321        }
6322        Binder.restoreCallingIdentity(origId);
6323    }
6324
6325    @Override
6326    public final void activityPaused(IBinder token) {
6327        final long origId = Binder.clearCallingIdentity();
6328        synchronized(this) {
6329            ActivityStack stack = ActivityRecord.getStackLocked(token);
6330            if (stack != null) {
6331                stack.activityPausedLocked(token, false);
6332            }
6333        }
6334        Binder.restoreCallingIdentity(origId);
6335    }
6336
6337    @Override
6338    public final void activityStopped(IBinder token, Bundle icicle,
6339            PersistableBundle persistentState, CharSequence description) {
6340        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6341
6342        // Refuse possible leaked file descriptors
6343        if (icicle != null && icicle.hasFileDescriptors()) {
6344            throw new IllegalArgumentException("File descriptors passed in Bundle");
6345        }
6346
6347        final long origId = Binder.clearCallingIdentity();
6348
6349        synchronized (this) {
6350            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6351            if (r != null) {
6352                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6353            }
6354        }
6355
6356        trimApplications();
6357
6358        Binder.restoreCallingIdentity(origId);
6359    }
6360
6361    @Override
6362    public final void activityDestroyed(IBinder token) {
6363        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6364        synchronized (this) {
6365            ActivityStack stack = ActivityRecord.getStackLocked(token);
6366            if (stack != null) {
6367                stack.activityDestroyedLocked(token);
6368            }
6369        }
6370    }
6371
6372    @Override
6373    public final void backgroundResourcesReleased(IBinder token) {
6374        final long origId = Binder.clearCallingIdentity();
6375        try {
6376            synchronized (this) {
6377                ActivityStack stack = ActivityRecord.getStackLocked(token);
6378                if (stack != null) {
6379                    stack.backgroundResourcesReleased(token);
6380                }
6381            }
6382        } finally {
6383            Binder.restoreCallingIdentity(origId);
6384        }
6385    }
6386
6387    @Override
6388    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6389        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6390    }
6391
6392    @Override
6393    public final void notifyEnterAnimationComplete(IBinder token) {
6394        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6395    }
6396
6397    @Override
6398    public String getCallingPackage(IBinder token) {
6399        synchronized (this) {
6400            ActivityRecord r = getCallingRecordLocked(token);
6401            return r != null ? r.info.packageName : null;
6402        }
6403    }
6404
6405    @Override
6406    public ComponentName getCallingActivity(IBinder token) {
6407        synchronized (this) {
6408            ActivityRecord r = getCallingRecordLocked(token);
6409            return r != null ? r.intent.getComponent() : null;
6410        }
6411    }
6412
6413    private ActivityRecord getCallingRecordLocked(IBinder token) {
6414        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6415        if (r == null) {
6416            return null;
6417        }
6418        return r.resultTo;
6419    }
6420
6421    @Override
6422    public ComponentName getActivityClassForToken(IBinder token) {
6423        synchronized(this) {
6424            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6425            if (r == null) {
6426                return null;
6427            }
6428            return r.intent.getComponent();
6429        }
6430    }
6431
6432    @Override
6433    public String getPackageForToken(IBinder token) {
6434        synchronized(this) {
6435            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6436            if (r == null) {
6437                return null;
6438            }
6439            return r.packageName;
6440        }
6441    }
6442
6443    @Override
6444    public IIntentSender getIntentSender(int type,
6445            String packageName, IBinder token, String resultWho,
6446            int requestCode, Intent[] intents, String[] resolvedTypes,
6447            int flags, Bundle options, int userId) {
6448        enforceNotIsolatedCaller("getIntentSender");
6449        // Refuse possible leaked file descriptors
6450        if (intents != null) {
6451            if (intents.length < 1) {
6452                throw new IllegalArgumentException("Intents array length must be >= 1");
6453            }
6454            for (int i=0; i<intents.length; i++) {
6455                Intent intent = intents[i];
6456                if (intent != null) {
6457                    if (intent.hasFileDescriptors()) {
6458                        throw new IllegalArgumentException("File descriptors passed in Intent");
6459                    }
6460                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6461                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6462                        throw new IllegalArgumentException(
6463                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6464                    }
6465                    intents[i] = new Intent(intent);
6466                }
6467            }
6468            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6469                throw new IllegalArgumentException(
6470                        "Intent array length does not match resolvedTypes length");
6471            }
6472        }
6473        if (options != null) {
6474            if (options.hasFileDescriptors()) {
6475                throw new IllegalArgumentException("File descriptors passed in options");
6476            }
6477        }
6478
6479        synchronized(this) {
6480            int callingUid = Binder.getCallingUid();
6481            int origUserId = userId;
6482            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6483                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6484                    ALLOW_NON_FULL, "getIntentSender", null);
6485            if (origUserId == UserHandle.USER_CURRENT) {
6486                // We don't want to evaluate this until the pending intent is
6487                // actually executed.  However, we do want to always do the
6488                // security checking for it above.
6489                userId = UserHandle.USER_CURRENT;
6490            }
6491            try {
6492                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6493                    int uid = AppGlobals.getPackageManager()
6494                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6495                    if (!UserHandle.isSameApp(callingUid, uid)) {
6496                        String msg = "Permission Denial: getIntentSender() from pid="
6497                            + Binder.getCallingPid()
6498                            + ", uid=" + Binder.getCallingUid()
6499                            + ", (need uid=" + uid + ")"
6500                            + " is not allowed to send as package " + packageName;
6501                        Slog.w(TAG, msg);
6502                        throw new SecurityException(msg);
6503                    }
6504                }
6505
6506                return getIntentSenderLocked(type, packageName, callingUid, userId,
6507                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6508
6509            } catch (RemoteException e) {
6510                throw new SecurityException(e);
6511            }
6512        }
6513    }
6514
6515    IIntentSender getIntentSenderLocked(int type, String packageName,
6516            int callingUid, int userId, IBinder token, String resultWho,
6517            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6518            Bundle options) {
6519        if (DEBUG_MU)
6520            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6521        ActivityRecord activity = null;
6522        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6523            activity = ActivityRecord.isInStackLocked(token);
6524            if (activity == null) {
6525                return null;
6526            }
6527            if (activity.finishing) {
6528                return null;
6529            }
6530        }
6531
6532        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6533        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6534        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6535        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6536                |PendingIntent.FLAG_UPDATE_CURRENT);
6537
6538        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6539                type, packageName, activity, resultWho,
6540                requestCode, intents, resolvedTypes, flags, options, userId);
6541        WeakReference<PendingIntentRecord> ref;
6542        ref = mIntentSenderRecords.get(key);
6543        PendingIntentRecord rec = ref != null ? ref.get() : null;
6544        if (rec != null) {
6545            if (!cancelCurrent) {
6546                if (updateCurrent) {
6547                    if (rec.key.requestIntent != null) {
6548                        rec.key.requestIntent.replaceExtras(intents != null ?
6549                                intents[intents.length - 1] : null);
6550                    }
6551                    if (intents != null) {
6552                        intents[intents.length-1] = rec.key.requestIntent;
6553                        rec.key.allIntents = intents;
6554                        rec.key.allResolvedTypes = resolvedTypes;
6555                    } else {
6556                        rec.key.allIntents = null;
6557                        rec.key.allResolvedTypes = null;
6558                    }
6559                }
6560                return rec;
6561            }
6562            rec.canceled = true;
6563            mIntentSenderRecords.remove(key);
6564        }
6565        if (noCreate) {
6566            return rec;
6567        }
6568        rec = new PendingIntentRecord(this, key, callingUid);
6569        mIntentSenderRecords.put(key, rec.ref);
6570        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6571            if (activity.pendingResults == null) {
6572                activity.pendingResults
6573                        = new HashSet<WeakReference<PendingIntentRecord>>();
6574            }
6575            activity.pendingResults.add(rec.ref);
6576        }
6577        return rec;
6578    }
6579
6580    @Override
6581    public void cancelIntentSender(IIntentSender sender) {
6582        if (!(sender instanceof PendingIntentRecord)) {
6583            return;
6584        }
6585        synchronized(this) {
6586            PendingIntentRecord rec = (PendingIntentRecord)sender;
6587            try {
6588                int uid = AppGlobals.getPackageManager()
6589                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6590                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6591                    String msg = "Permission Denial: cancelIntentSender() from pid="
6592                        + Binder.getCallingPid()
6593                        + ", uid=" + Binder.getCallingUid()
6594                        + " is not allowed to cancel packges "
6595                        + rec.key.packageName;
6596                    Slog.w(TAG, msg);
6597                    throw new SecurityException(msg);
6598                }
6599            } catch (RemoteException e) {
6600                throw new SecurityException(e);
6601            }
6602            cancelIntentSenderLocked(rec, true);
6603        }
6604    }
6605
6606    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6607        rec.canceled = true;
6608        mIntentSenderRecords.remove(rec.key);
6609        if (cleanActivity && rec.key.activity != null) {
6610            rec.key.activity.pendingResults.remove(rec.ref);
6611        }
6612    }
6613
6614    @Override
6615    public String getPackageForIntentSender(IIntentSender pendingResult) {
6616        if (!(pendingResult instanceof PendingIntentRecord)) {
6617            return null;
6618        }
6619        try {
6620            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6621            return res.key.packageName;
6622        } catch (ClassCastException e) {
6623        }
6624        return null;
6625    }
6626
6627    @Override
6628    public int getUidForIntentSender(IIntentSender sender) {
6629        if (sender instanceof PendingIntentRecord) {
6630            try {
6631                PendingIntentRecord res = (PendingIntentRecord)sender;
6632                return res.uid;
6633            } catch (ClassCastException e) {
6634            }
6635        }
6636        return -1;
6637    }
6638
6639    @Override
6640    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6641        if (!(pendingResult instanceof PendingIntentRecord)) {
6642            return false;
6643        }
6644        try {
6645            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6646            if (res.key.allIntents == null) {
6647                return false;
6648            }
6649            for (int i=0; i<res.key.allIntents.length; i++) {
6650                Intent intent = res.key.allIntents[i];
6651                if (intent.getPackage() != null && intent.getComponent() != null) {
6652                    return false;
6653                }
6654            }
6655            return true;
6656        } catch (ClassCastException e) {
6657        }
6658        return false;
6659    }
6660
6661    @Override
6662    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6663        if (!(pendingResult instanceof PendingIntentRecord)) {
6664            return false;
6665        }
6666        try {
6667            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6668            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6669                return true;
6670            }
6671            return false;
6672        } catch (ClassCastException e) {
6673        }
6674        return false;
6675    }
6676
6677    @Override
6678    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6679        if (!(pendingResult instanceof PendingIntentRecord)) {
6680            return null;
6681        }
6682        try {
6683            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6684            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6685        } catch (ClassCastException e) {
6686        }
6687        return null;
6688    }
6689
6690    @Override
6691    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6692        if (!(pendingResult instanceof PendingIntentRecord)) {
6693            return null;
6694        }
6695        try {
6696            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6697            Intent intent = res.key.requestIntent;
6698            if (intent != null) {
6699                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6700                        || res.lastTagPrefix.equals(prefix))) {
6701                    return res.lastTag;
6702                }
6703                res.lastTagPrefix = prefix;
6704                StringBuilder sb = new StringBuilder(128);
6705                if (prefix != null) {
6706                    sb.append(prefix);
6707                }
6708                if (intent.getAction() != null) {
6709                    sb.append(intent.getAction());
6710                } else if (intent.getComponent() != null) {
6711                    intent.getComponent().appendShortString(sb);
6712                } else {
6713                    sb.append("?");
6714                }
6715                return res.lastTag = sb.toString();
6716            }
6717        } catch (ClassCastException e) {
6718        }
6719        return null;
6720    }
6721
6722    @Override
6723    public void setProcessLimit(int max) {
6724        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6725                "setProcessLimit()");
6726        synchronized (this) {
6727            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6728            mProcessLimitOverride = max;
6729        }
6730        trimApplications();
6731    }
6732
6733    @Override
6734    public int getProcessLimit() {
6735        synchronized (this) {
6736            return mProcessLimitOverride;
6737        }
6738    }
6739
6740    void foregroundTokenDied(ForegroundToken token) {
6741        synchronized (ActivityManagerService.this) {
6742            synchronized (mPidsSelfLocked) {
6743                ForegroundToken cur
6744                    = mForegroundProcesses.get(token.pid);
6745                if (cur != token) {
6746                    return;
6747                }
6748                mForegroundProcesses.remove(token.pid);
6749                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6750                if (pr == null) {
6751                    return;
6752                }
6753                pr.forcingToForeground = null;
6754                updateProcessForegroundLocked(pr, false, false);
6755            }
6756            updateOomAdjLocked();
6757        }
6758    }
6759
6760    @Override
6761    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6762        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6763                "setProcessForeground()");
6764        synchronized(this) {
6765            boolean changed = false;
6766
6767            synchronized (mPidsSelfLocked) {
6768                ProcessRecord pr = mPidsSelfLocked.get(pid);
6769                if (pr == null && isForeground) {
6770                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6771                    return;
6772                }
6773                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6774                if (oldToken != null) {
6775                    oldToken.token.unlinkToDeath(oldToken, 0);
6776                    mForegroundProcesses.remove(pid);
6777                    if (pr != null) {
6778                        pr.forcingToForeground = null;
6779                    }
6780                    changed = true;
6781                }
6782                if (isForeground && token != null) {
6783                    ForegroundToken newToken = new ForegroundToken() {
6784                        @Override
6785                        public void binderDied() {
6786                            foregroundTokenDied(this);
6787                        }
6788                    };
6789                    newToken.pid = pid;
6790                    newToken.token = token;
6791                    try {
6792                        token.linkToDeath(newToken, 0);
6793                        mForegroundProcesses.put(pid, newToken);
6794                        pr.forcingToForeground = token;
6795                        changed = true;
6796                    } catch (RemoteException e) {
6797                        // If the process died while doing this, we will later
6798                        // do the cleanup with the process death link.
6799                    }
6800                }
6801            }
6802
6803            if (changed) {
6804                updateOomAdjLocked();
6805            }
6806        }
6807    }
6808
6809    // =========================================================
6810    // PERMISSIONS
6811    // =========================================================
6812
6813    static class PermissionController extends IPermissionController.Stub {
6814        ActivityManagerService mActivityManagerService;
6815        PermissionController(ActivityManagerService activityManagerService) {
6816            mActivityManagerService = activityManagerService;
6817        }
6818
6819        @Override
6820        public boolean checkPermission(String permission, int pid, int uid) {
6821            return mActivityManagerService.checkPermission(permission, pid,
6822                    uid) == PackageManager.PERMISSION_GRANTED;
6823        }
6824    }
6825
6826    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6827        @Override
6828        public int checkComponentPermission(String permission, int pid, int uid,
6829                int owningUid, boolean exported) {
6830            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6831                    owningUid, exported);
6832        }
6833
6834        @Override
6835        public Object getAMSLock() {
6836            return ActivityManagerService.this;
6837        }
6838    }
6839
6840    /**
6841     * This can be called with or without the global lock held.
6842     */
6843    int checkComponentPermission(String permission, int pid, int uid,
6844            int owningUid, boolean exported) {
6845        // We might be performing an operation on behalf of an indirect binder
6846        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6847        // client identity accordingly before proceeding.
6848        Identity tlsIdentity = sCallerIdentity.get();
6849        if (tlsIdentity != null) {
6850            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6851                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6852            uid = tlsIdentity.uid;
6853            pid = tlsIdentity.pid;
6854        }
6855
6856        if (pid == MY_PID) {
6857            return PackageManager.PERMISSION_GRANTED;
6858        }
6859
6860        return ActivityManager.checkComponentPermission(permission, uid,
6861                owningUid, exported);
6862    }
6863
6864    /**
6865     * As the only public entry point for permissions checking, this method
6866     * can enforce the semantic that requesting a check on a null global
6867     * permission is automatically denied.  (Internally a null permission
6868     * string is used when calling {@link #checkComponentPermission} in cases
6869     * when only uid-based security is needed.)
6870     *
6871     * This can be called with or without the global lock held.
6872     */
6873    @Override
6874    public int checkPermission(String permission, int pid, int uid) {
6875        if (permission == null) {
6876            return PackageManager.PERMISSION_DENIED;
6877        }
6878        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6879    }
6880
6881    /**
6882     * Binder IPC calls go through the public entry point.
6883     * This can be called with or without the global lock held.
6884     */
6885    int checkCallingPermission(String permission) {
6886        return checkPermission(permission,
6887                Binder.getCallingPid(),
6888                UserHandle.getAppId(Binder.getCallingUid()));
6889    }
6890
6891    /**
6892     * This can be called with or without the global lock held.
6893     */
6894    void enforceCallingPermission(String permission, String func) {
6895        if (checkCallingPermission(permission)
6896                == PackageManager.PERMISSION_GRANTED) {
6897            return;
6898        }
6899
6900        String msg = "Permission Denial: " + func + " from pid="
6901                + Binder.getCallingPid()
6902                + ", uid=" + Binder.getCallingUid()
6903                + " requires " + permission;
6904        Slog.w(TAG, msg);
6905        throw new SecurityException(msg);
6906    }
6907
6908    /**
6909     * Determine if UID is holding permissions required to access {@link Uri} in
6910     * the given {@link ProviderInfo}. Final permission checking is always done
6911     * in {@link ContentProvider}.
6912     */
6913    private final boolean checkHoldingPermissionsLocked(
6914            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6915        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6916                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6917        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6918            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6919                    != PERMISSION_GRANTED) {
6920                return false;
6921            }
6922        }
6923        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6924    }
6925
6926    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6927            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6928        if (pi.applicationInfo.uid == uid) {
6929            return true;
6930        } else if (!pi.exported) {
6931            return false;
6932        }
6933
6934        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6935        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6936        try {
6937            // check if target holds top-level <provider> permissions
6938            if (!readMet && pi.readPermission != null && considerUidPermissions
6939                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6940                readMet = true;
6941            }
6942            if (!writeMet && pi.writePermission != null && considerUidPermissions
6943                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6944                writeMet = true;
6945            }
6946
6947            // track if unprotected read/write is allowed; any denied
6948            // <path-permission> below removes this ability
6949            boolean allowDefaultRead = pi.readPermission == null;
6950            boolean allowDefaultWrite = pi.writePermission == null;
6951
6952            // check if target holds any <path-permission> that match uri
6953            final PathPermission[] pps = pi.pathPermissions;
6954            if (pps != null) {
6955                final String path = grantUri.uri.getPath();
6956                int i = pps.length;
6957                while (i > 0 && (!readMet || !writeMet)) {
6958                    i--;
6959                    PathPermission pp = pps[i];
6960                    if (pp.match(path)) {
6961                        if (!readMet) {
6962                            final String pprperm = pp.getReadPermission();
6963                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6964                                    + pprperm + " for " + pp.getPath()
6965                                    + ": match=" + pp.match(path)
6966                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6967                            if (pprperm != null) {
6968                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6969                                        == PERMISSION_GRANTED) {
6970                                    readMet = true;
6971                                } else {
6972                                    allowDefaultRead = false;
6973                                }
6974                            }
6975                        }
6976                        if (!writeMet) {
6977                            final String ppwperm = pp.getWritePermission();
6978                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6979                                    + ppwperm + " for " + pp.getPath()
6980                                    + ": match=" + pp.match(path)
6981                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6982                            if (ppwperm != null) {
6983                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6984                                        == PERMISSION_GRANTED) {
6985                                    writeMet = true;
6986                                } else {
6987                                    allowDefaultWrite = false;
6988                                }
6989                            }
6990                        }
6991                    }
6992                }
6993            }
6994
6995            // grant unprotected <provider> read/write, if not blocked by
6996            // <path-permission> above
6997            if (allowDefaultRead) readMet = true;
6998            if (allowDefaultWrite) writeMet = true;
6999
7000        } catch (RemoteException e) {
7001            return false;
7002        }
7003
7004        return readMet && writeMet;
7005    }
7006
7007    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7008        ProviderInfo pi = null;
7009        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7010        if (cpr != null) {
7011            pi = cpr.info;
7012        } else {
7013            try {
7014                pi = AppGlobals.getPackageManager().resolveContentProvider(
7015                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7016            } catch (RemoteException ex) {
7017            }
7018        }
7019        return pi;
7020    }
7021
7022    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7023        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7024        if (targetUris != null) {
7025            return targetUris.get(grantUri);
7026        }
7027        return null;
7028    }
7029
7030    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7031            String targetPkg, int targetUid, GrantUri grantUri) {
7032        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7033        if (targetUris == null) {
7034            targetUris = Maps.newArrayMap();
7035            mGrantedUriPermissions.put(targetUid, targetUris);
7036        }
7037
7038        UriPermission perm = targetUris.get(grantUri);
7039        if (perm == null) {
7040            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7041            targetUris.put(grantUri, perm);
7042        }
7043
7044        return perm;
7045    }
7046
7047    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7048            final int modeFlags) {
7049        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7050        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7051                : UriPermission.STRENGTH_OWNED;
7052
7053        // Root gets to do everything.
7054        if (uid == 0) {
7055            return true;
7056        }
7057
7058        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7059        if (perms == null) return false;
7060
7061        // First look for exact match
7062        final UriPermission exactPerm = perms.get(grantUri);
7063        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7064            return true;
7065        }
7066
7067        // No exact match, look for prefixes
7068        final int N = perms.size();
7069        for (int i = 0; i < N; i++) {
7070            final UriPermission perm = perms.valueAt(i);
7071            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7072                    && perm.getStrength(modeFlags) >= minStrength) {
7073                return true;
7074            }
7075        }
7076
7077        return false;
7078    }
7079
7080    /**
7081     * @param uri This uri must NOT contain an embedded userId.
7082     * @param userId The userId in which the uri is to be resolved.
7083     */
7084    @Override
7085    public int checkUriPermission(Uri uri, int pid, int uid,
7086            final int modeFlags, int userId) {
7087        enforceNotIsolatedCaller("checkUriPermission");
7088
7089        // Another redirected-binder-call permissions check as in
7090        // {@link checkComponentPermission}.
7091        Identity tlsIdentity = sCallerIdentity.get();
7092        if (tlsIdentity != null) {
7093            uid = tlsIdentity.uid;
7094            pid = tlsIdentity.pid;
7095        }
7096
7097        // Our own process gets to do everything.
7098        if (pid == MY_PID) {
7099            return PackageManager.PERMISSION_GRANTED;
7100        }
7101        synchronized (this) {
7102            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7103                    ? PackageManager.PERMISSION_GRANTED
7104                    : PackageManager.PERMISSION_DENIED;
7105        }
7106    }
7107
7108    /**
7109     * Check if the targetPkg can be granted permission to access uri by
7110     * the callingUid using the given modeFlags.  Throws a security exception
7111     * if callingUid is not allowed to do this.  Returns the uid of the target
7112     * if the URI permission grant should be performed; returns -1 if it is not
7113     * needed (for example targetPkg already has permission to access the URI).
7114     * If you already know the uid of the target, you can supply it in
7115     * lastTargetUid else set that to -1.
7116     */
7117    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7118            final int modeFlags, int lastTargetUid) {
7119        if (!Intent.isAccessUriMode(modeFlags)) {
7120            return -1;
7121        }
7122
7123        if (targetPkg != null) {
7124            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7125                    "Checking grant " + targetPkg + " permission to " + grantUri);
7126        }
7127
7128        final IPackageManager pm = AppGlobals.getPackageManager();
7129
7130        // If this is not a content: uri, we can't do anything with it.
7131        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7132            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7133                    "Can't grant URI permission for non-content URI: " + grantUri);
7134            return -1;
7135        }
7136
7137        final String authority = grantUri.uri.getAuthority();
7138        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7139        if (pi == null) {
7140            Slog.w(TAG, "No content provider found for permission check: " +
7141                    grantUri.uri.toSafeString());
7142            return -1;
7143        }
7144
7145        int targetUid = lastTargetUid;
7146        if (targetUid < 0 && targetPkg != null) {
7147            try {
7148                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7149                if (targetUid < 0) {
7150                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7151                            "Can't grant URI permission no uid for: " + targetPkg);
7152                    return -1;
7153                }
7154            } catch (RemoteException ex) {
7155                return -1;
7156            }
7157        }
7158
7159        if (targetUid >= 0) {
7160            // First...  does the target actually need this permission?
7161            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7162                // No need to grant the target this permission.
7163                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7164                        "Target " + targetPkg + " already has full permission to " + grantUri);
7165                return -1;
7166            }
7167        } else {
7168            // First...  there is no target package, so can anyone access it?
7169            boolean allowed = pi.exported;
7170            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7171                if (pi.readPermission != null) {
7172                    allowed = false;
7173                }
7174            }
7175            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7176                if (pi.writePermission != null) {
7177                    allowed = false;
7178                }
7179            }
7180            if (allowed) {
7181                return -1;
7182            }
7183        }
7184
7185        /* There is a special cross user grant if:
7186         * - The target is on another user.
7187         * - Apps on the current user can access the uri without any uid permissions.
7188         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7189         * grant uri permissions.
7190         */
7191        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7192                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7193                modeFlags, false /*without considering the uid permissions*/);
7194
7195        // Second...  is the provider allowing granting of URI permissions?
7196        if (!specialCrossUserGrant) {
7197            if (!pi.grantUriPermissions) {
7198                throw new SecurityException("Provider " + pi.packageName
7199                        + "/" + pi.name
7200                        + " does not allow granting of Uri permissions (uri "
7201                        + grantUri + ")");
7202            }
7203            if (pi.uriPermissionPatterns != null) {
7204                final int N = pi.uriPermissionPatterns.length;
7205                boolean allowed = false;
7206                for (int i=0; i<N; i++) {
7207                    if (pi.uriPermissionPatterns[i] != null
7208                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7209                        allowed = true;
7210                        break;
7211                    }
7212                }
7213                if (!allowed) {
7214                    throw new SecurityException("Provider " + pi.packageName
7215                            + "/" + pi.name
7216                            + " does not allow granting of permission to path of Uri "
7217                            + grantUri);
7218                }
7219            }
7220        }
7221
7222        // Third...  does the caller itself have permission to access
7223        // this uri?
7224        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7225            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7226                // Require they hold a strong enough Uri permission
7227                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7228                    throw new SecurityException("Uid " + callingUid
7229                            + " does not have permission to uri " + grantUri);
7230                }
7231            }
7232        }
7233        return targetUid;
7234    }
7235
7236    /**
7237     * @param uri This uri must NOT contain an embedded userId.
7238     * @param userId The userId in which the uri is to be resolved.
7239     */
7240    @Override
7241    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7242            final int modeFlags, int userId) {
7243        enforceNotIsolatedCaller("checkGrantUriPermission");
7244        synchronized(this) {
7245            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7246                    new GrantUri(userId, uri, false), modeFlags, -1);
7247        }
7248    }
7249
7250    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7251            final int modeFlags, UriPermissionOwner owner) {
7252        if (!Intent.isAccessUriMode(modeFlags)) {
7253            return;
7254        }
7255
7256        // So here we are: the caller has the assumed permission
7257        // to the uri, and the target doesn't.  Let's now give this to
7258        // the target.
7259
7260        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7261                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7262
7263        final String authority = grantUri.uri.getAuthority();
7264        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7265        if (pi == null) {
7266            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7267            return;
7268        }
7269
7270        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7271            grantUri.prefix = true;
7272        }
7273        final UriPermission perm = findOrCreateUriPermissionLocked(
7274                pi.packageName, targetPkg, targetUid, grantUri);
7275        perm.grantModes(modeFlags, owner);
7276    }
7277
7278    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7279            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7280        if (targetPkg == null) {
7281            throw new NullPointerException("targetPkg");
7282        }
7283        int targetUid;
7284        final IPackageManager pm = AppGlobals.getPackageManager();
7285        try {
7286            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7287        } catch (RemoteException ex) {
7288            return;
7289        }
7290
7291        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7292                targetUid);
7293        if (targetUid < 0) {
7294            return;
7295        }
7296
7297        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7298                owner);
7299    }
7300
7301    static class NeededUriGrants extends ArrayList<GrantUri> {
7302        final String targetPkg;
7303        final int targetUid;
7304        final int flags;
7305
7306        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7307            this.targetPkg = targetPkg;
7308            this.targetUid = targetUid;
7309            this.flags = flags;
7310        }
7311    }
7312
7313    /**
7314     * Like checkGrantUriPermissionLocked, but takes an Intent.
7315     */
7316    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7317            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7318        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7319                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7320                + " clip=" + (intent != null ? intent.getClipData() : null)
7321                + " from " + intent + "; flags=0x"
7322                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7323
7324        if (targetPkg == null) {
7325            throw new NullPointerException("targetPkg");
7326        }
7327
7328        if (intent == null) {
7329            return null;
7330        }
7331        Uri data = intent.getData();
7332        ClipData clip = intent.getClipData();
7333        if (data == null && clip == null) {
7334            return null;
7335        }
7336        // Default userId for uris in the intent (if they don't specify it themselves)
7337        int contentUserHint = intent.getContentUserHint();
7338        if (contentUserHint == UserHandle.USER_CURRENT) {
7339            contentUserHint = UserHandle.getUserId(callingUid);
7340        }
7341        final IPackageManager pm = AppGlobals.getPackageManager();
7342        int targetUid;
7343        if (needed != null) {
7344            targetUid = needed.targetUid;
7345        } else {
7346            try {
7347                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7348            } catch (RemoteException ex) {
7349                return null;
7350            }
7351            if (targetUid < 0) {
7352                if (DEBUG_URI_PERMISSION) {
7353                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7354                            + " on user " + targetUserId);
7355                }
7356                return null;
7357            }
7358        }
7359        if (data != null) {
7360            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7361            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7362                    targetUid);
7363            if (targetUid > 0) {
7364                if (needed == null) {
7365                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7366                }
7367                needed.add(grantUri);
7368            }
7369        }
7370        if (clip != null) {
7371            for (int i=0; i<clip.getItemCount(); i++) {
7372                Uri uri = clip.getItemAt(i).getUri();
7373                if (uri != null) {
7374                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7375                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7376                            targetUid);
7377                    if (targetUid > 0) {
7378                        if (needed == null) {
7379                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7380                        }
7381                        needed.add(grantUri);
7382                    }
7383                } else {
7384                    Intent clipIntent = clip.getItemAt(i).getIntent();
7385                    if (clipIntent != null) {
7386                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7387                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7388                        if (newNeeded != null) {
7389                            needed = newNeeded;
7390                        }
7391                    }
7392                }
7393            }
7394        }
7395
7396        return needed;
7397    }
7398
7399    /**
7400     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7401     */
7402    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7403            UriPermissionOwner owner) {
7404        if (needed != null) {
7405            for (int i=0; i<needed.size(); i++) {
7406                GrantUri grantUri = needed.get(i);
7407                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7408                        grantUri, needed.flags, owner);
7409            }
7410        }
7411    }
7412
7413    void grantUriPermissionFromIntentLocked(int callingUid,
7414            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7415        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7416                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7417        if (needed == null) {
7418            return;
7419        }
7420
7421        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7422    }
7423
7424    /**
7425     * @param uri This uri must NOT contain an embedded userId.
7426     * @param userId The userId in which the uri is to be resolved.
7427     */
7428    @Override
7429    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7430            final int modeFlags, int userId) {
7431        enforceNotIsolatedCaller("grantUriPermission");
7432        GrantUri grantUri = new GrantUri(userId, uri, false);
7433        synchronized(this) {
7434            final ProcessRecord r = getRecordForAppLocked(caller);
7435            if (r == null) {
7436                throw new SecurityException("Unable to find app for caller "
7437                        + caller
7438                        + " when granting permission to uri " + grantUri);
7439            }
7440            if (targetPkg == null) {
7441                throw new IllegalArgumentException("null target");
7442            }
7443            if (grantUri == null) {
7444                throw new IllegalArgumentException("null uri");
7445            }
7446
7447            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7448                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7449                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7450                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7451
7452            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7453                    UserHandle.getUserId(r.uid));
7454        }
7455    }
7456
7457    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7458        if (perm.modeFlags == 0) {
7459            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7460                    perm.targetUid);
7461            if (perms != null) {
7462                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7463                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7464
7465                perms.remove(perm.uri);
7466                if (perms.isEmpty()) {
7467                    mGrantedUriPermissions.remove(perm.targetUid);
7468                }
7469            }
7470        }
7471    }
7472
7473    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7474        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7475
7476        final IPackageManager pm = AppGlobals.getPackageManager();
7477        final String authority = grantUri.uri.getAuthority();
7478        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7479        if (pi == null) {
7480            Slog.w(TAG, "No content provider found for permission revoke: "
7481                    + grantUri.toSafeString());
7482            return;
7483        }
7484
7485        // Does the caller have this permission on the URI?
7486        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7487            // Right now, if you are not the original owner of the permission,
7488            // you are not allowed to revoke it.
7489            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7490                throw new SecurityException("Uid " + callingUid
7491                        + " does not have permission to uri " + grantUri);
7492            //}
7493        }
7494
7495        boolean persistChanged = false;
7496
7497        // Go through all of the permissions and remove any that match.
7498        int N = mGrantedUriPermissions.size();
7499        for (int i = 0; i < N; i++) {
7500            final int targetUid = mGrantedUriPermissions.keyAt(i);
7501            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7502
7503            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7504                final UriPermission perm = it.next();
7505                if (perm.uri.sourceUserId == grantUri.sourceUserId
7506                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7507                    if (DEBUG_URI_PERMISSION)
7508                        Slog.v(TAG,
7509                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7510                    persistChanged |= perm.revokeModes(
7511                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7512                    if (perm.modeFlags == 0) {
7513                        it.remove();
7514                    }
7515                }
7516            }
7517
7518            if (perms.isEmpty()) {
7519                mGrantedUriPermissions.remove(targetUid);
7520                N--;
7521                i--;
7522            }
7523        }
7524
7525        if (persistChanged) {
7526            schedulePersistUriGrants();
7527        }
7528    }
7529
7530    /**
7531     * @param uri This uri must NOT contain an embedded userId.
7532     * @param userId The userId in which the uri is to be resolved.
7533     */
7534    @Override
7535    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7536            int userId) {
7537        enforceNotIsolatedCaller("revokeUriPermission");
7538        synchronized(this) {
7539            final ProcessRecord r = getRecordForAppLocked(caller);
7540            if (r == null) {
7541                throw new SecurityException("Unable to find app for caller "
7542                        + caller
7543                        + " when revoking permission to uri " + uri);
7544            }
7545            if (uri == null) {
7546                Slog.w(TAG, "revokeUriPermission: null uri");
7547                return;
7548            }
7549
7550            if (!Intent.isAccessUriMode(modeFlags)) {
7551                return;
7552            }
7553
7554            final IPackageManager pm = AppGlobals.getPackageManager();
7555            final String authority = uri.getAuthority();
7556            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7557            if (pi == null) {
7558                Slog.w(TAG, "No content provider found for permission revoke: "
7559                        + uri.toSafeString());
7560                return;
7561            }
7562
7563            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7564        }
7565    }
7566
7567    /**
7568     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7569     * given package.
7570     *
7571     * @param packageName Package name to match, or {@code null} to apply to all
7572     *            packages.
7573     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7574     *            to all users.
7575     * @param persistable If persistable grants should be removed.
7576     */
7577    private void removeUriPermissionsForPackageLocked(
7578            String packageName, int userHandle, boolean persistable) {
7579        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7580            throw new IllegalArgumentException("Must narrow by either package or user");
7581        }
7582
7583        boolean persistChanged = false;
7584
7585        int N = mGrantedUriPermissions.size();
7586        for (int i = 0; i < N; i++) {
7587            final int targetUid = mGrantedUriPermissions.keyAt(i);
7588            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7589
7590            // Only inspect grants matching user
7591            if (userHandle == UserHandle.USER_ALL
7592                    || userHandle == UserHandle.getUserId(targetUid)) {
7593                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7594                    final UriPermission perm = it.next();
7595
7596                    // Only inspect grants matching package
7597                    if (packageName == null || perm.sourcePkg.equals(packageName)
7598                            || perm.targetPkg.equals(packageName)) {
7599                        persistChanged |= perm.revokeModes(
7600                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7601
7602                        // Only remove when no modes remain; any persisted grants
7603                        // will keep this alive.
7604                        if (perm.modeFlags == 0) {
7605                            it.remove();
7606                        }
7607                    }
7608                }
7609
7610                if (perms.isEmpty()) {
7611                    mGrantedUriPermissions.remove(targetUid);
7612                    N--;
7613                    i--;
7614                }
7615            }
7616        }
7617
7618        if (persistChanged) {
7619            schedulePersistUriGrants();
7620        }
7621    }
7622
7623    @Override
7624    public IBinder newUriPermissionOwner(String name) {
7625        enforceNotIsolatedCaller("newUriPermissionOwner");
7626        synchronized(this) {
7627            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7628            return owner.getExternalTokenLocked();
7629        }
7630    }
7631
7632    /**
7633     * @param uri This uri must NOT contain an embedded userId.
7634     * @param sourceUserId The userId in which the uri is to be resolved.
7635     * @param targetUserId The userId of the app that receives the grant.
7636     */
7637    @Override
7638    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7639            final int modeFlags, int sourceUserId, int targetUserId) {
7640        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7641                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7642        synchronized(this) {
7643            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7644            if (owner == null) {
7645                throw new IllegalArgumentException("Unknown owner: " + token);
7646            }
7647            if (fromUid != Binder.getCallingUid()) {
7648                if (Binder.getCallingUid() != Process.myUid()) {
7649                    // Only system code can grant URI permissions on behalf
7650                    // of other users.
7651                    throw new SecurityException("nice try");
7652                }
7653            }
7654            if (targetPkg == null) {
7655                throw new IllegalArgumentException("null target");
7656            }
7657            if (uri == null) {
7658                throw new IllegalArgumentException("null uri");
7659            }
7660
7661            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7662                    modeFlags, owner, targetUserId);
7663        }
7664    }
7665
7666    /**
7667     * @param uri This uri must NOT contain an embedded userId.
7668     * @param userId The userId in which the uri is to be resolved.
7669     */
7670    @Override
7671    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7672        synchronized(this) {
7673            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7674            if (owner == null) {
7675                throw new IllegalArgumentException("Unknown owner: " + token);
7676            }
7677
7678            if (uri == null) {
7679                owner.removeUriPermissionsLocked(mode);
7680            } else {
7681                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7682            }
7683        }
7684    }
7685
7686    private void schedulePersistUriGrants() {
7687        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7688            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7689                    10 * DateUtils.SECOND_IN_MILLIS);
7690        }
7691    }
7692
7693    private void writeGrantedUriPermissions() {
7694        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7695
7696        // Snapshot permissions so we can persist without lock
7697        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7698        synchronized (this) {
7699            final int size = mGrantedUriPermissions.size();
7700            for (int i = 0; i < size; i++) {
7701                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7702                for (UriPermission perm : perms.values()) {
7703                    if (perm.persistedModeFlags != 0) {
7704                        persist.add(perm.snapshot());
7705                    }
7706                }
7707            }
7708        }
7709
7710        FileOutputStream fos = null;
7711        try {
7712            fos = mGrantFile.startWrite();
7713
7714            XmlSerializer out = new FastXmlSerializer();
7715            out.setOutput(fos, "utf-8");
7716            out.startDocument(null, true);
7717            out.startTag(null, TAG_URI_GRANTS);
7718            for (UriPermission.Snapshot perm : persist) {
7719                out.startTag(null, TAG_URI_GRANT);
7720                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7721                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7722                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7723                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7724                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7725                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7726                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7727                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7728                out.endTag(null, TAG_URI_GRANT);
7729            }
7730            out.endTag(null, TAG_URI_GRANTS);
7731            out.endDocument();
7732
7733            mGrantFile.finishWrite(fos);
7734        } catch (IOException e) {
7735            if (fos != null) {
7736                mGrantFile.failWrite(fos);
7737            }
7738        }
7739    }
7740
7741    private void readGrantedUriPermissionsLocked() {
7742        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7743
7744        final long now = System.currentTimeMillis();
7745
7746        FileInputStream fis = null;
7747        try {
7748            fis = mGrantFile.openRead();
7749            final XmlPullParser in = Xml.newPullParser();
7750            in.setInput(fis, null);
7751
7752            int type;
7753            while ((type = in.next()) != END_DOCUMENT) {
7754                final String tag = in.getName();
7755                if (type == START_TAG) {
7756                    if (TAG_URI_GRANT.equals(tag)) {
7757                        final int sourceUserId;
7758                        final int targetUserId;
7759                        final int userHandle = readIntAttribute(in,
7760                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7761                        if (userHandle != UserHandle.USER_NULL) {
7762                            // For backwards compatibility.
7763                            sourceUserId = userHandle;
7764                            targetUserId = userHandle;
7765                        } else {
7766                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7767                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7768                        }
7769                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7770                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7771                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7772                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7773                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7774                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7775
7776                        // Sanity check that provider still belongs to source package
7777                        final ProviderInfo pi = getProviderInfoLocked(
7778                                uri.getAuthority(), sourceUserId);
7779                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7780                            int targetUid = -1;
7781                            try {
7782                                targetUid = AppGlobals.getPackageManager()
7783                                        .getPackageUid(targetPkg, targetUserId);
7784                            } catch (RemoteException e) {
7785                            }
7786                            if (targetUid != -1) {
7787                                final UriPermission perm = findOrCreateUriPermissionLocked(
7788                                        sourcePkg, targetPkg, targetUid,
7789                                        new GrantUri(sourceUserId, uri, prefix));
7790                                perm.initPersistedModes(modeFlags, createdTime);
7791                            }
7792                        } else {
7793                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7794                                    + " but instead found " + pi);
7795                        }
7796                    }
7797                }
7798            }
7799        } catch (FileNotFoundException e) {
7800            // Missing grants is okay
7801        } catch (IOException e) {
7802            Log.wtf(TAG, "Failed reading Uri grants", e);
7803        } catch (XmlPullParserException e) {
7804            Log.wtf(TAG, "Failed reading Uri grants", e);
7805        } finally {
7806            IoUtils.closeQuietly(fis);
7807        }
7808    }
7809
7810    /**
7811     * @param uri This uri must NOT contain an embedded userId.
7812     * @param userId The userId in which the uri is to be resolved.
7813     */
7814    @Override
7815    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7816        enforceNotIsolatedCaller("takePersistableUriPermission");
7817
7818        Preconditions.checkFlagsArgument(modeFlags,
7819                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7820
7821        synchronized (this) {
7822            final int callingUid = Binder.getCallingUid();
7823            boolean persistChanged = false;
7824            GrantUri grantUri = new GrantUri(userId, uri, false);
7825
7826            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7827                    new GrantUri(userId, uri, false));
7828            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7829                    new GrantUri(userId, uri, true));
7830
7831            final boolean exactValid = (exactPerm != null)
7832                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7833            final boolean prefixValid = (prefixPerm != null)
7834                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7835
7836            if (!(exactValid || prefixValid)) {
7837                throw new SecurityException("No persistable permission grants found for UID "
7838                        + callingUid + " and Uri " + grantUri.toSafeString());
7839            }
7840
7841            if (exactValid) {
7842                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7843            }
7844            if (prefixValid) {
7845                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7846            }
7847
7848            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7849
7850            if (persistChanged) {
7851                schedulePersistUriGrants();
7852            }
7853        }
7854    }
7855
7856    /**
7857     * @param uri This uri must NOT contain an embedded userId.
7858     * @param userId The userId in which the uri is to be resolved.
7859     */
7860    @Override
7861    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7862        enforceNotIsolatedCaller("releasePersistableUriPermission");
7863
7864        Preconditions.checkFlagsArgument(modeFlags,
7865                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7866
7867        synchronized (this) {
7868            final int callingUid = Binder.getCallingUid();
7869            boolean persistChanged = false;
7870
7871            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7872                    new GrantUri(userId, uri, false));
7873            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7874                    new GrantUri(userId, uri, true));
7875            if (exactPerm == null && prefixPerm == null) {
7876                throw new SecurityException("No permission grants found for UID " + callingUid
7877                        + " and Uri " + uri.toSafeString());
7878            }
7879
7880            if (exactPerm != null) {
7881                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7882                removeUriPermissionIfNeededLocked(exactPerm);
7883            }
7884            if (prefixPerm != null) {
7885                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7886                removeUriPermissionIfNeededLocked(prefixPerm);
7887            }
7888
7889            if (persistChanged) {
7890                schedulePersistUriGrants();
7891            }
7892        }
7893    }
7894
7895    /**
7896     * Prune any older {@link UriPermission} for the given UID until outstanding
7897     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7898     *
7899     * @return if any mutations occured that require persisting.
7900     */
7901    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7902        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7903        if (perms == null) return false;
7904        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7905
7906        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7907        for (UriPermission perm : perms.values()) {
7908            if (perm.persistedModeFlags != 0) {
7909                persisted.add(perm);
7910            }
7911        }
7912
7913        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7914        if (trimCount <= 0) return false;
7915
7916        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7917        for (int i = 0; i < trimCount; i++) {
7918            final UriPermission perm = persisted.get(i);
7919
7920            if (DEBUG_URI_PERMISSION) {
7921                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7922            }
7923
7924            perm.releasePersistableModes(~0);
7925            removeUriPermissionIfNeededLocked(perm);
7926        }
7927
7928        return true;
7929    }
7930
7931    @Override
7932    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7933            String packageName, boolean incoming) {
7934        enforceNotIsolatedCaller("getPersistedUriPermissions");
7935        Preconditions.checkNotNull(packageName, "packageName");
7936
7937        final int callingUid = Binder.getCallingUid();
7938        final IPackageManager pm = AppGlobals.getPackageManager();
7939        try {
7940            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7941            if (packageUid != callingUid) {
7942                throw new SecurityException(
7943                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7944            }
7945        } catch (RemoteException e) {
7946            throw new SecurityException("Failed to verify package name ownership");
7947        }
7948
7949        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7950        synchronized (this) {
7951            if (incoming) {
7952                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7953                        callingUid);
7954                if (perms == null) {
7955                    Slog.w(TAG, "No permission grants found for " + packageName);
7956                } else {
7957                    for (UriPermission perm : perms.values()) {
7958                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7959                            result.add(perm.buildPersistedPublicApiObject());
7960                        }
7961                    }
7962                }
7963            } else {
7964                final int size = mGrantedUriPermissions.size();
7965                for (int i = 0; i < size; i++) {
7966                    final ArrayMap<GrantUri, UriPermission> perms =
7967                            mGrantedUriPermissions.valueAt(i);
7968                    for (UriPermission perm : perms.values()) {
7969                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7970                            result.add(perm.buildPersistedPublicApiObject());
7971                        }
7972                    }
7973                }
7974            }
7975        }
7976        return new ParceledListSlice<android.content.UriPermission>(result);
7977    }
7978
7979    @Override
7980    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7981        synchronized (this) {
7982            ProcessRecord app =
7983                who != null ? getRecordForAppLocked(who) : null;
7984            if (app == null) return;
7985
7986            Message msg = Message.obtain();
7987            msg.what = WAIT_FOR_DEBUGGER_MSG;
7988            msg.obj = app;
7989            msg.arg1 = waiting ? 1 : 0;
7990            mHandler.sendMessage(msg);
7991        }
7992    }
7993
7994    @Override
7995    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7996        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7997        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7998        outInfo.availMem = Process.getFreeMemory();
7999        outInfo.totalMem = Process.getTotalMemory();
8000        outInfo.threshold = homeAppMem;
8001        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8002        outInfo.hiddenAppThreshold = cachedAppMem;
8003        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8004                ProcessList.SERVICE_ADJ);
8005        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8006                ProcessList.VISIBLE_APP_ADJ);
8007        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8008                ProcessList.FOREGROUND_APP_ADJ);
8009    }
8010
8011    // =========================================================
8012    // TASK MANAGEMENT
8013    // =========================================================
8014
8015    @Override
8016    public List<IAppTask> getAppTasks(String callingPackage) {
8017        int callingUid = Binder.getCallingUid();
8018        long ident = Binder.clearCallingIdentity();
8019
8020        synchronized(this) {
8021            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8022            try {
8023                if (localLOGV) Slog.v(TAG, "getAppTasks");
8024
8025                final int N = mRecentTasks.size();
8026                for (int i = 0; i < N; i++) {
8027                    TaskRecord tr = mRecentTasks.get(i);
8028                    // Skip tasks that do not match the caller.  We don't need to verify
8029                    // callingPackage, because we are also limiting to callingUid and know
8030                    // that will limit to the correct security sandbox.
8031                    if (tr.effectiveUid != callingUid) {
8032                        continue;
8033                    }
8034                    Intent intent = tr.getBaseIntent();
8035                    if (intent == null ||
8036                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8037                        continue;
8038                    }
8039                    ActivityManager.RecentTaskInfo taskInfo =
8040                            createRecentTaskInfoFromTaskRecord(tr);
8041                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8042                    list.add(taskImpl);
8043                }
8044            } finally {
8045                Binder.restoreCallingIdentity(ident);
8046            }
8047            return list;
8048        }
8049    }
8050
8051    @Override
8052    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8053        final int callingUid = Binder.getCallingUid();
8054        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8055
8056        synchronized(this) {
8057            if (localLOGV) Slog.v(
8058                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8059
8060            final boolean allowed = checkCallingPermission(
8061                    android.Manifest.permission.GET_TASKS)
8062                    == PackageManager.PERMISSION_GRANTED;
8063            if (!allowed) {
8064                Slog.w(TAG, "getTasks: caller " + callingUid
8065                        + " does not hold GET_TASKS; limiting output");
8066            }
8067
8068            // TODO: Improve with MRU list from all ActivityStacks.
8069            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8070        }
8071
8072        return list;
8073    }
8074
8075    TaskRecord getMostRecentTask() {
8076        return mRecentTasks.get(0);
8077    }
8078
8079    /**
8080     * Creates a new RecentTaskInfo from a TaskRecord.
8081     */
8082    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8083        // Update the task description to reflect any changes in the task stack
8084        tr.updateTaskDescription();
8085
8086        // Compose the recent task info
8087        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8088        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8089        rti.persistentId = tr.taskId;
8090        rti.baseIntent = new Intent(tr.getBaseIntent());
8091        rti.origActivity = tr.origActivity;
8092        rti.description = tr.lastDescription;
8093        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8094        rti.userId = tr.userId;
8095        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8096        rti.firstActiveTime = tr.firstActiveTime;
8097        rti.lastActiveTime = tr.lastActiveTime;
8098        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8099        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8100        return rti;
8101    }
8102
8103    @Override
8104    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8105        final int callingUid = Binder.getCallingUid();
8106        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8107                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8108
8109        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8110        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8111        synchronized (this) {
8112            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8113                    == PackageManager.PERMISSION_GRANTED;
8114            if (!allowed) {
8115                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8116                        + " does not hold GET_TASKS; limiting output");
8117            }
8118            final boolean detailed = checkCallingPermission(
8119                    android.Manifest.permission.GET_DETAILED_TASKS)
8120                    == PackageManager.PERMISSION_GRANTED;
8121
8122            final int N = mRecentTasks.size();
8123            ArrayList<ActivityManager.RecentTaskInfo> res
8124                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8125                            maxNum < N ? maxNum : N);
8126
8127            final Set<Integer> includedUsers;
8128            if (includeProfiles) {
8129                includedUsers = getProfileIdsLocked(userId);
8130            } else {
8131                includedUsers = new HashSet<Integer>();
8132            }
8133            includedUsers.add(Integer.valueOf(userId));
8134
8135            for (int i=0; i<N && maxNum > 0; i++) {
8136                TaskRecord tr = mRecentTasks.get(i);
8137                // Only add calling user or related users recent tasks
8138                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8139                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8140                    continue;
8141                }
8142
8143                // Return the entry if desired by the caller.  We always return
8144                // the first entry, because callers always expect this to be the
8145                // foreground app.  We may filter others if the caller has
8146                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8147                // we should exclude the entry.
8148
8149                if (i == 0
8150                        || withExcluded
8151                        || (tr.intent == null)
8152                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8153                                == 0)) {
8154                    if (!allowed) {
8155                        // If the caller doesn't have the GET_TASKS permission, then only
8156                        // allow them to see a small subset of tasks -- their own and home.
8157                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8158                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8159                            continue;
8160                        }
8161                    }
8162                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8163                        if (tr.stack != null && tr.stack.isHomeStack()) {
8164                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8165                            continue;
8166                        }
8167                    }
8168                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8169                        // Don't include auto remove tasks that are finished or finishing.
8170                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8171                                + tr);
8172                        continue;
8173                    }
8174                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8175                            && !tr.isAvailable) {
8176                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8177                        continue;
8178                    }
8179
8180                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8181                    if (!detailed) {
8182                        rti.baseIntent.replaceExtras((Bundle)null);
8183                    }
8184
8185                    res.add(rti);
8186                    maxNum--;
8187                }
8188            }
8189            return res;
8190        }
8191    }
8192
8193    private TaskRecord recentTaskForIdLocked(int id) {
8194        final int N = mRecentTasks.size();
8195            for (int i=0; i<N; i++) {
8196                TaskRecord tr = mRecentTasks.get(i);
8197                if (tr.taskId == id) {
8198                    return tr;
8199                }
8200            }
8201            return null;
8202    }
8203
8204    @Override
8205    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8206        synchronized (this) {
8207            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8208                    "getTaskThumbnail()");
8209            TaskRecord tr = recentTaskForIdLocked(id);
8210            if (tr != null) {
8211                return tr.getTaskThumbnailLocked();
8212            }
8213        }
8214        return null;
8215    }
8216
8217    @Override
8218    public int addAppTask(IBinder activityToken, Intent intent,
8219            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8220        final int callingUid = Binder.getCallingUid();
8221        final long callingIdent = Binder.clearCallingIdentity();
8222
8223        try {
8224            synchronized (this) {
8225                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8226                if (r == null) {
8227                    throw new IllegalArgumentException("Activity does not exist; token="
8228                            + activityToken);
8229                }
8230                ComponentName comp = intent.getComponent();
8231                if (comp == null) {
8232                    throw new IllegalArgumentException("Intent " + intent
8233                            + " must specify explicit component");
8234                }
8235                if (thumbnail.getWidth() != mThumbnailWidth
8236                        || thumbnail.getHeight() != mThumbnailHeight) {
8237                    throw new IllegalArgumentException("Bad thumbnail size: got "
8238                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8239                            + mThumbnailWidth + "x" + mThumbnailHeight);
8240                }
8241                if (intent.getSelector() != null) {
8242                    intent.setSelector(null);
8243                }
8244                if (intent.getSourceBounds() != null) {
8245                    intent.setSourceBounds(null);
8246                }
8247                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8248                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8249                        // The caller has added this as an auto-remove task...  that makes no
8250                        // sense, so turn off auto-remove.
8251                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8252                    }
8253                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8254                    // Must be a new task.
8255                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8256                }
8257                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8258                    mLastAddedTaskActivity = null;
8259                }
8260                ActivityInfo ainfo = mLastAddedTaskActivity;
8261                if (ainfo == null) {
8262                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8263                            comp, 0, UserHandle.getUserId(callingUid));
8264                    if (ainfo.applicationInfo.uid != callingUid) {
8265                        throw new SecurityException(
8266                                "Can't add task for another application: target uid="
8267                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8268                    }
8269                }
8270
8271                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8272                        intent, description);
8273
8274                int trimIdx = trimRecentsForTask(task, false);
8275                if (trimIdx >= 0) {
8276                    // If this would have caused a trim, then we'll abort because that
8277                    // means it would be added at the end of the list but then just removed.
8278                    return -1;
8279                }
8280
8281                final int N = mRecentTasks.size();
8282                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8283                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8284                    tr.removedFromRecents(mTaskPersister);
8285                }
8286
8287                task.inRecents = true;
8288                mRecentTasks.add(task);
8289                r.task.stack.addTask(task, false, false);
8290
8291                task.setLastThumbnail(thumbnail);
8292                task.freeLastThumbnail();
8293
8294                return task.taskId;
8295            }
8296        } finally {
8297            Binder.restoreCallingIdentity(callingIdent);
8298        }
8299    }
8300
8301    @Override
8302    public Point getAppTaskThumbnailSize() {
8303        synchronized (this) {
8304            return new Point(mThumbnailWidth,  mThumbnailHeight);
8305        }
8306    }
8307
8308    @Override
8309    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8310        synchronized (this) {
8311            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8312            if (r != null) {
8313                r.taskDescription = td;
8314                r.task.updateTaskDescription();
8315            }
8316        }
8317    }
8318
8319    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8320        mRecentTasks.remove(tr);
8321        tr.removedFromRecents(mTaskPersister);
8322        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8323        Intent baseIntent = new Intent(
8324                tr.intent != null ? tr.intent : tr.affinityIntent);
8325        ComponentName component = baseIntent.getComponent();
8326        if (component == null) {
8327            Slog.w(TAG, "Now component for base intent of task: " + tr);
8328            return;
8329        }
8330
8331        // Find any running services associated with this app.
8332        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8333
8334        if (killProcesses) {
8335            // Find any running processes associated with this app.
8336            final String pkg = component.getPackageName();
8337            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8338            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8339            for (int i=0; i<pmap.size(); i++) {
8340                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8341                for (int j=0; j<uids.size(); j++) {
8342                    ProcessRecord proc = uids.valueAt(j);
8343                    if (proc.userId != tr.userId) {
8344                        continue;
8345                    }
8346                    if (!proc.pkgList.containsKey(pkg)) {
8347                        continue;
8348                    }
8349                    procs.add(proc);
8350                }
8351            }
8352
8353            // Kill the running processes.
8354            for (int i=0; i<procs.size(); i++) {
8355                ProcessRecord pr = procs.get(i);
8356                if (pr == mHomeProcess) {
8357                    // Don't kill the home process along with tasks from the same package.
8358                    continue;
8359                }
8360                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8361                    pr.kill("remove task", true);
8362                } else {
8363                    pr.waitingToKill = "remove task";
8364                }
8365            }
8366        }
8367    }
8368
8369    /**
8370     * Removes the task with the specified task id.
8371     *
8372     * @param taskId Identifier of the task to be removed.
8373     * @param flags Additional operational flags.  May be 0 or
8374     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8375     * @return Returns true if the given task was found and removed.
8376     */
8377    private boolean removeTaskByIdLocked(int taskId, int flags) {
8378        TaskRecord tr = recentTaskForIdLocked(taskId);
8379        if (tr != null) {
8380            tr.removeTaskActivitiesLocked();
8381            cleanUpRemovedTaskLocked(tr, flags);
8382            if (tr.isPersistable) {
8383                notifyTaskPersisterLocked(null, true);
8384            }
8385            return true;
8386        }
8387        return false;
8388    }
8389
8390    @Override
8391    public boolean removeTask(int taskId, int flags) {
8392        synchronized (this) {
8393            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8394                    "removeTask()");
8395            long ident = Binder.clearCallingIdentity();
8396            try {
8397                return removeTaskByIdLocked(taskId, flags);
8398            } finally {
8399                Binder.restoreCallingIdentity(ident);
8400            }
8401        }
8402    }
8403
8404    /**
8405     * TODO: Add mController hook
8406     */
8407    @Override
8408    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8409        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8410                "moveTaskToFront()");
8411
8412        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8413        synchronized(this) {
8414            moveTaskToFrontLocked(taskId, flags, options);
8415        }
8416    }
8417
8418    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8419        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8420                Binder.getCallingUid(), "Task to front")) {
8421            ActivityOptions.abort(options);
8422            return;
8423        }
8424        final long origId = Binder.clearCallingIdentity();
8425        try {
8426            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8427            if (task == null) {
8428                return;
8429            }
8430            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8431                mStackSupervisor.showLockTaskToast();
8432                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8433                return;
8434            }
8435            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8436            if (prev != null && prev.isRecentsActivity()) {
8437                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8438            }
8439            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8440        } finally {
8441            Binder.restoreCallingIdentity(origId);
8442        }
8443        ActivityOptions.abort(options);
8444    }
8445
8446    @Override
8447    public void moveTaskToBack(int taskId) {
8448        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8449                "moveTaskToBack()");
8450
8451        synchronized(this) {
8452            TaskRecord tr = recentTaskForIdLocked(taskId);
8453            if (tr != null) {
8454                if (tr == mStackSupervisor.mLockTaskModeTask) {
8455                    mStackSupervisor.showLockTaskToast();
8456                    return;
8457                }
8458                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8459                ActivityStack stack = tr.stack;
8460                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8461                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8462                            Binder.getCallingUid(), "Task to back")) {
8463                        return;
8464                    }
8465                }
8466                final long origId = Binder.clearCallingIdentity();
8467                try {
8468                    stack.moveTaskToBackLocked(taskId, null);
8469                } finally {
8470                    Binder.restoreCallingIdentity(origId);
8471                }
8472            }
8473        }
8474    }
8475
8476    /**
8477     * Moves an activity, and all of the other activities within the same task, to the bottom
8478     * of the history stack.  The activity's order within the task is unchanged.
8479     *
8480     * @param token A reference to the activity we wish to move
8481     * @param nonRoot If false then this only works if the activity is the root
8482     *                of a task; if true it will work for any activity in a task.
8483     * @return Returns true if the move completed, false if not.
8484     */
8485    @Override
8486    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8487        enforceNotIsolatedCaller("moveActivityTaskToBack");
8488        synchronized(this) {
8489            final long origId = Binder.clearCallingIdentity();
8490            try {
8491                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8492                if (taskId >= 0) {
8493                    if ((mStackSupervisor.mLockTaskModeTask != null)
8494                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8495                        mStackSupervisor.showLockTaskToast();
8496                        return false;
8497                    }
8498                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8499                }
8500            } finally {
8501                Binder.restoreCallingIdentity(origId);
8502            }
8503        }
8504        return false;
8505    }
8506
8507    @Override
8508    public void moveTaskBackwards(int task) {
8509        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8510                "moveTaskBackwards()");
8511
8512        synchronized(this) {
8513            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8514                    Binder.getCallingUid(), "Task backwards")) {
8515                return;
8516            }
8517            final long origId = Binder.clearCallingIdentity();
8518            moveTaskBackwardsLocked(task);
8519            Binder.restoreCallingIdentity(origId);
8520        }
8521    }
8522
8523    private final void moveTaskBackwardsLocked(int task) {
8524        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8525    }
8526
8527    @Override
8528    public IBinder getHomeActivityToken() throws RemoteException {
8529        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8530                "getHomeActivityToken()");
8531        synchronized (this) {
8532            return mStackSupervisor.getHomeActivityToken();
8533        }
8534    }
8535
8536    @Override
8537    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8538            IActivityContainerCallback callback) throws RemoteException {
8539        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8540                "createActivityContainer()");
8541        synchronized (this) {
8542            if (parentActivityToken == null) {
8543                throw new IllegalArgumentException("parent token must not be null");
8544            }
8545            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8546            if (r == null) {
8547                return null;
8548            }
8549            if (callback == null) {
8550                throw new IllegalArgumentException("callback must not be null");
8551            }
8552            return mStackSupervisor.createActivityContainer(r, callback);
8553        }
8554    }
8555
8556    @Override
8557    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8558        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8559                "deleteActivityContainer()");
8560        synchronized (this) {
8561            mStackSupervisor.deleteActivityContainer(container);
8562        }
8563    }
8564
8565    @Override
8566    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8567            throws RemoteException {
8568        synchronized (this) {
8569            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8570            if (stack != null) {
8571                return stack.mActivityContainer;
8572            }
8573            return null;
8574        }
8575    }
8576
8577    @Override
8578    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8579        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8580                "moveTaskToStack()");
8581        if (stackId == HOME_STACK_ID) {
8582            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8583                    new RuntimeException("here").fillInStackTrace());
8584        }
8585        synchronized (this) {
8586            long ident = Binder.clearCallingIdentity();
8587            try {
8588                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8589                        + stackId + " toTop=" + toTop);
8590                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8591            } finally {
8592                Binder.restoreCallingIdentity(ident);
8593            }
8594        }
8595    }
8596
8597    @Override
8598    public void resizeStack(int stackBoxId, Rect bounds) {
8599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8600                "resizeStackBox()");
8601        long ident = Binder.clearCallingIdentity();
8602        try {
8603            mWindowManager.resizeStack(stackBoxId, bounds);
8604        } finally {
8605            Binder.restoreCallingIdentity(ident);
8606        }
8607    }
8608
8609    @Override
8610    public List<StackInfo> getAllStackInfos() {
8611        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8612                "getAllStackInfos()");
8613        long ident = Binder.clearCallingIdentity();
8614        try {
8615            synchronized (this) {
8616                return mStackSupervisor.getAllStackInfosLocked();
8617            }
8618        } finally {
8619            Binder.restoreCallingIdentity(ident);
8620        }
8621    }
8622
8623    @Override
8624    public StackInfo getStackInfo(int stackId) {
8625        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8626                "getStackInfo()");
8627        long ident = Binder.clearCallingIdentity();
8628        try {
8629            synchronized (this) {
8630                return mStackSupervisor.getStackInfoLocked(stackId);
8631            }
8632        } finally {
8633            Binder.restoreCallingIdentity(ident);
8634        }
8635    }
8636
8637    @Override
8638    public boolean isInHomeStack(int taskId) {
8639        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8640                "getStackInfo()");
8641        long ident = Binder.clearCallingIdentity();
8642        try {
8643            synchronized (this) {
8644                TaskRecord tr = recentTaskForIdLocked(taskId);
8645                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8646            }
8647        } finally {
8648            Binder.restoreCallingIdentity(ident);
8649        }
8650    }
8651
8652    @Override
8653    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8654        synchronized(this) {
8655            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8656        }
8657    }
8658
8659    private boolean isLockTaskAuthorized(String pkg) {
8660        final DevicePolicyManager dpm = (DevicePolicyManager)
8661                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8662        try {
8663            int uid = mContext.getPackageManager().getPackageUid(pkg,
8664                    Binder.getCallingUserHandle().getIdentifier());
8665            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8666        } catch (NameNotFoundException e) {
8667            return false;
8668        }
8669    }
8670
8671    void startLockTaskMode(TaskRecord task) {
8672        final String pkg;
8673        synchronized (this) {
8674            pkg = task.intent.getComponent().getPackageName();
8675        }
8676        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8677        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8678            final TaskRecord taskRecord = task;
8679            mHandler.post(new Runnable() {
8680                @Override
8681                public void run() {
8682                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8683                }
8684            });
8685            return;
8686        }
8687        long ident = Binder.clearCallingIdentity();
8688        try {
8689            synchronized (this) {
8690                // Since we lost lock on task, make sure it is still there.
8691                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8692                if (task != null) {
8693                    if (!isSystemInitiated
8694                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8695                        throw new IllegalArgumentException("Invalid task, not in foreground");
8696                    }
8697                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8698                }
8699            }
8700        } finally {
8701            Binder.restoreCallingIdentity(ident);
8702        }
8703    }
8704
8705    @Override
8706    public void startLockTaskMode(int taskId) {
8707        final TaskRecord task;
8708        long ident = Binder.clearCallingIdentity();
8709        try {
8710            synchronized (this) {
8711                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8712            }
8713        } finally {
8714            Binder.restoreCallingIdentity(ident);
8715        }
8716        if (task != null) {
8717            startLockTaskMode(task);
8718        }
8719    }
8720
8721    @Override
8722    public void startLockTaskMode(IBinder token) {
8723        final TaskRecord task;
8724        long ident = Binder.clearCallingIdentity();
8725        try {
8726            synchronized (this) {
8727                final ActivityRecord r = ActivityRecord.forToken(token);
8728                if (r == null) {
8729                    return;
8730                }
8731                task = r.task;
8732            }
8733        } finally {
8734            Binder.restoreCallingIdentity(ident);
8735        }
8736        if (task != null) {
8737            startLockTaskMode(task);
8738        }
8739    }
8740
8741    @Override
8742    public void startLockTaskModeOnCurrent() throws RemoteException {
8743        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744                "startLockTaskModeOnCurrent");
8745        ActivityRecord r = null;
8746        synchronized (this) {
8747            r = mStackSupervisor.topRunningActivityLocked();
8748        }
8749        startLockTaskMode(r.task);
8750    }
8751
8752    @Override
8753    public void stopLockTaskMode() {
8754        // Verify that the user matches the package of the intent for the TaskRecord
8755        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8756        // and stopLockTaskMode.
8757        final int callingUid = Binder.getCallingUid();
8758        if (callingUid != Process.SYSTEM_UID) {
8759            try {
8760                String pkg =
8761                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8762                int uid = mContext.getPackageManager().getPackageUid(pkg,
8763                        Binder.getCallingUserHandle().getIdentifier());
8764                if (uid != callingUid) {
8765                    throw new SecurityException("Invalid uid, expected " + uid);
8766                }
8767            } catch (NameNotFoundException e) {
8768                Log.d(TAG, "stopLockTaskMode " + e);
8769                return;
8770            }
8771        }
8772        long ident = Binder.clearCallingIdentity();
8773        try {
8774            Log.d(TAG, "stopLockTaskMode");
8775            // Stop lock task
8776            synchronized (this) {
8777                mStackSupervisor.setLockTaskModeLocked(null, false);
8778            }
8779        } finally {
8780            Binder.restoreCallingIdentity(ident);
8781        }
8782    }
8783
8784    @Override
8785    public void stopLockTaskModeOnCurrent() throws RemoteException {
8786        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8787                "stopLockTaskModeOnCurrent");
8788        long ident = Binder.clearCallingIdentity();
8789        try {
8790            stopLockTaskMode();
8791        } finally {
8792            Binder.restoreCallingIdentity(ident);
8793        }
8794    }
8795
8796    @Override
8797    public boolean isInLockTaskMode() {
8798        synchronized (this) {
8799            return mStackSupervisor.isInLockTaskMode();
8800        }
8801    }
8802
8803    // =========================================================
8804    // CONTENT PROVIDERS
8805    // =========================================================
8806
8807    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8808        List<ProviderInfo> providers = null;
8809        try {
8810            providers = AppGlobals.getPackageManager().
8811                queryContentProviders(app.processName, app.uid,
8812                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8813        } catch (RemoteException ex) {
8814        }
8815        if (DEBUG_MU)
8816            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8817        int userId = app.userId;
8818        if (providers != null) {
8819            int N = providers.size();
8820            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8821            for (int i=0; i<N; i++) {
8822                ProviderInfo cpi =
8823                    (ProviderInfo)providers.get(i);
8824                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8825                        cpi.name, cpi.flags);
8826                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8827                    // This is a singleton provider, but a user besides the
8828                    // default user is asking to initialize a process it runs
8829                    // in...  well, no, it doesn't actually run in this process,
8830                    // it runs in the process of the default user.  Get rid of it.
8831                    providers.remove(i);
8832                    N--;
8833                    i--;
8834                    continue;
8835                }
8836
8837                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8838                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8839                if (cpr == null) {
8840                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8841                    mProviderMap.putProviderByClass(comp, cpr);
8842                }
8843                if (DEBUG_MU)
8844                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8845                app.pubProviders.put(cpi.name, cpr);
8846                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8847                    // Don't add this if it is a platform component that is marked
8848                    // to run in multiple processes, because this is actually
8849                    // part of the framework so doesn't make sense to track as a
8850                    // separate apk in the process.
8851                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8852                            mProcessStats);
8853                }
8854                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8855            }
8856        }
8857        return providers;
8858    }
8859
8860    /**
8861     * Check if {@link ProcessRecord} has a possible chance at accessing the
8862     * given {@link ProviderInfo}. Final permission checking is always done
8863     * in {@link ContentProvider}.
8864     */
8865    private final String checkContentProviderPermissionLocked(
8866            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8867        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8868        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8869        boolean checkedGrants = false;
8870        if (checkUser) {
8871            // Looking for cross-user grants before enforcing the typical cross-users permissions
8872            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8873            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8874                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8875                    return null;
8876                }
8877                checkedGrants = true;
8878            }
8879            userId = handleIncomingUser(callingPid, callingUid, userId,
8880                    false, ALLOW_NON_FULL,
8881                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8882            if (userId != tmpTargetUserId) {
8883                // When we actually went to determine the final targer user ID, this ended
8884                // up different than our initial check for the authority.  This is because
8885                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8886                // SELF.  So we need to re-check the grants again.
8887                checkedGrants = false;
8888            }
8889        }
8890        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8891                cpi.applicationInfo.uid, cpi.exported)
8892                == PackageManager.PERMISSION_GRANTED) {
8893            return null;
8894        }
8895        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8896                cpi.applicationInfo.uid, cpi.exported)
8897                == PackageManager.PERMISSION_GRANTED) {
8898            return null;
8899        }
8900
8901        PathPermission[] pps = cpi.pathPermissions;
8902        if (pps != null) {
8903            int i = pps.length;
8904            while (i > 0) {
8905                i--;
8906                PathPermission pp = pps[i];
8907                String pprperm = pp.getReadPermission();
8908                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8909                        cpi.applicationInfo.uid, cpi.exported)
8910                        == PackageManager.PERMISSION_GRANTED) {
8911                    return null;
8912                }
8913                String ppwperm = pp.getWritePermission();
8914                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8915                        cpi.applicationInfo.uid, cpi.exported)
8916                        == PackageManager.PERMISSION_GRANTED) {
8917                    return null;
8918                }
8919            }
8920        }
8921        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8922            return null;
8923        }
8924
8925        String msg;
8926        if (!cpi.exported) {
8927            msg = "Permission Denial: opening provider " + cpi.name
8928                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8929                    + ", uid=" + callingUid + ") that is not exported from uid "
8930                    + cpi.applicationInfo.uid;
8931        } else {
8932            msg = "Permission Denial: opening provider " + cpi.name
8933                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8934                    + ", uid=" + callingUid + ") requires "
8935                    + cpi.readPermission + " or " + cpi.writePermission;
8936        }
8937        Slog.w(TAG, msg);
8938        return msg;
8939    }
8940
8941    /**
8942     * Returns if the ContentProvider has granted a uri to callingUid
8943     */
8944    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8945        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8946        if (perms != null) {
8947            for (int i=perms.size()-1; i>=0; i--) {
8948                GrantUri grantUri = perms.keyAt(i);
8949                if (grantUri.sourceUserId == userId || !checkUser) {
8950                    if (matchesProvider(grantUri.uri, cpi)) {
8951                        return true;
8952                    }
8953                }
8954            }
8955        }
8956        return false;
8957    }
8958
8959    /**
8960     * Returns true if the uri authority is one of the authorities specified in the provider.
8961     */
8962    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8963        String uriAuth = uri.getAuthority();
8964        String cpiAuth = cpi.authority;
8965        if (cpiAuth.indexOf(';') == -1) {
8966            return cpiAuth.equals(uriAuth);
8967        }
8968        String[] cpiAuths = cpiAuth.split(";");
8969        int length = cpiAuths.length;
8970        for (int i = 0; i < length; i++) {
8971            if (cpiAuths[i].equals(uriAuth)) return true;
8972        }
8973        return false;
8974    }
8975
8976    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8977            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8978        if (r != null) {
8979            for (int i=0; i<r.conProviders.size(); i++) {
8980                ContentProviderConnection conn = r.conProviders.get(i);
8981                if (conn.provider == cpr) {
8982                    if (DEBUG_PROVIDER) Slog.v(TAG,
8983                            "Adding provider requested by "
8984                            + r.processName + " from process "
8985                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8986                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8987                    if (stable) {
8988                        conn.stableCount++;
8989                        conn.numStableIncs++;
8990                    } else {
8991                        conn.unstableCount++;
8992                        conn.numUnstableIncs++;
8993                    }
8994                    return conn;
8995                }
8996            }
8997            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8998            if (stable) {
8999                conn.stableCount = 1;
9000                conn.numStableIncs = 1;
9001            } else {
9002                conn.unstableCount = 1;
9003                conn.numUnstableIncs = 1;
9004            }
9005            cpr.connections.add(conn);
9006            r.conProviders.add(conn);
9007            return conn;
9008        }
9009        cpr.addExternalProcessHandleLocked(externalProcessToken);
9010        return null;
9011    }
9012
9013    boolean decProviderCountLocked(ContentProviderConnection conn,
9014            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9015        if (conn != null) {
9016            cpr = conn.provider;
9017            if (DEBUG_PROVIDER) Slog.v(TAG,
9018                    "Removing provider requested by "
9019                    + conn.client.processName + " from process "
9020                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9021                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9022            if (stable) {
9023                conn.stableCount--;
9024            } else {
9025                conn.unstableCount--;
9026            }
9027            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9028                cpr.connections.remove(conn);
9029                conn.client.conProviders.remove(conn);
9030                return true;
9031            }
9032            return false;
9033        }
9034        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9035        return false;
9036    }
9037
9038    private void checkTime(long startTime, String where) {
9039        long now = SystemClock.elapsedRealtime();
9040        if ((now-startTime) > 1000) {
9041            // If we are taking more than a second, log about it.
9042            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9043        }
9044    }
9045
9046    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9047            String name, IBinder token, boolean stable, int userId) {
9048        ContentProviderRecord cpr;
9049        ContentProviderConnection conn = null;
9050        ProviderInfo cpi = null;
9051
9052        synchronized(this) {
9053            long startTime = SystemClock.elapsedRealtime();
9054
9055            ProcessRecord r = null;
9056            if (caller != null) {
9057                r = getRecordForAppLocked(caller);
9058                if (r == null) {
9059                    throw new SecurityException(
9060                            "Unable to find app for caller " + caller
9061                          + " (pid=" + Binder.getCallingPid()
9062                          + ") when getting content provider " + name);
9063                }
9064            }
9065
9066            boolean checkCrossUser = true;
9067
9068            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9069
9070            // First check if this content provider has been published...
9071            cpr = mProviderMap.getProviderByName(name, userId);
9072            // If that didn't work, check if it exists for user 0 and then
9073            // verify that it's a singleton provider before using it.
9074            if (cpr == null && userId != UserHandle.USER_OWNER) {
9075                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9076                if (cpr != null) {
9077                    cpi = cpr.info;
9078                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9079                            cpi.name, cpi.flags)
9080                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9081                        userId = UserHandle.USER_OWNER;
9082                        checkCrossUser = false;
9083                    } else {
9084                        cpr = null;
9085                        cpi = null;
9086                    }
9087                }
9088            }
9089
9090            boolean providerRunning = cpr != null;
9091            if (providerRunning) {
9092                cpi = cpr.info;
9093                String msg;
9094                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9095                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9096                        != null) {
9097                    throw new SecurityException(msg);
9098                }
9099                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9100
9101                if (r != null && cpr.canRunHere(r)) {
9102                    // This provider has been published or is in the process
9103                    // of being published...  but it is also allowed to run
9104                    // in the caller's process, so don't make a connection
9105                    // and just let the caller instantiate its own instance.
9106                    ContentProviderHolder holder = cpr.newHolder(null);
9107                    // don't give caller the provider object, it needs
9108                    // to make its own.
9109                    holder.provider = null;
9110                    return holder;
9111                }
9112
9113                final long origId = Binder.clearCallingIdentity();
9114
9115                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9116
9117                // In this case the provider instance already exists, so we can
9118                // return it right away.
9119                conn = incProviderCountLocked(r, cpr, token, stable);
9120                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9121                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9122                        // If this is a perceptible app accessing the provider,
9123                        // make sure to count it as being accessed and thus
9124                        // back up on the LRU list.  This is good because
9125                        // content providers are often expensive to start.
9126                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9127                        updateLruProcessLocked(cpr.proc, false, null);
9128                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9129                    }
9130                }
9131
9132                if (cpr.proc != null) {
9133                    if (false) {
9134                        if (cpr.name.flattenToShortString().equals(
9135                                "com.android.providers.calendar/.CalendarProvider2")) {
9136                            Slog.v(TAG, "****************** KILLING "
9137                                + cpr.name.flattenToShortString());
9138                            Process.killProcess(cpr.proc.pid);
9139                        }
9140                    }
9141                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9142                    boolean success = updateOomAdjLocked(cpr.proc);
9143                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9144                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9145                    // NOTE: there is still a race here where a signal could be
9146                    // pending on the process even though we managed to update its
9147                    // adj level.  Not sure what to do about this, but at least
9148                    // the race is now smaller.
9149                    if (!success) {
9150                        // Uh oh...  it looks like the provider's process
9151                        // has been killed on us.  We need to wait for a new
9152                        // process to be started, and make sure its death
9153                        // doesn't kill our process.
9154                        Slog.i(TAG,
9155                                "Existing provider " + cpr.name.flattenToShortString()
9156                                + " is crashing; detaching " + r);
9157                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9158                        checkTime(startTime, "getContentProviderImpl: before appDied");
9159                        appDiedLocked(cpr.proc);
9160                        checkTime(startTime, "getContentProviderImpl: after appDied");
9161                        if (!lastRef) {
9162                            // This wasn't the last ref our process had on
9163                            // the provider...  we have now been killed, bail.
9164                            return null;
9165                        }
9166                        providerRunning = false;
9167                        conn = null;
9168                    }
9169                }
9170
9171                Binder.restoreCallingIdentity(origId);
9172            }
9173
9174            boolean singleton;
9175            if (!providerRunning) {
9176                try {
9177                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9178                    cpi = AppGlobals.getPackageManager().
9179                        resolveContentProvider(name,
9180                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9181                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9182                } catch (RemoteException ex) {
9183                }
9184                if (cpi == null) {
9185                    return null;
9186                }
9187                // If the provider is a singleton AND
9188                // (it's a call within the same user || the provider is a
9189                // privileged app)
9190                // Then allow connecting to the singleton provider
9191                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9192                        cpi.name, cpi.flags)
9193                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9194                if (singleton) {
9195                    userId = UserHandle.USER_OWNER;
9196                }
9197                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9198                checkTime(startTime, "getContentProviderImpl: got app info for user");
9199
9200                String msg;
9201                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9202                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9203                        != null) {
9204                    throw new SecurityException(msg);
9205                }
9206                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9207
9208                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9209                        && !cpi.processName.equals("system")) {
9210                    // If this content provider does not run in the system
9211                    // process, and the system is not yet ready to run other
9212                    // processes, then fail fast instead of hanging.
9213                    throw new IllegalArgumentException(
9214                            "Attempt to launch content provider before system ready");
9215                }
9216
9217                // Make sure that the user who owns this provider is started.  If not,
9218                // we don't want to allow it to run.
9219                if (mStartedUsers.get(userId) == null) {
9220                    Slog.w(TAG, "Unable to launch app "
9221                            + cpi.applicationInfo.packageName + "/"
9222                            + cpi.applicationInfo.uid + " for provider "
9223                            + name + ": user " + userId + " is stopped");
9224                    return null;
9225                }
9226
9227                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9228                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9229                cpr = mProviderMap.getProviderByClass(comp, userId);
9230                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9231                final boolean firstClass = cpr == null;
9232                if (firstClass) {
9233                    try {
9234                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9235                        ApplicationInfo ai =
9236                            AppGlobals.getPackageManager().
9237                                getApplicationInfo(
9238                                        cpi.applicationInfo.packageName,
9239                                        STOCK_PM_FLAGS, userId);
9240                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9241                        if (ai == null) {
9242                            Slog.w(TAG, "No package info for content provider "
9243                                    + cpi.name);
9244                            return null;
9245                        }
9246                        ai = getAppInfoForUser(ai, userId);
9247                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9248                    } catch (RemoteException ex) {
9249                        // pm is in same process, this will never happen.
9250                    }
9251                }
9252
9253                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9254
9255                if (r != null && cpr.canRunHere(r)) {
9256                    // If this is a multiprocess provider, then just return its
9257                    // info and allow the caller to instantiate it.  Only do
9258                    // this if the provider is the same user as the caller's
9259                    // process, or can run as root (so can be in any process).
9260                    return cpr.newHolder(null);
9261                }
9262
9263                if (DEBUG_PROVIDER) {
9264                    RuntimeException e = new RuntimeException("here");
9265                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9266                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9267                }
9268
9269                // This is single process, and our app is now connecting to it.
9270                // See if we are already in the process of launching this
9271                // provider.
9272                final int N = mLaunchingProviders.size();
9273                int i;
9274                for (i=0; i<N; i++) {
9275                    if (mLaunchingProviders.get(i) == cpr) {
9276                        break;
9277                    }
9278                }
9279
9280                // If the provider is not already being launched, then get it
9281                // started.
9282                if (i >= N) {
9283                    final long origId = Binder.clearCallingIdentity();
9284
9285                    try {
9286                        // Content provider is now in use, its package can't be stopped.
9287                        try {
9288                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9289                            AppGlobals.getPackageManager().setPackageStoppedState(
9290                                    cpr.appInfo.packageName, false, userId);
9291                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9292                        } catch (RemoteException e) {
9293                        } catch (IllegalArgumentException e) {
9294                            Slog.w(TAG, "Failed trying to unstop package "
9295                                    + cpr.appInfo.packageName + ": " + e);
9296                        }
9297
9298                        // Use existing process if already started
9299                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9300                        ProcessRecord proc = getProcessRecordLocked(
9301                                cpi.processName, cpr.appInfo.uid, false);
9302                        if (proc != null && proc.thread != null) {
9303                            if (DEBUG_PROVIDER) {
9304                                Slog.d(TAG, "Installing in existing process " + proc);
9305                            }
9306                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9307                            proc.pubProviders.put(cpi.name, cpr);
9308                            try {
9309                                proc.thread.scheduleInstallProvider(cpi);
9310                            } catch (RemoteException e) {
9311                            }
9312                        } else {
9313                            checkTime(startTime, "getContentProviderImpl: before start process");
9314                            proc = startProcessLocked(cpi.processName,
9315                                    cpr.appInfo, false, 0, "content provider",
9316                                    new ComponentName(cpi.applicationInfo.packageName,
9317                                            cpi.name), false, false, false);
9318                            checkTime(startTime, "getContentProviderImpl: after start process");
9319                            if (proc == null) {
9320                                Slog.w(TAG, "Unable to launch app "
9321                                        + cpi.applicationInfo.packageName + "/"
9322                                        + cpi.applicationInfo.uid + " for provider "
9323                                        + name + ": process is bad");
9324                                return null;
9325                            }
9326                        }
9327                        cpr.launchingApp = proc;
9328                        mLaunchingProviders.add(cpr);
9329                    } finally {
9330                        Binder.restoreCallingIdentity(origId);
9331                    }
9332                }
9333
9334                checkTime(startTime, "getContentProviderImpl: updating data structures");
9335
9336                // Make sure the provider is published (the same provider class
9337                // may be published under multiple names).
9338                if (firstClass) {
9339                    mProviderMap.putProviderByClass(comp, cpr);
9340                }
9341
9342                mProviderMap.putProviderByName(name, cpr);
9343                conn = incProviderCountLocked(r, cpr, token, stable);
9344                if (conn != null) {
9345                    conn.waiting = true;
9346                }
9347            }
9348            checkTime(startTime, "getContentProviderImpl: done!");
9349        }
9350
9351        // Wait for the provider to be published...
9352        synchronized (cpr) {
9353            while (cpr.provider == null) {
9354                if (cpr.launchingApp == null) {
9355                    Slog.w(TAG, "Unable to launch app "
9356                            + cpi.applicationInfo.packageName + "/"
9357                            + cpi.applicationInfo.uid + " for provider "
9358                            + name + ": launching app became null");
9359                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9360                            UserHandle.getUserId(cpi.applicationInfo.uid),
9361                            cpi.applicationInfo.packageName,
9362                            cpi.applicationInfo.uid, name);
9363                    return null;
9364                }
9365                try {
9366                    if (DEBUG_MU) {
9367                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9368                                + cpr.launchingApp);
9369                    }
9370                    if (conn != null) {
9371                        conn.waiting = true;
9372                    }
9373                    cpr.wait();
9374                } catch (InterruptedException ex) {
9375                } finally {
9376                    if (conn != null) {
9377                        conn.waiting = false;
9378                    }
9379                }
9380            }
9381        }
9382        return cpr != null ? cpr.newHolder(conn) : null;
9383    }
9384
9385    @Override
9386    public final ContentProviderHolder getContentProvider(
9387            IApplicationThread caller, String name, int userId, boolean stable) {
9388        enforceNotIsolatedCaller("getContentProvider");
9389        if (caller == null) {
9390            String msg = "null IApplicationThread when getting content provider "
9391                    + name;
9392            Slog.w(TAG, msg);
9393            throw new SecurityException(msg);
9394        }
9395        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9396        // with cross-user grant.
9397        return getContentProviderImpl(caller, name, null, stable, userId);
9398    }
9399
9400    public ContentProviderHolder getContentProviderExternal(
9401            String name, int userId, IBinder token) {
9402        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9403            "Do not have permission in call getContentProviderExternal()");
9404        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9405                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9406        return getContentProviderExternalUnchecked(name, token, userId);
9407    }
9408
9409    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9410            IBinder token, int userId) {
9411        return getContentProviderImpl(null, name, token, true, userId);
9412    }
9413
9414    /**
9415     * Drop a content provider from a ProcessRecord's bookkeeping
9416     */
9417    public void removeContentProvider(IBinder connection, boolean stable) {
9418        enforceNotIsolatedCaller("removeContentProvider");
9419        long ident = Binder.clearCallingIdentity();
9420        try {
9421            synchronized (this) {
9422                ContentProviderConnection conn;
9423                try {
9424                    conn = (ContentProviderConnection)connection;
9425                } catch (ClassCastException e) {
9426                    String msg ="removeContentProvider: " + connection
9427                            + " not a ContentProviderConnection";
9428                    Slog.w(TAG, msg);
9429                    throw new IllegalArgumentException(msg);
9430                }
9431                if (conn == null) {
9432                    throw new NullPointerException("connection is null");
9433                }
9434                if (decProviderCountLocked(conn, null, null, stable)) {
9435                    updateOomAdjLocked();
9436                }
9437            }
9438        } finally {
9439            Binder.restoreCallingIdentity(ident);
9440        }
9441    }
9442
9443    public void removeContentProviderExternal(String name, IBinder token) {
9444        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9445            "Do not have permission in call removeContentProviderExternal()");
9446        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9447    }
9448
9449    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9450        synchronized (this) {
9451            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9452            if(cpr == null) {
9453                //remove from mProvidersByClass
9454                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9455                return;
9456            }
9457
9458            //update content provider record entry info
9459            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9460            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9461            if (localCpr.hasExternalProcessHandles()) {
9462                if (localCpr.removeExternalProcessHandleLocked(token)) {
9463                    updateOomAdjLocked();
9464                } else {
9465                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9466                            + " with no external reference for token: "
9467                            + token + ".");
9468                }
9469            } else {
9470                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9471                        + " with no external references.");
9472            }
9473        }
9474    }
9475
9476    public final void publishContentProviders(IApplicationThread caller,
9477            List<ContentProviderHolder> providers) {
9478        if (providers == null) {
9479            return;
9480        }
9481
9482        enforceNotIsolatedCaller("publishContentProviders");
9483        synchronized (this) {
9484            final ProcessRecord r = getRecordForAppLocked(caller);
9485            if (DEBUG_MU)
9486                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9487            if (r == null) {
9488                throw new SecurityException(
9489                        "Unable to find app for caller " + caller
9490                      + " (pid=" + Binder.getCallingPid()
9491                      + ") when publishing content providers");
9492            }
9493
9494            final long origId = Binder.clearCallingIdentity();
9495
9496            final int N = providers.size();
9497            for (int i=0; i<N; i++) {
9498                ContentProviderHolder src = providers.get(i);
9499                if (src == null || src.info == null || src.provider == null) {
9500                    continue;
9501                }
9502                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9503                if (DEBUG_MU)
9504                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9505                if (dst != null) {
9506                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9507                    mProviderMap.putProviderByClass(comp, dst);
9508                    String names[] = dst.info.authority.split(";");
9509                    for (int j = 0; j < names.length; j++) {
9510                        mProviderMap.putProviderByName(names[j], dst);
9511                    }
9512
9513                    int NL = mLaunchingProviders.size();
9514                    int j;
9515                    for (j=0; j<NL; j++) {
9516                        if (mLaunchingProviders.get(j) == dst) {
9517                            mLaunchingProviders.remove(j);
9518                            j--;
9519                            NL--;
9520                        }
9521                    }
9522                    synchronized (dst) {
9523                        dst.provider = src.provider;
9524                        dst.proc = r;
9525                        dst.notifyAll();
9526                    }
9527                    updateOomAdjLocked(r);
9528                }
9529            }
9530
9531            Binder.restoreCallingIdentity(origId);
9532        }
9533    }
9534
9535    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9536        ContentProviderConnection conn;
9537        try {
9538            conn = (ContentProviderConnection)connection;
9539        } catch (ClassCastException e) {
9540            String msg ="refContentProvider: " + connection
9541                    + " not a ContentProviderConnection";
9542            Slog.w(TAG, msg);
9543            throw new IllegalArgumentException(msg);
9544        }
9545        if (conn == null) {
9546            throw new NullPointerException("connection is null");
9547        }
9548
9549        synchronized (this) {
9550            if (stable > 0) {
9551                conn.numStableIncs += stable;
9552            }
9553            stable = conn.stableCount + stable;
9554            if (stable < 0) {
9555                throw new IllegalStateException("stableCount < 0: " + stable);
9556            }
9557
9558            if (unstable > 0) {
9559                conn.numUnstableIncs += unstable;
9560            }
9561            unstable = conn.unstableCount + unstable;
9562            if (unstable < 0) {
9563                throw new IllegalStateException("unstableCount < 0: " + unstable);
9564            }
9565
9566            if ((stable+unstable) <= 0) {
9567                throw new IllegalStateException("ref counts can't go to zero here: stable="
9568                        + stable + " unstable=" + unstable);
9569            }
9570            conn.stableCount = stable;
9571            conn.unstableCount = unstable;
9572            return !conn.dead;
9573        }
9574    }
9575
9576    public void unstableProviderDied(IBinder connection) {
9577        ContentProviderConnection conn;
9578        try {
9579            conn = (ContentProviderConnection)connection;
9580        } catch (ClassCastException e) {
9581            String msg ="refContentProvider: " + connection
9582                    + " not a ContentProviderConnection";
9583            Slog.w(TAG, msg);
9584            throw new IllegalArgumentException(msg);
9585        }
9586        if (conn == null) {
9587            throw new NullPointerException("connection is null");
9588        }
9589
9590        // Safely retrieve the content provider associated with the connection.
9591        IContentProvider provider;
9592        synchronized (this) {
9593            provider = conn.provider.provider;
9594        }
9595
9596        if (provider == null) {
9597            // Um, yeah, we're way ahead of you.
9598            return;
9599        }
9600
9601        // Make sure the caller is being honest with us.
9602        if (provider.asBinder().pingBinder()) {
9603            // Er, no, still looks good to us.
9604            synchronized (this) {
9605                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9606                        + " says " + conn + " died, but we don't agree");
9607                return;
9608            }
9609        }
9610
9611        // Well look at that!  It's dead!
9612        synchronized (this) {
9613            if (conn.provider.provider != provider) {
9614                // But something changed...  good enough.
9615                return;
9616            }
9617
9618            ProcessRecord proc = conn.provider.proc;
9619            if (proc == null || proc.thread == null) {
9620                // Seems like the process is already cleaned up.
9621                return;
9622            }
9623
9624            // As far as we're concerned, this is just like receiving a
9625            // death notification...  just a bit prematurely.
9626            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9627                    + ") early provider death");
9628            final long ident = Binder.clearCallingIdentity();
9629            try {
9630                appDiedLocked(proc);
9631            } finally {
9632                Binder.restoreCallingIdentity(ident);
9633            }
9634        }
9635    }
9636
9637    @Override
9638    public void appNotRespondingViaProvider(IBinder connection) {
9639        enforceCallingPermission(
9640                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9641
9642        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9643        if (conn == null) {
9644            Slog.w(TAG, "ContentProviderConnection is null");
9645            return;
9646        }
9647
9648        final ProcessRecord host = conn.provider.proc;
9649        if (host == null) {
9650            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9651            return;
9652        }
9653
9654        final long token = Binder.clearCallingIdentity();
9655        try {
9656            appNotResponding(host, null, null, false, "ContentProvider not responding");
9657        } finally {
9658            Binder.restoreCallingIdentity(token);
9659        }
9660    }
9661
9662    public final void installSystemProviders() {
9663        List<ProviderInfo> providers;
9664        synchronized (this) {
9665            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9666            providers = generateApplicationProvidersLocked(app);
9667            if (providers != null) {
9668                for (int i=providers.size()-1; i>=0; i--) {
9669                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9670                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9671                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9672                                + ": not system .apk");
9673                        providers.remove(i);
9674                    }
9675                }
9676            }
9677        }
9678        if (providers != null) {
9679            mSystemThread.installSystemProviders(providers);
9680        }
9681
9682        mCoreSettingsObserver = new CoreSettingsObserver(this);
9683
9684        //mUsageStatsService.monitorPackages();
9685    }
9686
9687    /**
9688     * Allows apps to retrieve the MIME type of a URI.
9689     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9690     * users, then it does not need permission to access the ContentProvider.
9691     * Either, it needs cross-user uri grants.
9692     *
9693     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9694     *
9695     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9696     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9697     */
9698    public String getProviderMimeType(Uri uri, int userId) {
9699        enforceNotIsolatedCaller("getProviderMimeType");
9700        final String name = uri.getAuthority();
9701        int callingUid = Binder.getCallingUid();
9702        int callingPid = Binder.getCallingPid();
9703        long ident = 0;
9704        boolean clearedIdentity = false;
9705        userId = unsafeConvertIncomingUser(userId);
9706        if (UserHandle.getUserId(callingUid) != userId) {
9707            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9708                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9709                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9710                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9711                clearedIdentity = true;
9712                ident = Binder.clearCallingIdentity();
9713            }
9714        }
9715        ContentProviderHolder holder = null;
9716        try {
9717            holder = getContentProviderExternalUnchecked(name, null, userId);
9718            if (holder != null) {
9719                return holder.provider.getType(uri);
9720            }
9721        } catch (RemoteException e) {
9722            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9723            return null;
9724        } finally {
9725            // We need to clear the identity to call removeContentProviderExternalUnchecked
9726            if (!clearedIdentity) {
9727                ident = Binder.clearCallingIdentity();
9728            }
9729            try {
9730                if (holder != null) {
9731                    removeContentProviderExternalUnchecked(name, null, userId);
9732                }
9733            } finally {
9734                Binder.restoreCallingIdentity(ident);
9735            }
9736        }
9737
9738        return null;
9739    }
9740
9741    // =========================================================
9742    // GLOBAL MANAGEMENT
9743    // =========================================================
9744
9745    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9746            boolean isolated, int isolatedUid) {
9747        String proc = customProcess != null ? customProcess : info.processName;
9748        BatteryStatsImpl.Uid.Proc ps = null;
9749        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9750        int uid = info.uid;
9751        if (isolated) {
9752            if (isolatedUid == 0) {
9753                int userId = UserHandle.getUserId(uid);
9754                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9755                while (true) {
9756                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9757                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9758                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9759                    }
9760                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9761                    mNextIsolatedProcessUid++;
9762                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9763                        // No process for this uid, use it.
9764                        break;
9765                    }
9766                    stepsLeft--;
9767                    if (stepsLeft <= 0) {
9768                        return null;
9769                    }
9770                }
9771            } else {
9772                // Special case for startIsolatedProcess (internal only), where
9773                // the uid of the isolated process is specified by the caller.
9774                uid = isolatedUid;
9775            }
9776        }
9777        return new ProcessRecord(stats, info, proc, uid);
9778    }
9779
9780    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9781            String abiOverride) {
9782        ProcessRecord app;
9783        if (!isolated) {
9784            app = getProcessRecordLocked(info.processName, info.uid, true);
9785        } else {
9786            app = null;
9787        }
9788
9789        if (app == null) {
9790            app = newProcessRecordLocked(info, null, isolated, 0);
9791            mProcessNames.put(info.processName, app.uid, app);
9792            if (isolated) {
9793                mIsolatedProcesses.put(app.uid, app);
9794            }
9795            updateLruProcessLocked(app, false, null);
9796            updateOomAdjLocked();
9797        }
9798
9799        // This package really, really can not be stopped.
9800        try {
9801            AppGlobals.getPackageManager().setPackageStoppedState(
9802                    info.packageName, false, UserHandle.getUserId(app.uid));
9803        } catch (RemoteException e) {
9804        } catch (IllegalArgumentException e) {
9805            Slog.w(TAG, "Failed trying to unstop package "
9806                    + info.packageName + ": " + e);
9807        }
9808
9809        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9810                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9811            app.persistent = true;
9812            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9813        }
9814        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9815            mPersistentStartingProcesses.add(app);
9816            startProcessLocked(app, "added application", app.processName, abiOverride,
9817                    null /* entryPoint */, null /* entryPointArgs */);
9818        }
9819
9820        return app;
9821    }
9822
9823    public void unhandledBack() {
9824        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9825                "unhandledBack()");
9826
9827        synchronized(this) {
9828            final long origId = Binder.clearCallingIdentity();
9829            try {
9830                getFocusedStack().unhandledBackLocked();
9831            } finally {
9832                Binder.restoreCallingIdentity(origId);
9833            }
9834        }
9835    }
9836
9837    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9838        enforceNotIsolatedCaller("openContentUri");
9839        final int userId = UserHandle.getCallingUserId();
9840        String name = uri.getAuthority();
9841        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9842        ParcelFileDescriptor pfd = null;
9843        if (cph != null) {
9844            // We record the binder invoker's uid in thread-local storage before
9845            // going to the content provider to open the file.  Later, in the code
9846            // that handles all permissions checks, we look for this uid and use
9847            // that rather than the Activity Manager's own uid.  The effect is that
9848            // we do the check against the caller's permissions even though it looks
9849            // to the content provider like the Activity Manager itself is making
9850            // the request.
9851            sCallerIdentity.set(new Identity(
9852                    Binder.getCallingPid(), Binder.getCallingUid()));
9853            try {
9854                pfd = cph.provider.openFile(null, uri, "r", null);
9855            } catch (FileNotFoundException e) {
9856                // do nothing; pfd will be returned null
9857            } finally {
9858                // Ensure that whatever happens, we clean up the identity state
9859                sCallerIdentity.remove();
9860            }
9861
9862            // We've got the fd now, so we're done with the provider.
9863            removeContentProviderExternalUnchecked(name, null, userId);
9864        } else {
9865            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9866        }
9867        return pfd;
9868    }
9869
9870    // Actually is sleeping or shutting down or whatever else in the future
9871    // is an inactive state.
9872    public boolean isSleepingOrShuttingDown() {
9873        return mSleeping || mShuttingDown;
9874    }
9875
9876    public boolean isSleeping() {
9877        return mSleeping;
9878    }
9879
9880    void goingToSleep() {
9881        synchronized(this) {
9882            mWentToSleep = true;
9883            updateEventDispatchingLocked();
9884            goToSleepIfNeededLocked();
9885        }
9886    }
9887
9888    void finishRunningVoiceLocked() {
9889        if (mRunningVoice) {
9890            mRunningVoice = false;
9891            goToSleepIfNeededLocked();
9892        }
9893    }
9894
9895    void goToSleepIfNeededLocked() {
9896        if (mWentToSleep && !mRunningVoice) {
9897            if (!mSleeping) {
9898                mSleeping = true;
9899                mStackSupervisor.goingToSleepLocked();
9900
9901                // Initialize the wake times of all processes.
9902                checkExcessivePowerUsageLocked(false);
9903                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9904                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9905                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9906            }
9907        }
9908    }
9909
9910    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9911        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9912            // Never persist the home stack.
9913            return;
9914        }
9915        mTaskPersister.wakeup(task, flush);
9916    }
9917
9918    @Override
9919    public boolean shutdown(int timeout) {
9920        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9921                != PackageManager.PERMISSION_GRANTED) {
9922            throw new SecurityException("Requires permission "
9923                    + android.Manifest.permission.SHUTDOWN);
9924        }
9925
9926        boolean timedout = false;
9927
9928        synchronized(this) {
9929            mShuttingDown = true;
9930            updateEventDispatchingLocked();
9931            timedout = mStackSupervisor.shutdownLocked(timeout);
9932        }
9933
9934        mAppOpsService.shutdown();
9935        if (mUsageStatsService != null) {
9936            mUsageStatsService.prepareShutdown();
9937        }
9938        mBatteryStatsService.shutdown();
9939        synchronized (this) {
9940            mProcessStats.shutdownLocked();
9941        }
9942        notifyTaskPersisterLocked(null, true);
9943
9944        return timedout;
9945    }
9946
9947    public final void activitySlept(IBinder token) {
9948        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9949
9950        final long origId = Binder.clearCallingIdentity();
9951
9952        synchronized (this) {
9953            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9954            if (r != null) {
9955                mStackSupervisor.activitySleptLocked(r);
9956            }
9957        }
9958
9959        Binder.restoreCallingIdentity(origId);
9960    }
9961
9962    void logLockScreen(String msg) {
9963        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9964                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9965                mWentToSleep + " mSleeping=" + mSleeping);
9966    }
9967
9968    private void comeOutOfSleepIfNeededLocked() {
9969        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9970            if (mSleeping) {
9971                mSleeping = false;
9972                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9973            }
9974        }
9975    }
9976
9977    void wakingUp() {
9978        synchronized(this) {
9979            mWentToSleep = false;
9980            updateEventDispatchingLocked();
9981            comeOutOfSleepIfNeededLocked();
9982        }
9983    }
9984
9985    void startRunningVoiceLocked() {
9986        if (!mRunningVoice) {
9987            mRunningVoice = true;
9988            comeOutOfSleepIfNeededLocked();
9989        }
9990    }
9991
9992    private void updateEventDispatchingLocked() {
9993        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9994    }
9995
9996    public void setLockScreenShown(boolean shown) {
9997        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9998                != PackageManager.PERMISSION_GRANTED) {
9999            throw new SecurityException("Requires permission "
10000                    + android.Manifest.permission.DEVICE_POWER);
10001        }
10002
10003        synchronized(this) {
10004            long ident = Binder.clearCallingIdentity();
10005            try {
10006                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10007                mLockScreenShown = shown;
10008                comeOutOfSleepIfNeededLocked();
10009            } finally {
10010                Binder.restoreCallingIdentity(ident);
10011            }
10012        }
10013    }
10014
10015    @Override
10016    public void stopAppSwitches() {
10017        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10018                != PackageManager.PERMISSION_GRANTED) {
10019            throw new SecurityException("Requires permission "
10020                    + android.Manifest.permission.STOP_APP_SWITCHES);
10021        }
10022
10023        synchronized(this) {
10024            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10025                    + APP_SWITCH_DELAY_TIME;
10026            mDidAppSwitch = false;
10027            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10028            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10029            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10030        }
10031    }
10032
10033    public void resumeAppSwitches() {
10034        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10035                != PackageManager.PERMISSION_GRANTED) {
10036            throw new SecurityException("Requires permission "
10037                    + android.Manifest.permission.STOP_APP_SWITCHES);
10038        }
10039
10040        synchronized(this) {
10041            // Note that we don't execute any pending app switches... we will
10042            // let those wait until either the timeout, or the next start
10043            // activity request.
10044            mAppSwitchesAllowedTime = 0;
10045        }
10046    }
10047
10048    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10049            String name) {
10050        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10051            return true;
10052        }
10053
10054        final int perm = checkComponentPermission(
10055                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10056                callingUid, -1, true);
10057        if (perm == PackageManager.PERMISSION_GRANTED) {
10058            return true;
10059        }
10060
10061        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10062        return false;
10063    }
10064
10065    public void setDebugApp(String packageName, boolean waitForDebugger,
10066            boolean persistent) {
10067        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10068                "setDebugApp()");
10069
10070        long ident = Binder.clearCallingIdentity();
10071        try {
10072            // Note that this is not really thread safe if there are multiple
10073            // callers into it at the same time, but that's not a situation we
10074            // care about.
10075            if (persistent) {
10076                final ContentResolver resolver = mContext.getContentResolver();
10077                Settings.Global.putString(
10078                    resolver, Settings.Global.DEBUG_APP,
10079                    packageName);
10080                Settings.Global.putInt(
10081                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10082                    waitForDebugger ? 1 : 0);
10083            }
10084
10085            synchronized (this) {
10086                if (!persistent) {
10087                    mOrigDebugApp = mDebugApp;
10088                    mOrigWaitForDebugger = mWaitForDebugger;
10089                }
10090                mDebugApp = packageName;
10091                mWaitForDebugger = waitForDebugger;
10092                mDebugTransient = !persistent;
10093                if (packageName != null) {
10094                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10095                            false, UserHandle.USER_ALL, "set debug app");
10096                }
10097            }
10098        } finally {
10099            Binder.restoreCallingIdentity(ident);
10100        }
10101    }
10102
10103    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10104        synchronized (this) {
10105            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10106            if (!isDebuggable) {
10107                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10108                    throw new SecurityException("Process not debuggable: " + app.packageName);
10109                }
10110            }
10111
10112            mOpenGlTraceApp = processName;
10113        }
10114    }
10115
10116    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10117        synchronized (this) {
10118            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10119            if (!isDebuggable) {
10120                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10121                    throw new SecurityException("Process not debuggable: " + app.packageName);
10122                }
10123            }
10124            mProfileApp = processName;
10125            mProfileFile = profilerInfo.profileFile;
10126            if (mProfileFd != null) {
10127                try {
10128                    mProfileFd.close();
10129                } catch (IOException e) {
10130                }
10131                mProfileFd = null;
10132            }
10133            mProfileFd = profilerInfo.profileFd;
10134            mSamplingInterval = profilerInfo.samplingInterval;
10135            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10136            mProfileType = 0;
10137        }
10138    }
10139
10140    @Override
10141    public void setAlwaysFinish(boolean enabled) {
10142        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10143                "setAlwaysFinish()");
10144
10145        Settings.Global.putInt(
10146                mContext.getContentResolver(),
10147                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10148
10149        synchronized (this) {
10150            mAlwaysFinishActivities = enabled;
10151        }
10152    }
10153
10154    @Override
10155    public void setActivityController(IActivityController controller) {
10156        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10157                "setActivityController()");
10158        synchronized (this) {
10159            mController = controller;
10160            Watchdog.getInstance().setActivityController(controller);
10161        }
10162    }
10163
10164    @Override
10165    public void setUserIsMonkey(boolean userIsMonkey) {
10166        synchronized (this) {
10167            synchronized (mPidsSelfLocked) {
10168                final int callingPid = Binder.getCallingPid();
10169                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10170                if (precessRecord == null) {
10171                    throw new SecurityException("Unknown process: " + callingPid);
10172                }
10173                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10174                    throw new SecurityException("Only an instrumentation process "
10175                            + "with a UiAutomation can call setUserIsMonkey");
10176                }
10177            }
10178            mUserIsMonkey = userIsMonkey;
10179        }
10180    }
10181
10182    @Override
10183    public boolean isUserAMonkey() {
10184        synchronized (this) {
10185            // If there is a controller also implies the user is a monkey.
10186            return (mUserIsMonkey || mController != null);
10187        }
10188    }
10189
10190    public void requestBugReport() {
10191        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10192        SystemProperties.set("ctl.start", "bugreport");
10193    }
10194
10195    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10196        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10197    }
10198
10199    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10200        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10201            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10202        }
10203        return KEY_DISPATCHING_TIMEOUT;
10204    }
10205
10206    @Override
10207    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10208        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10209                != PackageManager.PERMISSION_GRANTED) {
10210            throw new SecurityException("Requires permission "
10211                    + android.Manifest.permission.FILTER_EVENTS);
10212        }
10213        ProcessRecord proc;
10214        long timeout;
10215        synchronized (this) {
10216            synchronized (mPidsSelfLocked) {
10217                proc = mPidsSelfLocked.get(pid);
10218            }
10219            timeout = getInputDispatchingTimeoutLocked(proc);
10220        }
10221
10222        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10223            return -1;
10224        }
10225
10226        return timeout;
10227    }
10228
10229    /**
10230     * Handle input dispatching timeouts.
10231     * Returns whether input dispatching should be aborted or not.
10232     */
10233    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10234            final ActivityRecord activity, final ActivityRecord parent,
10235            final boolean aboveSystem, String reason) {
10236        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10237                != PackageManager.PERMISSION_GRANTED) {
10238            throw new SecurityException("Requires permission "
10239                    + android.Manifest.permission.FILTER_EVENTS);
10240        }
10241
10242        final String annotation;
10243        if (reason == null) {
10244            annotation = "Input dispatching timed out";
10245        } else {
10246            annotation = "Input dispatching timed out (" + reason + ")";
10247        }
10248
10249        if (proc != null) {
10250            synchronized (this) {
10251                if (proc.debugging) {
10252                    return false;
10253                }
10254
10255                if (mDidDexOpt) {
10256                    // Give more time since we were dexopting.
10257                    mDidDexOpt = false;
10258                    return false;
10259                }
10260
10261                if (proc.instrumentationClass != null) {
10262                    Bundle info = new Bundle();
10263                    info.putString("shortMsg", "keyDispatchingTimedOut");
10264                    info.putString("longMsg", annotation);
10265                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10266                    return true;
10267                }
10268            }
10269            mHandler.post(new Runnable() {
10270                @Override
10271                public void run() {
10272                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10273                }
10274            });
10275        }
10276
10277        return true;
10278    }
10279
10280    public Bundle getAssistContextExtras(int requestType) {
10281        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10282                "getAssistContextExtras()");
10283        PendingAssistExtras pae;
10284        Bundle extras = new Bundle();
10285        synchronized (this) {
10286            ActivityRecord activity = getFocusedStack().mResumedActivity;
10287            if (activity == null) {
10288                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10289                return null;
10290            }
10291            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10292            if (activity.app == null || activity.app.thread == null) {
10293                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10294                return extras;
10295            }
10296            if (activity.app.pid == Binder.getCallingPid()) {
10297                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10298                return extras;
10299            }
10300            pae = new PendingAssistExtras(activity);
10301            try {
10302                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10303                        requestType);
10304                mPendingAssistExtras.add(pae);
10305                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10306            } catch (RemoteException e) {
10307                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10308                return extras;
10309            }
10310        }
10311        synchronized (pae) {
10312            while (!pae.haveResult) {
10313                try {
10314                    pae.wait();
10315                } catch (InterruptedException e) {
10316                }
10317            }
10318            if (pae.result != null) {
10319                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10320            }
10321        }
10322        synchronized (this) {
10323            mPendingAssistExtras.remove(pae);
10324            mHandler.removeCallbacks(pae);
10325        }
10326        return extras;
10327    }
10328
10329    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10330        PendingAssistExtras pae = (PendingAssistExtras)token;
10331        synchronized (pae) {
10332            pae.result = extras;
10333            pae.haveResult = true;
10334            pae.notifyAll();
10335        }
10336    }
10337
10338    public void registerProcessObserver(IProcessObserver observer) {
10339        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10340                "registerProcessObserver()");
10341        synchronized (this) {
10342            mProcessObservers.register(observer);
10343        }
10344    }
10345
10346    @Override
10347    public void unregisterProcessObserver(IProcessObserver observer) {
10348        synchronized (this) {
10349            mProcessObservers.unregister(observer);
10350        }
10351    }
10352
10353    @Override
10354    public boolean convertFromTranslucent(IBinder token) {
10355        final long origId = Binder.clearCallingIdentity();
10356        try {
10357            synchronized (this) {
10358                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10359                if (r == null) {
10360                    return false;
10361                }
10362                final boolean translucentChanged = r.changeWindowTranslucency(true);
10363                if (translucentChanged) {
10364                    r.task.stack.releaseBackgroundResources();
10365                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10366                }
10367                mWindowManager.setAppFullscreen(token, true);
10368                return translucentChanged;
10369            }
10370        } finally {
10371            Binder.restoreCallingIdentity(origId);
10372        }
10373    }
10374
10375    @Override
10376    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10377        final long origId = Binder.clearCallingIdentity();
10378        try {
10379            synchronized (this) {
10380                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10381                if (r == null) {
10382                    return false;
10383                }
10384                int index = r.task.mActivities.lastIndexOf(r);
10385                if (index > 0) {
10386                    ActivityRecord under = r.task.mActivities.get(index - 1);
10387                    under.returningOptions = options;
10388                }
10389                final boolean translucentChanged = r.changeWindowTranslucency(false);
10390                if (translucentChanged) {
10391                    r.task.stack.convertToTranslucent(r);
10392                }
10393                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10394                mWindowManager.setAppFullscreen(token, false);
10395                return translucentChanged;
10396            }
10397        } finally {
10398            Binder.restoreCallingIdentity(origId);
10399        }
10400    }
10401
10402    @Override
10403    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10404        final long origId = Binder.clearCallingIdentity();
10405        try {
10406            synchronized (this) {
10407                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10408                if (r != null) {
10409                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10410                }
10411            }
10412            return false;
10413        } finally {
10414            Binder.restoreCallingIdentity(origId);
10415        }
10416    }
10417
10418    @Override
10419    public boolean isBackgroundVisibleBehind(IBinder token) {
10420        final long origId = Binder.clearCallingIdentity();
10421        try {
10422            synchronized (this) {
10423                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10424                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10425                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10426                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10427                return visible;
10428            }
10429        } finally {
10430            Binder.restoreCallingIdentity(origId);
10431        }
10432    }
10433
10434    @Override
10435    public ActivityOptions getActivityOptions(IBinder token) {
10436        final long origId = Binder.clearCallingIdentity();
10437        try {
10438            synchronized (this) {
10439                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10440                if (r != null) {
10441                    final ActivityOptions activityOptions = r.pendingOptions;
10442                    r.pendingOptions = null;
10443                    return activityOptions;
10444                }
10445                return null;
10446            }
10447        } finally {
10448            Binder.restoreCallingIdentity(origId);
10449        }
10450    }
10451
10452    @Override
10453    public void setImmersive(IBinder token, boolean immersive) {
10454        synchronized(this) {
10455            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10456            if (r == null) {
10457                throw new IllegalArgumentException();
10458            }
10459            r.immersive = immersive;
10460
10461            // update associated state if we're frontmost
10462            if (r == mFocusedActivity) {
10463                if (DEBUG_IMMERSIVE) {
10464                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10465                }
10466                applyUpdateLockStateLocked(r);
10467            }
10468        }
10469    }
10470
10471    @Override
10472    public boolean isImmersive(IBinder token) {
10473        synchronized (this) {
10474            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10475            if (r == null) {
10476                throw new IllegalArgumentException();
10477            }
10478            return r.immersive;
10479        }
10480    }
10481
10482    public boolean isTopActivityImmersive() {
10483        enforceNotIsolatedCaller("startActivity");
10484        synchronized (this) {
10485            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10486            return (r != null) ? r.immersive : false;
10487        }
10488    }
10489
10490    @Override
10491    public boolean isTopOfTask(IBinder token) {
10492        synchronized (this) {
10493            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10494            if (r == null) {
10495                throw new IllegalArgumentException();
10496            }
10497            return r.task.getTopActivity() == r;
10498        }
10499    }
10500
10501    public final void enterSafeMode() {
10502        synchronized(this) {
10503            // It only makes sense to do this before the system is ready
10504            // and started launching other packages.
10505            if (!mSystemReady) {
10506                try {
10507                    AppGlobals.getPackageManager().enterSafeMode();
10508                } catch (RemoteException e) {
10509                }
10510            }
10511
10512            mSafeMode = true;
10513        }
10514    }
10515
10516    public final void showSafeModeOverlay() {
10517        View v = LayoutInflater.from(mContext).inflate(
10518                com.android.internal.R.layout.safe_mode, null);
10519        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10520        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10521        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10522        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10523        lp.gravity = Gravity.BOTTOM | Gravity.START;
10524        lp.format = v.getBackground().getOpacity();
10525        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10526                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10527        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10528        ((WindowManager)mContext.getSystemService(
10529                Context.WINDOW_SERVICE)).addView(v, lp);
10530    }
10531
10532    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10533        if (!(sender instanceof PendingIntentRecord)) {
10534            return;
10535        }
10536        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10537        synchronized (stats) {
10538            if (mBatteryStatsService.isOnBattery()) {
10539                mBatteryStatsService.enforceCallingPermission();
10540                PendingIntentRecord rec = (PendingIntentRecord)sender;
10541                int MY_UID = Binder.getCallingUid();
10542                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10543                BatteryStatsImpl.Uid.Pkg pkg =
10544                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10545                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10546                pkg.incWakeupsLocked();
10547            }
10548        }
10549    }
10550
10551    public boolean killPids(int[] pids, String pReason, boolean secure) {
10552        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10553            throw new SecurityException("killPids only available to the system");
10554        }
10555        String reason = (pReason == null) ? "Unknown" : pReason;
10556        // XXX Note: don't acquire main activity lock here, because the window
10557        // manager calls in with its locks held.
10558
10559        boolean killed = false;
10560        synchronized (mPidsSelfLocked) {
10561            int[] types = new int[pids.length];
10562            int worstType = 0;
10563            for (int i=0; i<pids.length; i++) {
10564                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10565                if (proc != null) {
10566                    int type = proc.setAdj;
10567                    types[i] = type;
10568                    if (type > worstType) {
10569                        worstType = type;
10570                    }
10571                }
10572            }
10573
10574            // If the worst oom_adj is somewhere in the cached proc LRU range,
10575            // then constrain it so we will kill all cached procs.
10576            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10577                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10578                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10579            }
10580
10581            // If this is not a secure call, don't let it kill processes that
10582            // are important.
10583            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10584                worstType = ProcessList.SERVICE_ADJ;
10585            }
10586
10587            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10588            for (int i=0; i<pids.length; i++) {
10589                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10590                if (proc == null) {
10591                    continue;
10592                }
10593                int adj = proc.setAdj;
10594                if (adj >= worstType && !proc.killedByAm) {
10595                    proc.kill(reason, true);
10596                    killed = true;
10597                }
10598            }
10599        }
10600        return killed;
10601    }
10602
10603    @Override
10604    public void killUid(int uid, String reason) {
10605        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10606            throw new SecurityException("killUid only available to the system");
10607        }
10608        synchronized (this) {
10609            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10610                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10611                    reason != null ? reason : "kill uid");
10612        }
10613    }
10614
10615    @Override
10616    public boolean killProcessesBelowForeground(String reason) {
10617        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10618            throw new SecurityException("killProcessesBelowForeground() only available to system");
10619        }
10620
10621        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10622    }
10623
10624    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10625        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10626            throw new SecurityException("killProcessesBelowAdj() only available to system");
10627        }
10628
10629        boolean killed = false;
10630        synchronized (mPidsSelfLocked) {
10631            final int size = mPidsSelfLocked.size();
10632            for (int i = 0; i < size; i++) {
10633                final int pid = mPidsSelfLocked.keyAt(i);
10634                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10635                if (proc == null) continue;
10636
10637                final int adj = proc.setAdj;
10638                if (adj > belowAdj && !proc.killedByAm) {
10639                    proc.kill(reason, true);
10640                    killed = true;
10641                }
10642            }
10643        }
10644        return killed;
10645    }
10646
10647    @Override
10648    public void hang(final IBinder who, boolean allowRestart) {
10649        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10650                != PackageManager.PERMISSION_GRANTED) {
10651            throw new SecurityException("Requires permission "
10652                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10653        }
10654
10655        final IBinder.DeathRecipient death = new DeathRecipient() {
10656            @Override
10657            public void binderDied() {
10658                synchronized (this) {
10659                    notifyAll();
10660                }
10661            }
10662        };
10663
10664        try {
10665            who.linkToDeath(death, 0);
10666        } catch (RemoteException e) {
10667            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10668            return;
10669        }
10670
10671        synchronized (this) {
10672            Watchdog.getInstance().setAllowRestart(allowRestart);
10673            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10674            synchronized (death) {
10675                while (who.isBinderAlive()) {
10676                    try {
10677                        death.wait();
10678                    } catch (InterruptedException e) {
10679                    }
10680                }
10681            }
10682            Watchdog.getInstance().setAllowRestart(true);
10683        }
10684    }
10685
10686    @Override
10687    public void restart() {
10688        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10689                != PackageManager.PERMISSION_GRANTED) {
10690            throw new SecurityException("Requires permission "
10691                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10692        }
10693
10694        Log.i(TAG, "Sending shutdown broadcast...");
10695
10696        BroadcastReceiver br = new BroadcastReceiver() {
10697            @Override public void onReceive(Context context, Intent intent) {
10698                // Now the broadcast is done, finish up the low-level shutdown.
10699                Log.i(TAG, "Shutting down activity manager...");
10700                shutdown(10000);
10701                Log.i(TAG, "Shutdown complete, restarting!");
10702                Process.killProcess(Process.myPid());
10703                System.exit(10);
10704            }
10705        };
10706
10707        // First send the high-level shut down broadcast.
10708        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10709        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10710        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10711        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10712        mContext.sendOrderedBroadcastAsUser(intent,
10713                UserHandle.ALL, null, br, mHandler, 0, null, null);
10714        */
10715        br.onReceive(mContext, intent);
10716    }
10717
10718    private long getLowRamTimeSinceIdle(long now) {
10719        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10720    }
10721
10722    @Override
10723    public void performIdleMaintenance() {
10724        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10725                != PackageManager.PERMISSION_GRANTED) {
10726            throw new SecurityException("Requires permission "
10727                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10728        }
10729
10730        synchronized (this) {
10731            final long now = SystemClock.uptimeMillis();
10732            final long timeSinceLastIdle = now - mLastIdleTime;
10733            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10734            mLastIdleTime = now;
10735            mLowRamTimeSinceLastIdle = 0;
10736            if (mLowRamStartTime != 0) {
10737                mLowRamStartTime = now;
10738            }
10739
10740            StringBuilder sb = new StringBuilder(128);
10741            sb.append("Idle maintenance over ");
10742            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10743            sb.append(" low RAM for ");
10744            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10745            Slog.i(TAG, sb.toString());
10746
10747            // If at least 1/3 of our time since the last idle period has been spent
10748            // with RAM low, then we want to kill processes.
10749            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10750
10751            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10752                ProcessRecord proc = mLruProcesses.get(i);
10753                if (proc.notCachedSinceIdle) {
10754                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10755                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10756                        if (doKilling && proc.initialIdlePss != 0
10757                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10758                            proc.kill("idle maint (pss " + proc.lastPss
10759                                    + " from " + proc.initialIdlePss + ")", true);
10760                        }
10761                    }
10762                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10763                    proc.notCachedSinceIdle = true;
10764                    proc.initialIdlePss = 0;
10765                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10766                            isSleeping(), now);
10767                }
10768            }
10769
10770            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10771            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10772        }
10773    }
10774
10775    private void retrieveSettings() {
10776        final ContentResolver resolver = mContext.getContentResolver();
10777        String debugApp = Settings.Global.getString(
10778            resolver, Settings.Global.DEBUG_APP);
10779        boolean waitForDebugger = Settings.Global.getInt(
10780            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10781        boolean alwaysFinishActivities = Settings.Global.getInt(
10782            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10783        boolean forceRtl = Settings.Global.getInt(
10784                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10785        // Transfer any global setting for forcing RTL layout, into a System Property
10786        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10787
10788        Configuration configuration = new Configuration();
10789        Settings.System.getConfiguration(resolver, configuration);
10790        if (forceRtl) {
10791            // This will take care of setting the correct layout direction flags
10792            configuration.setLayoutDirection(configuration.locale);
10793        }
10794
10795        synchronized (this) {
10796            mDebugApp = mOrigDebugApp = debugApp;
10797            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10798            mAlwaysFinishActivities = alwaysFinishActivities;
10799            // This happens before any activities are started, so we can
10800            // change mConfiguration in-place.
10801            updateConfigurationLocked(configuration, null, false, true);
10802            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10803        }
10804    }
10805
10806    /** Loads resources after the current configuration has been set. */
10807    private void loadResourcesOnSystemReady() {
10808        final Resources res = mContext.getResources();
10809        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10810        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10811        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10812    }
10813
10814    public boolean testIsSystemReady() {
10815        // no need to synchronize(this) just to read & return the value
10816        return mSystemReady;
10817    }
10818
10819    private static File getCalledPreBootReceiversFile() {
10820        File dataDir = Environment.getDataDirectory();
10821        File systemDir = new File(dataDir, "system");
10822        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10823        return fname;
10824    }
10825
10826    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10827        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10828        File file = getCalledPreBootReceiversFile();
10829        FileInputStream fis = null;
10830        try {
10831            fis = new FileInputStream(file);
10832            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10833            int fvers = dis.readInt();
10834            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10835                String vers = dis.readUTF();
10836                String codename = dis.readUTF();
10837                String build = dis.readUTF();
10838                if (android.os.Build.VERSION.RELEASE.equals(vers)
10839                        && android.os.Build.VERSION.CODENAME.equals(codename)
10840                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10841                    int num = dis.readInt();
10842                    while (num > 0) {
10843                        num--;
10844                        String pkg = dis.readUTF();
10845                        String cls = dis.readUTF();
10846                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10847                    }
10848                }
10849            }
10850        } catch (FileNotFoundException e) {
10851        } catch (IOException e) {
10852            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10853        } finally {
10854            if (fis != null) {
10855                try {
10856                    fis.close();
10857                } catch (IOException e) {
10858                }
10859            }
10860        }
10861        return lastDoneReceivers;
10862    }
10863
10864    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10865        File file = getCalledPreBootReceiversFile();
10866        FileOutputStream fos = null;
10867        DataOutputStream dos = null;
10868        try {
10869            fos = new FileOutputStream(file);
10870            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10871            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10872            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10873            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10874            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10875            dos.writeInt(list.size());
10876            for (int i=0; i<list.size(); i++) {
10877                dos.writeUTF(list.get(i).getPackageName());
10878                dos.writeUTF(list.get(i).getClassName());
10879            }
10880        } catch (IOException e) {
10881            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10882            file.delete();
10883        } finally {
10884            FileUtils.sync(fos);
10885            if (dos != null) {
10886                try {
10887                    dos.close();
10888                } catch (IOException e) {
10889                    // TODO Auto-generated catch block
10890                    e.printStackTrace();
10891                }
10892            }
10893        }
10894    }
10895
10896    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10897            ArrayList<ComponentName> doneReceivers, int userId) {
10898        boolean waitingUpdate = false;
10899        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10900        List<ResolveInfo> ris = null;
10901        try {
10902            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10903                    intent, null, 0, userId);
10904        } catch (RemoteException e) {
10905        }
10906        if (ris != null) {
10907            for (int i=ris.size()-1; i>=0; i--) {
10908                if ((ris.get(i).activityInfo.applicationInfo.flags
10909                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10910                    ris.remove(i);
10911                }
10912            }
10913            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10914
10915            // For User 0, load the version number. When delivering to a new user, deliver
10916            // to all receivers.
10917            if (userId == UserHandle.USER_OWNER) {
10918                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10919                for (int i=0; i<ris.size(); i++) {
10920                    ActivityInfo ai = ris.get(i).activityInfo;
10921                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10922                    if (lastDoneReceivers.contains(comp)) {
10923                        // We already did the pre boot receiver for this app with the current
10924                        // platform version, so don't do it again...
10925                        ris.remove(i);
10926                        i--;
10927                        // ...however, do keep it as one that has been done, so we don't
10928                        // forget about it when rewriting the file of last done receivers.
10929                        doneReceivers.add(comp);
10930                    }
10931                }
10932            }
10933
10934            // If primary user, send broadcast to all available users, else just to userId
10935            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10936                    : new int[] { userId };
10937            for (int i = 0; i < ris.size(); i++) {
10938                ActivityInfo ai = ris.get(i).activityInfo;
10939                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10940                doneReceivers.add(comp);
10941                intent.setComponent(comp);
10942                for (int j=0; j<users.length; j++) {
10943                    IIntentReceiver finisher = null;
10944                    // On last receiver and user, set up a completion callback
10945                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10946                        finisher = new IIntentReceiver.Stub() {
10947                            public void performReceive(Intent intent, int resultCode,
10948                                    String data, Bundle extras, boolean ordered,
10949                                    boolean sticky, int sendingUser) {
10950                                // The raw IIntentReceiver interface is called
10951                                // with the AM lock held, so redispatch to
10952                                // execute our code without the lock.
10953                                mHandler.post(onFinishCallback);
10954                            }
10955                        };
10956                    }
10957                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10958                            + " for user " + users[j]);
10959                    broadcastIntentLocked(null, null, intent, null, finisher,
10960                            0, null, null, null, AppOpsManager.OP_NONE,
10961                            true, false, MY_PID, Process.SYSTEM_UID,
10962                            users[j]);
10963                    if (finisher != null) {
10964                        waitingUpdate = true;
10965                    }
10966                }
10967            }
10968        }
10969
10970        return waitingUpdate;
10971    }
10972
10973    public void systemReady(final Runnable goingCallback) {
10974        synchronized(this) {
10975            if (mSystemReady) {
10976                // If we're done calling all the receivers, run the next "boot phase" passed in
10977                // by the SystemServer
10978                if (goingCallback != null) {
10979                    goingCallback.run();
10980                }
10981                return;
10982            }
10983
10984            // Make sure we have the current profile info, since it is needed for
10985            // security checks.
10986            updateCurrentProfileIdsLocked();
10987
10988            if (mRecentTasks == null) {
10989                mRecentTasks = mTaskPersister.restoreTasksLocked();
10990                if (!mRecentTasks.isEmpty()) {
10991                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10992                }
10993                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10994                mTaskPersister.startPersisting();
10995            }
10996
10997            // Check to see if there are any update receivers to run.
10998            if (!mDidUpdate) {
10999                if (mWaitingUpdate) {
11000                    return;
11001                }
11002                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11003                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11004                    public void run() {
11005                        synchronized (ActivityManagerService.this) {
11006                            mDidUpdate = true;
11007                        }
11008                        writeLastDonePreBootReceivers(doneReceivers);
11009                        showBootMessage(mContext.getText(
11010                                R.string.android_upgrading_complete),
11011                                false);
11012                        systemReady(goingCallback);
11013                    }
11014                }, doneReceivers, UserHandle.USER_OWNER);
11015
11016                if (mWaitingUpdate) {
11017                    return;
11018                }
11019                mDidUpdate = true;
11020            }
11021
11022            mAppOpsService.systemReady();
11023            mSystemReady = true;
11024        }
11025
11026        ArrayList<ProcessRecord> procsToKill = null;
11027        synchronized(mPidsSelfLocked) {
11028            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11029                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11030                if (!isAllowedWhileBooting(proc.info)){
11031                    if (procsToKill == null) {
11032                        procsToKill = new ArrayList<ProcessRecord>();
11033                    }
11034                    procsToKill.add(proc);
11035                }
11036            }
11037        }
11038
11039        synchronized(this) {
11040            if (procsToKill != null) {
11041                for (int i=procsToKill.size()-1; i>=0; i--) {
11042                    ProcessRecord proc = procsToKill.get(i);
11043                    Slog.i(TAG, "Removing system update proc: " + proc);
11044                    removeProcessLocked(proc, true, false, "system update done");
11045                }
11046            }
11047
11048            // Now that we have cleaned up any update processes, we
11049            // are ready to start launching real processes and know that
11050            // we won't trample on them any more.
11051            mProcessesReady = true;
11052        }
11053
11054        Slog.i(TAG, "System now ready");
11055        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11056            SystemClock.uptimeMillis());
11057
11058        synchronized(this) {
11059            // Make sure we have no pre-ready processes sitting around.
11060
11061            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11062                ResolveInfo ri = mContext.getPackageManager()
11063                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11064                                STOCK_PM_FLAGS);
11065                CharSequence errorMsg = null;
11066                if (ri != null) {
11067                    ActivityInfo ai = ri.activityInfo;
11068                    ApplicationInfo app = ai.applicationInfo;
11069                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11070                        mTopAction = Intent.ACTION_FACTORY_TEST;
11071                        mTopData = null;
11072                        mTopComponent = new ComponentName(app.packageName,
11073                                ai.name);
11074                    } else {
11075                        errorMsg = mContext.getResources().getText(
11076                                com.android.internal.R.string.factorytest_not_system);
11077                    }
11078                } else {
11079                    errorMsg = mContext.getResources().getText(
11080                            com.android.internal.R.string.factorytest_no_action);
11081                }
11082                if (errorMsg != null) {
11083                    mTopAction = null;
11084                    mTopData = null;
11085                    mTopComponent = null;
11086                    Message msg = Message.obtain();
11087                    msg.what = SHOW_FACTORY_ERROR_MSG;
11088                    msg.getData().putCharSequence("msg", errorMsg);
11089                    mHandler.sendMessage(msg);
11090                }
11091            }
11092        }
11093
11094        retrieveSettings();
11095        loadResourcesOnSystemReady();
11096
11097        synchronized (this) {
11098            readGrantedUriPermissionsLocked();
11099        }
11100
11101        if (goingCallback != null) goingCallback.run();
11102
11103        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11104                Integer.toString(mCurrentUserId), mCurrentUserId);
11105        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11106                Integer.toString(mCurrentUserId), mCurrentUserId);
11107        mSystemServiceManager.startUser(mCurrentUserId);
11108
11109        synchronized (this) {
11110            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11111                try {
11112                    List apps = AppGlobals.getPackageManager().
11113                        getPersistentApplications(STOCK_PM_FLAGS);
11114                    if (apps != null) {
11115                        int N = apps.size();
11116                        int i;
11117                        for (i=0; i<N; i++) {
11118                            ApplicationInfo info
11119                                = (ApplicationInfo)apps.get(i);
11120                            if (info != null &&
11121                                    !info.packageName.equals("android")) {
11122                                addAppLocked(info, false, null /* ABI override */);
11123                            }
11124                        }
11125                    }
11126                } catch (RemoteException ex) {
11127                    // pm is in same process, this will never happen.
11128                }
11129            }
11130
11131            // Start up initial activity.
11132            mBooting = true;
11133
11134            try {
11135                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11136                    Message msg = Message.obtain();
11137                    msg.what = SHOW_UID_ERROR_MSG;
11138                    mHandler.sendMessage(msg);
11139                }
11140            } catch (RemoteException e) {
11141            }
11142
11143            long ident = Binder.clearCallingIdentity();
11144            try {
11145                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11146                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11147                        | Intent.FLAG_RECEIVER_FOREGROUND);
11148                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11149                broadcastIntentLocked(null, null, intent,
11150                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11151                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11152                intent = new Intent(Intent.ACTION_USER_STARTING);
11153                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11154                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11155                broadcastIntentLocked(null, null, intent,
11156                        null, new IIntentReceiver.Stub() {
11157                            @Override
11158                            public void performReceive(Intent intent, int resultCode, String data,
11159                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11160                                    throws RemoteException {
11161                            }
11162                        }, 0, null, null,
11163                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11164                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11165            } catch (Throwable t) {
11166                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11167            } finally {
11168                Binder.restoreCallingIdentity(ident);
11169            }
11170            mStackSupervisor.resumeTopActivitiesLocked();
11171            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11172        }
11173    }
11174
11175    private boolean makeAppCrashingLocked(ProcessRecord app,
11176            String shortMsg, String longMsg, String stackTrace) {
11177        app.crashing = true;
11178        app.crashingReport = generateProcessError(app,
11179                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11180        startAppProblemLocked(app);
11181        app.stopFreezingAllLocked();
11182        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11183    }
11184
11185    private void makeAppNotRespondingLocked(ProcessRecord app,
11186            String activity, String shortMsg, String longMsg) {
11187        app.notResponding = true;
11188        app.notRespondingReport = generateProcessError(app,
11189                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11190                activity, shortMsg, longMsg, null);
11191        startAppProblemLocked(app);
11192        app.stopFreezingAllLocked();
11193    }
11194
11195    /**
11196     * Generate a process error record, suitable for attachment to a ProcessRecord.
11197     *
11198     * @param app The ProcessRecord in which the error occurred.
11199     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11200     *                      ActivityManager.AppErrorStateInfo
11201     * @param activity The activity associated with the crash, if known.
11202     * @param shortMsg Short message describing the crash.
11203     * @param longMsg Long message describing the crash.
11204     * @param stackTrace Full crash stack trace, may be null.
11205     *
11206     * @return Returns a fully-formed AppErrorStateInfo record.
11207     */
11208    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11209            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11210        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11211
11212        report.condition = condition;
11213        report.processName = app.processName;
11214        report.pid = app.pid;
11215        report.uid = app.info.uid;
11216        report.tag = activity;
11217        report.shortMsg = shortMsg;
11218        report.longMsg = longMsg;
11219        report.stackTrace = stackTrace;
11220
11221        return report;
11222    }
11223
11224    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11225        synchronized (this) {
11226            app.crashing = false;
11227            app.crashingReport = null;
11228            app.notResponding = false;
11229            app.notRespondingReport = null;
11230            if (app.anrDialog == fromDialog) {
11231                app.anrDialog = null;
11232            }
11233            if (app.waitDialog == fromDialog) {
11234                app.waitDialog = null;
11235            }
11236            if (app.pid > 0 && app.pid != MY_PID) {
11237                handleAppCrashLocked(app, null, null, null);
11238                app.kill("user request after error", true);
11239            }
11240        }
11241    }
11242
11243    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11244            String stackTrace) {
11245        long now = SystemClock.uptimeMillis();
11246
11247        Long crashTime;
11248        if (!app.isolated) {
11249            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11250        } else {
11251            crashTime = null;
11252        }
11253        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11254            // This process loses!
11255            Slog.w(TAG, "Process " + app.info.processName
11256                    + " has crashed too many times: killing!");
11257            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11258                    app.userId, app.info.processName, app.uid);
11259            mStackSupervisor.handleAppCrashLocked(app);
11260            if (!app.persistent) {
11261                // We don't want to start this process again until the user
11262                // explicitly does so...  but for persistent process, we really
11263                // need to keep it running.  If a persistent process is actually
11264                // repeatedly crashing, then badness for everyone.
11265                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11266                        app.info.processName);
11267                if (!app.isolated) {
11268                    // XXX We don't have a way to mark isolated processes
11269                    // as bad, since they don't have a peristent identity.
11270                    mBadProcesses.put(app.info.processName, app.uid,
11271                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11272                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11273                }
11274                app.bad = true;
11275                app.removed = true;
11276                // Don't let services in this process be restarted and potentially
11277                // annoy the user repeatedly.  Unless it is persistent, since those
11278                // processes run critical code.
11279                removeProcessLocked(app, false, false, "crash");
11280                mStackSupervisor.resumeTopActivitiesLocked();
11281                return false;
11282            }
11283            mStackSupervisor.resumeTopActivitiesLocked();
11284        } else {
11285            mStackSupervisor.finishTopRunningActivityLocked(app);
11286        }
11287
11288        // Bump up the crash count of any services currently running in the proc.
11289        for (int i=app.services.size()-1; i>=0; i--) {
11290            // Any services running in the application need to be placed
11291            // back in the pending list.
11292            ServiceRecord sr = app.services.valueAt(i);
11293            sr.crashCount++;
11294        }
11295
11296        // If the crashing process is what we consider to be the "home process" and it has been
11297        // replaced by a third-party app, clear the package preferred activities from packages
11298        // with a home activity running in the process to prevent a repeatedly crashing app
11299        // from blocking the user to manually clear the list.
11300        final ArrayList<ActivityRecord> activities = app.activities;
11301        if (app == mHomeProcess && activities.size() > 0
11302                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11303            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11304                final ActivityRecord r = activities.get(activityNdx);
11305                if (r.isHomeActivity()) {
11306                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11307                    try {
11308                        ActivityThread.getPackageManager()
11309                                .clearPackagePreferredActivities(r.packageName);
11310                    } catch (RemoteException c) {
11311                        // pm is in same process, this will never happen.
11312                    }
11313                }
11314            }
11315        }
11316
11317        if (!app.isolated) {
11318            // XXX Can't keep track of crash times for isolated processes,
11319            // because they don't have a perisistent identity.
11320            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11321        }
11322
11323        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11324        return true;
11325    }
11326
11327    void startAppProblemLocked(ProcessRecord app) {
11328        // If this app is not running under the current user, then we
11329        // can't give it a report button because that would require
11330        // launching the report UI under a different user.
11331        app.errorReportReceiver = null;
11332
11333        for (int userId : mCurrentProfileIds) {
11334            if (app.userId == userId) {
11335                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11336                        mContext, app.info.packageName, app.info.flags);
11337            }
11338        }
11339        skipCurrentReceiverLocked(app);
11340    }
11341
11342    void skipCurrentReceiverLocked(ProcessRecord app) {
11343        for (BroadcastQueue queue : mBroadcastQueues) {
11344            queue.skipCurrentReceiverLocked(app);
11345        }
11346    }
11347
11348    /**
11349     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11350     * The application process will exit immediately after this call returns.
11351     * @param app object of the crashing app, null for the system server
11352     * @param crashInfo describing the exception
11353     */
11354    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11355        ProcessRecord r = findAppProcess(app, "Crash");
11356        final String processName = app == null ? "system_server"
11357                : (r == null ? "unknown" : r.processName);
11358
11359        handleApplicationCrashInner("crash", r, processName, crashInfo);
11360    }
11361
11362    /* Native crash reporting uses this inner version because it needs to be somewhat
11363     * decoupled from the AM-managed cleanup lifecycle
11364     */
11365    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11366            ApplicationErrorReport.CrashInfo crashInfo) {
11367        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11368                UserHandle.getUserId(Binder.getCallingUid()), processName,
11369                r == null ? -1 : r.info.flags,
11370                crashInfo.exceptionClassName,
11371                crashInfo.exceptionMessage,
11372                crashInfo.throwFileName,
11373                crashInfo.throwLineNumber);
11374
11375        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11376
11377        crashApplication(r, crashInfo);
11378    }
11379
11380    public void handleApplicationStrictModeViolation(
11381            IBinder app,
11382            int violationMask,
11383            StrictMode.ViolationInfo info) {
11384        ProcessRecord r = findAppProcess(app, "StrictMode");
11385        if (r == null) {
11386            return;
11387        }
11388
11389        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11390            Integer stackFingerprint = info.hashCode();
11391            boolean logIt = true;
11392            synchronized (mAlreadyLoggedViolatedStacks) {
11393                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11394                    logIt = false;
11395                    // TODO: sub-sample into EventLog for these, with
11396                    // the info.durationMillis?  Then we'd get
11397                    // the relative pain numbers, without logging all
11398                    // the stack traces repeatedly.  We'd want to do
11399                    // likewise in the client code, which also does
11400                    // dup suppression, before the Binder call.
11401                } else {
11402                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11403                        mAlreadyLoggedViolatedStacks.clear();
11404                    }
11405                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11406                }
11407            }
11408            if (logIt) {
11409                logStrictModeViolationToDropBox(r, info);
11410            }
11411        }
11412
11413        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11414            AppErrorResult result = new AppErrorResult();
11415            synchronized (this) {
11416                final long origId = Binder.clearCallingIdentity();
11417
11418                Message msg = Message.obtain();
11419                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11420                HashMap<String, Object> data = new HashMap<String, Object>();
11421                data.put("result", result);
11422                data.put("app", r);
11423                data.put("violationMask", violationMask);
11424                data.put("info", info);
11425                msg.obj = data;
11426                mHandler.sendMessage(msg);
11427
11428                Binder.restoreCallingIdentity(origId);
11429            }
11430            int res = result.get();
11431            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11432        }
11433    }
11434
11435    // Depending on the policy in effect, there could be a bunch of
11436    // these in quick succession so we try to batch these together to
11437    // minimize disk writes, number of dropbox entries, and maximize
11438    // compression, by having more fewer, larger records.
11439    private void logStrictModeViolationToDropBox(
11440            ProcessRecord process,
11441            StrictMode.ViolationInfo info) {
11442        if (info == null) {
11443            return;
11444        }
11445        final boolean isSystemApp = process == null ||
11446                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11447                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11448        final String processName = process == null ? "unknown" : process.processName;
11449        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11450        final DropBoxManager dbox = (DropBoxManager)
11451                mContext.getSystemService(Context.DROPBOX_SERVICE);
11452
11453        // Exit early if the dropbox isn't configured to accept this report type.
11454        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11455
11456        boolean bufferWasEmpty;
11457        boolean needsFlush;
11458        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11459        synchronized (sb) {
11460            bufferWasEmpty = sb.length() == 0;
11461            appendDropBoxProcessHeaders(process, processName, sb);
11462            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11463            sb.append("System-App: ").append(isSystemApp).append("\n");
11464            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11465            if (info.violationNumThisLoop != 0) {
11466                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11467            }
11468            if (info.numAnimationsRunning != 0) {
11469                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11470            }
11471            if (info.broadcastIntentAction != null) {
11472                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11473            }
11474            if (info.durationMillis != -1) {
11475                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11476            }
11477            if (info.numInstances != -1) {
11478                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11479            }
11480            if (info.tags != null) {
11481                for (String tag : info.tags) {
11482                    sb.append("Span-Tag: ").append(tag).append("\n");
11483                }
11484            }
11485            sb.append("\n");
11486            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11487                sb.append(info.crashInfo.stackTrace);
11488            }
11489            sb.append("\n");
11490
11491            // Only buffer up to ~64k.  Various logging bits truncate
11492            // things at 128k.
11493            needsFlush = (sb.length() > 64 * 1024);
11494        }
11495
11496        // Flush immediately if the buffer's grown too large, or this
11497        // is a non-system app.  Non-system apps are isolated with a
11498        // different tag & policy and not batched.
11499        //
11500        // Batching is useful during internal testing with
11501        // StrictMode settings turned up high.  Without batching,
11502        // thousands of separate files could be created on boot.
11503        if (!isSystemApp || needsFlush) {
11504            new Thread("Error dump: " + dropboxTag) {
11505                @Override
11506                public void run() {
11507                    String report;
11508                    synchronized (sb) {
11509                        report = sb.toString();
11510                        sb.delete(0, sb.length());
11511                        sb.trimToSize();
11512                    }
11513                    if (report.length() != 0) {
11514                        dbox.addText(dropboxTag, report);
11515                    }
11516                }
11517            }.start();
11518            return;
11519        }
11520
11521        // System app batching:
11522        if (!bufferWasEmpty) {
11523            // An existing dropbox-writing thread is outstanding, so
11524            // we don't need to start it up.  The existing thread will
11525            // catch the buffer appends we just did.
11526            return;
11527        }
11528
11529        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11530        // (After this point, we shouldn't access AMS internal data structures.)
11531        new Thread("Error dump: " + dropboxTag) {
11532            @Override
11533            public void run() {
11534                // 5 second sleep to let stacks arrive and be batched together
11535                try {
11536                    Thread.sleep(5000);  // 5 seconds
11537                } catch (InterruptedException e) {}
11538
11539                String errorReport;
11540                synchronized (mStrictModeBuffer) {
11541                    errorReport = mStrictModeBuffer.toString();
11542                    if (errorReport.length() == 0) {
11543                        return;
11544                    }
11545                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11546                    mStrictModeBuffer.trimToSize();
11547                }
11548                dbox.addText(dropboxTag, errorReport);
11549            }
11550        }.start();
11551    }
11552
11553    /**
11554     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11555     * @param app object of the crashing app, null for the system server
11556     * @param tag reported by the caller
11557     * @param system whether this wtf is coming from the system
11558     * @param crashInfo describing the context of the error
11559     * @return true if the process should exit immediately (WTF is fatal)
11560     */
11561    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11562            final ApplicationErrorReport.CrashInfo crashInfo) {
11563        final ProcessRecord r = findAppProcess(app, "WTF");
11564        final String processName = app == null ? "system_server"
11565                : (r == null ? "unknown" : r.processName);
11566
11567        EventLog.writeEvent(EventLogTags.AM_WTF,
11568                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11569                processName,
11570                r == null ? -1 : r.info.flags,
11571                tag, crashInfo.exceptionMessage);
11572
11573        if (system) {
11574            // If this is coming from the system, we could very well have low-level
11575            // system locks held, so we want to do this all asynchronously.  And we
11576            // never want this to become fatal, so there is that too.
11577            mHandler.post(new Runnable() {
11578                @Override public void run() {
11579                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11580                            crashInfo);
11581                }
11582            });
11583            return false;
11584        }
11585
11586        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11587
11588        if (r != null && r.pid != Process.myPid() &&
11589                Settings.Global.getInt(mContext.getContentResolver(),
11590                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11591            crashApplication(r, crashInfo);
11592            return true;
11593        } else {
11594            return false;
11595        }
11596    }
11597
11598    /**
11599     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11600     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11601     */
11602    private ProcessRecord findAppProcess(IBinder app, String reason) {
11603        if (app == null) {
11604            return null;
11605        }
11606
11607        synchronized (this) {
11608            final int NP = mProcessNames.getMap().size();
11609            for (int ip=0; ip<NP; ip++) {
11610                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11611                final int NA = apps.size();
11612                for (int ia=0; ia<NA; ia++) {
11613                    ProcessRecord p = apps.valueAt(ia);
11614                    if (p.thread != null && p.thread.asBinder() == app) {
11615                        return p;
11616                    }
11617                }
11618            }
11619
11620            Slog.w(TAG, "Can't find mystery application for " + reason
11621                    + " from pid=" + Binder.getCallingPid()
11622                    + " uid=" + Binder.getCallingUid() + ": " + app);
11623            return null;
11624        }
11625    }
11626
11627    /**
11628     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11629     * to append various headers to the dropbox log text.
11630     */
11631    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11632            StringBuilder sb) {
11633        // Watchdog thread ends up invoking this function (with
11634        // a null ProcessRecord) to add the stack file to dropbox.
11635        // Do not acquire a lock on this (am) in such cases, as it
11636        // could cause a potential deadlock, if and when watchdog
11637        // is invoked due to unavailability of lock on am and it
11638        // would prevent watchdog from killing system_server.
11639        if (process == null) {
11640            sb.append("Process: ").append(processName).append("\n");
11641            return;
11642        }
11643        // Note: ProcessRecord 'process' is guarded by the service
11644        // instance.  (notably process.pkgList, which could otherwise change
11645        // concurrently during execution of this method)
11646        synchronized (this) {
11647            sb.append("Process: ").append(processName).append("\n");
11648            int flags = process.info.flags;
11649            IPackageManager pm = AppGlobals.getPackageManager();
11650            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11651            for (int ip=0; ip<process.pkgList.size(); ip++) {
11652                String pkg = process.pkgList.keyAt(ip);
11653                sb.append("Package: ").append(pkg);
11654                try {
11655                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11656                    if (pi != null) {
11657                        sb.append(" v").append(pi.versionCode);
11658                        if (pi.versionName != null) {
11659                            sb.append(" (").append(pi.versionName).append(")");
11660                        }
11661                    }
11662                } catch (RemoteException e) {
11663                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11664                }
11665                sb.append("\n");
11666            }
11667        }
11668    }
11669
11670    private static String processClass(ProcessRecord process) {
11671        if (process == null || process.pid == MY_PID) {
11672            return "system_server";
11673        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11674            return "system_app";
11675        } else {
11676            return "data_app";
11677        }
11678    }
11679
11680    /**
11681     * Write a description of an error (crash, WTF, ANR) to the drop box.
11682     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11683     * @param process which caused the error, null means the system server
11684     * @param activity which triggered the error, null if unknown
11685     * @param parent activity related to the error, null if unknown
11686     * @param subject line related to the error, null if absent
11687     * @param report in long form describing the error, null if absent
11688     * @param logFile to include in the report, null if none
11689     * @param crashInfo giving an application stack trace, null if absent
11690     */
11691    public void addErrorToDropBox(String eventType,
11692            ProcessRecord process, String processName, ActivityRecord activity,
11693            ActivityRecord parent, String subject,
11694            final String report, final File logFile,
11695            final ApplicationErrorReport.CrashInfo crashInfo) {
11696        // NOTE -- this must never acquire the ActivityManagerService lock,
11697        // otherwise the watchdog may be prevented from resetting the system.
11698
11699        final String dropboxTag = processClass(process) + "_" + eventType;
11700        final DropBoxManager dbox = (DropBoxManager)
11701                mContext.getSystemService(Context.DROPBOX_SERVICE);
11702
11703        // Exit early if the dropbox isn't configured to accept this report type.
11704        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11705
11706        final StringBuilder sb = new StringBuilder(1024);
11707        appendDropBoxProcessHeaders(process, processName, sb);
11708        if (activity != null) {
11709            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11710        }
11711        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11712            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11713        }
11714        if (parent != null && parent != activity) {
11715            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11716        }
11717        if (subject != null) {
11718            sb.append("Subject: ").append(subject).append("\n");
11719        }
11720        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11721        if (Debug.isDebuggerConnected()) {
11722            sb.append("Debugger: Connected\n");
11723        }
11724        sb.append("\n");
11725
11726        // Do the rest in a worker thread to avoid blocking the caller on I/O
11727        // (After this point, we shouldn't access AMS internal data structures.)
11728        Thread worker = new Thread("Error dump: " + dropboxTag) {
11729            @Override
11730            public void run() {
11731                if (report != null) {
11732                    sb.append(report);
11733                }
11734                if (logFile != null) {
11735                    try {
11736                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11737                                    "\n\n[[TRUNCATED]]"));
11738                    } catch (IOException e) {
11739                        Slog.e(TAG, "Error reading " + logFile, e);
11740                    }
11741                }
11742                if (crashInfo != null && crashInfo.stackTrace != null) {
11743                    sb.append(crashInfo.stackTrace);
11744                }
11745
11746                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11747                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11748                if (lines > 0) {
11749                    sb.append("\n");
11750
11751                    // Merge several logcat streams, and take the last N lines
11752                    InputStreamReader input = null;
11753                    try {
11754                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11755                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11756                                "-b", "crash",
11757                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11758
11759                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11760                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11761                        input = new InputStreamReader(logcat.getInputStream());
11762
11763                        int num;
11764                        char[] buf = new char[8192];
11765                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11766                    } catch (IOException e) {
11767                        Slog.e(TAG, "Error running logcat", e);
11768                    } finally {
11769                        if (input != null) try { input.close(); } catch (IOException e) {}
11770                    }
11771                }
11772
11773                dbox.addText(dropboxTag, sb.toString());
11774            }
11775        };
11776
11777        if (process == null) {
11778            // If process is null, we are being called from some internal code
11779            // and may be about to die -- run this synchronously.
11780            worker.run();
11781        } else {
11782            worker.start();
11783        }
11784    }
11785
11786    /**
11787     * Bring up the "unexpected error" dialog box for a crashing app.
11788     * Deal with edge cases (intercepts from instrumented applications,
11789     * ActivityController, error intent receivers, that sort of thing).
11790     * @param r the application crashing
11791     * @param crashInfo describing the failure
11792     */
11793    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11794        long timeMillis = System.currentTimeMillis();
11795        String shortMsg = crashInfo.exceptionClassName;
11796        String longMsg = crashInfo.exceptionMessage;
11797        String stackTrace = crashInfo.stackTrace;
11798        if (shortMsg != null && longMsg != null) {
11799            longMsg = shortMsg + ": " + longMsg;
11800        } else if (shortMsg != null) {
11801            longMsg = shortMsg;
11802        }
11803
11804        AppErrorResult result = new AppErrorResult();
11805        synchronized (this) {
11806            if (mController != null) {
11807                try {
11808                    String name = r != null ? r.processName : null;
11809                    int pid = r != null ? r.pid : Binder.getCallingPid();
11810                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11811                    if (!mController.appCrashed(name, pid,
11812                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11813                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11814                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11815                            Slog.w(TAG, "Skip killing native crashed app " + name
11816                                    + "(" + pid + ") during testing");
11817                        } else {
11818                            Slog.w(TAG, "Force-killing crashed app " + name
11819                                    + " at watcher's request");
11820                            if (r != null) {
11821                                r.kill("crash", true);
11822                            } else {
11823                                // Huh.
11824                                Process.killProcess(pid);
11825                                Process.killProcessGroup(uid, pid);
11826                            }
11827                        }
11828                        return;
11829                    }
11830                } catch (RemoteException e) {
11831                    mController = null;
11832                    Watchdog.getInstance().setActivityController(null);
11833                }
11834            }
11835
11836            final long origId = Binder.clearCallingIdentity();
11837
11838            // If this process is running instrumentation, finish it.
11839            if (r != null && r.instrumentationClass != null) {
11840                Slog.w(TAG, "Error in app " + r.processName
11841                      + " running instrumentation " + r.instrumentationClass + ":");
11842                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11843                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11844                Bundle info = new Bundle();
11845                info.putString("shortMsg", shortMsg);
11846                info.putString("longMsg", longMsg);
11847                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11848                Binder.restoreCallingIdentity(origId);
11849                return;
11850            }
11851
11852            // If we can't identify the process or it's already exceeded its crash quota,
11853            // quit right away without showing a crash dialog.
11854            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11855                Binder.restoreCallingIdentity(origId);
11856                return;
11857            }
11858
11859            Message msg = Message.obtain();
11860            msg.what = SHOW_ERROR_MSG;
11861            HashMap data = new HashMap();
11862            data.put("result", result);
11863            data.put("app", r);
11864            msg.obj = data;
11865            mHandler.sendMessage(msg);
11866
11867            Binder.restoreCallingIdentity(origId);
11868        }
11869
11870        int res = result.get();
11871
11872        Intent appErrorIntent = null;
11873        synchronized (this) {
11874            if (r != null && !r.isolated) {
11875                // XXX Can't keep track of crash time for isolated processes,
11876                // since they don't have a persistent identity.
11877                mProcessCrashTimes.put(r.info.processName, r.uid,
11878                        SystemClock.uptimeMillis());
11879            }
11880            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11881                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11882            }
11883        }
11884
11885        if (appErrorIntent != null) {
11886            try {
11887                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11888            } catch (ActivityNotFoundException e) {
11889                Slog.w(TAG, "bug report receiver dissappeared", e);
11890            }
11891        }
11892    }
11893
11894    Intent createAppErrorIntentLocked(ProcessRecord r,
11895            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11896        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11897        if (report == null) {
11898            return null;
11899        }
11900        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11901        result.setComponent(r.errorReportReceiver);
11902        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11903        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11904        return result;
11905    }
11906
11907    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11908            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11909        if (r.errorReportReceiver == null) {
11910            return null;
11911        }
11912
11913        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11914            return null;
11915        }
11916
11917        ApplicationErrorReport report = new ApplicationErrorReport();
11918        report.packageName = r.info.packageName;
11919        report.installerPackageName = r.errorReportReceiver.getPackageName();
11920        report.processName = r.processName;
11921        report.time = timeMillis;
11922        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11923
11924        if (r.crashing || r.forceCrashReport) {
11925            report.type = ApplicationErrorReport.TYPE_CRASH;
11926            report.crashInfo = crashInfo;
11927        } else if (r.notResponding) {
11928            report.type = ApplicationErrorReport.TYPE_ANR;
11929            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11930
11931            report.anrInfo.activity = r.notRespondingReport.tag;
11932            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11933            report.anrInfo.info = r.notRespondingReport.longMsg;
11934        }
11935
11936        return report;
11937    }
11938
11939    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11940        enforceNotIsolatedCaller("getProcessesInErrorState");
11941        // assume our apps are happy - lazy create the list
11942        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11943
11944        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11945                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11946        int userId = UserHandle.getUserId(Binder.getCallingUid());
11947
11948        synchronized (this) {
11949
11950            // iterate across all processes
11951            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11952                ProcessRecord app = mLruProcesses.get(i);
11953                if (!allUsers && app.userId != userId) {
11954                    continue;
11955                }
11956                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11957                    // This one's in trouble, so we'll generate a report for it
11958                    // crashes are higher priority (in case there's a crash *and* an anr)
11959                    ActivityManager.ProcessErrorStateInfo report = null;
11960                    if (app.crashing) {
11961                        report = app.crashingReport;
11962                    } else if (app.notResponding) {
11963                        report = app.notRespondingReport;
11964                    }
11965
11966                    if (report != null) {
11967                        if (errList == null) {
11968                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11969                        }
11970                        errList.add(report);
11971                    } else {
11972                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11973                                " crashing = " + app.crashing +
11974                                " notResponding = " + app.notResponding);
11975                    }
11976                }
11977            }
11978        }
11979
11980        return errList;
11981    }
11982
11983    static int procStateToImportance(int procState, int memAdj,
11984            ActivityManager.RunningAppProcessInfo currApp) {
11985        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11986        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11987            currApp.lru = memAdj;
11988        } else {
11989            currApp.lru = 0;
11990        }
11991        return imp;
11992    }
11993
11994    private void fillInProcMemInfo(ProcessRecord app,
11995            ActivityManager.RunningAppProcessInfo outInfo) {
11996        outInfo.pid = app.pid;
11997        outInfo.uid = app.info.uid;
11998        if (mHeavyWeightProcess == app) {
11999            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12000        }
12001        if (app.persistent) {
12002            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12003        }
12004        if (app.activities.size() > 0) {
12005            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12006        }
12007        outInfo.lastTrimLevel = app.trimMemoryLevel;
12008        int adj = app.curAdj;
12009        int procState = app.curProcState;
12010        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12011        outInfo.importanceReasonCode = app.adjTypeCode;
12012        outInfo.processState = app.curProcState;
12013    }
12014
12015    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12016        enforceNotIsolatedCaller("getRunningAppProcesses");
12017        // Lazy instantiation of list
12018        List<ActivityManager.RunningAppProcessInfo> runList = null;
12019        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12020                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12021        int userId = UserHandle.getUserId(Binder.getCallingUid());
12022        synchronized (this) {
12023            // Iterate across all processes
12024            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12025                ProcessRecord app = mLruProcesses.get(i);
12026                if (!allUsers && app.userId != userId) {
12027                    continue;
12028                }
12029                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12030                    // Generate process state info for running application
12031                    ActivityManager.RunningAppProcessInfo currApp =
12032                        new ActivityManager.RunningAppProcessInfo(app.processName,
12033                                app.pid, app.getPackageList());
12034                    fillInProcMemInfo(app, currApp);
12035                    if (app.adjSource instanceof ProcessRecord) {
12036                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12037                        currApp.importanceReasonImportance =
12038                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12039                                        app.adjSourceProcState);
12040                    } else if (app.adjSource instanceof ActivityRecord) {
12041                        ActivityRecord r = (ActivityRecord)app.adjSource;
12042                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12043                    }
12044                    if (app.adjTarget instanceof ComponentName) {
12045                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12046                    }
12047                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12048                    //        + " lru=" + currApp.lru);
12049                    if (runList == null) {
12050                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12051                    }
12052                    runList.add(currApp);
12053                }
12054            }
12055        }
12056        return runList;
12057    }
12058
12059    public List<ApplicationInfo> getRunningExternalApplications() {
12060        enforceNotIsolatedCaller("getRunningExternalApplications");
12061        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12062        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12063        if (runningApps != null && runningApps.size() > 0) {
12064            Set<String> extList = new HashSet<String>();
12065            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12066                if (app.pkgList != null) {
12067                    for (String pkg : app.pkgList) {
12068                        extList.add(pkg);
12069                    }
12070                }
12071            }
12072            IPackageManager pm = AppGlobals.getPackageManager();
12073            for (String pkg : extList) {
12074                try {
12075                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12076                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12077                        retList.add(info);
12078                    }
12079                } catch (RemoteException e) {
12080                }
12081            }
12082        }
12083        return retList;
12084    }
12085
12086    @Override
12087    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12088        enforceNotIsolatedCaller("getMyMemoryState");
12089        synchronized (this) {
12090            ProcessRecord proc;
12091            synchronized (mPidsSelfLocked) {
12092                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12093            }
12094            fillInProcMemInfo(proc, outInfo);
12095        }
12096    }
12097
12098    @Override
12099    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12100        if (checkCallingPermission(android.Manifest.permission.DUMP)
12101                != PackageManager.PERMISSION_GRANTED) {
12102            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12103                    + Binder.getCallingPid()
12104                    + ", uid=" + Binder.getCallingUid()
12105                    + " without permission "
12106                    + android.Manifest.permission.DUMP);
12107            return;
12108        }
12109
12110        boolean dumpAll = false;
12111        boolean dumpClient = false;
12112        String dumpPackage = null;
12113
12114        int opti = 0;
12115        while (opti < args.length) {
12116            String opt = args[opti];
12117            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12118                break;
12119            }
12120            opti++;
12121            if ("-a".equals(opt)) {
12122                dumpAll = true;
12123            } else if ("-c".equals(opt)) {
12124                dumpClient = true;
12125            } else if ("-h".equals(opt)) {
12126                pw.println("Activity manager dump options:");
12127                pw.println("  [-a] [-c] [-h] [cmd] ...");
12128                pw.println("  cmd may be one of:");
12129                pw.println("    a[ctivities]: activity stack state");
12130                pw.println("    r[recents]: recent activities state");
12131                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12132                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12133                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12134                pw.println("    o[om]: out of memory management");
12135                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12136                pw.println("    provider [COMP_SPEC]: provider client-side state");
12137                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12138                pw.println("    service [COMP_SPEC]: service client-side state");
12139                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12140                pw.println("    all: dump all activities");
12141                pw.println("    top: dump the top activity");
12142                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12143                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12144                pw.println("    a partial substring in a component name, a");
12145                pw.println("    hex object identifier.");
12146                pw.println("  -a: include all available server state.");
12147                pw.println("  -c: include client state.");
12148                return;
12149            } else {
12150                pw.println("Unknown argument: " + opt + "; use -h for help");
12151            }
12152        }
12153
12154        long origId = Binder.clearCallingIdentity();
12155        boolean more = false;
12156        // Is the caller requesting to dump a particular piece of data?
12157        if (opti < args.length) {
12158            String cmd = args[opti];
12159            opti++;
12160            if ("activities".equals(cmd) || "a".equals(cmd)) {
12161                synchronized (this) {
12162                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12163                }
12164            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12165                synchronized (this) {
12166                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12167                }
12168            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12169                String[] newArgs;
12170                String name;
12171                if (opti >= args.length) {
12172                    name = null;
12173                    newArgs = EMPTY_STRING_ARRAY;
12174                } else {
12175                    name = args[opti];
12176                    opti++;
12177                    newArgs = new String[args.length - opti];
12178                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12179                            args.length - opti);
12180                }
12181                synchronized (this) {
12182                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12183                }
12184            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12185                String[] newArgs;
12186                String name;
12187                if (opti >= args.length) {
12188                    name = null;
12189                    newArgs = EMPTY_STRING_ARRAY;
12190                } else {
12191                    name = args[opti];
12192                    opti++;
12193                    newArgs = new String[args.length - opti];
12194                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12195                            args.length - opti);
12196                }
12197                synchronized (this) {
12198                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12199                }
12200            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12201                String[] newArgs;
12202                String name;
12203                if (opti >= args.length) {
12204                    name = null;
12205                    newArgs = EMPTY_STRING_ARRAY;
12206                } else {
12207                    name = args[opti];
12208                    opti++;
12209                    newArgs = new String[args.length - opti];
12210                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12211                            args.length - opti);
12212                }
12213                synchronized (this) {
12214                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12215                }
12216            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12217                synchronized (this) {
12218                    dumpOomLocked(fd, pw, args, opti, true);
12219                }
12220            } else if ("provider".equals(cmd)) {
12221                String[] newArgs;
12222                String name;
12223                if (opti >= args.length) {
12224                    name = null;
12225                    newArgs = EMPTY_STRING_ARRAY;
12226                } else {
12227                    name = args[opti];
12228                    opti++;
12229                    newArgs = new String[args.length - opti];
12230                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12231                }
12232                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12233                    pw.println("No providers match: " + name);
12234                    pw.println("Use -h for help.");
12235                }
12236            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12237                synchronized (this) {
12238                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12239                }
12240            } else if ("service".equals(cmd)) {
12241                String[] newArgs;
12242                String name;
12243                if (opti >= args.length) {
12244                    name = null;
12245                    newArgs = EMPTY_STRING_ARRAY;
12246                } else {
12247                    name = args[opti];
12248                    opti++;
12249                    newArgs = new String[args.length - opti];
12250                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12251                            args.length - opti);
12252                }
12253                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12254                    pw.println("No services match: " + name);
12255                    pw.println("Use -h for help.");
12256                }
12257            } else if ("package".equals(cmd)) {
12258                String[] newArgs;
12259                if (opti >= args.length) {
12260                    pw.println("package: no package name specified");
12261                    pw.println("Use -h for help.");
12262                } else {
12263                    dumpPackage = args[opti];
12264                    opti++;
12265                    newArgs = new String[args.length - opti];
12266                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12267                            args.length - opti);
12268                    args = newArgs;
12269                    opti = 0;
12270                    more = true;
12271                }
12272            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12273                synchronized (this) {
12274                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12275                }
12276            } else {
12277                // Dumping a single activity?
12278                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12279                    pw.println("Bad activity command, or no activities match: " + cmd);
12280                    pw.println("Use -h for help.");
12281                }
12282            }
12283            if (!more) {
12284                Binder.restoreCallingIdentity(origId);
12285                return;
12286            }
12287        }
12288
12289        // No piece of data specified, dump everything.
12290        synchronized (this) {
12291            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12292            pw.println();
12293            if (dumpAll) {
12294                pw.println("-------------------------------------------------------------------------------");
12295            }
12296            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12297            pw.println();
12298            if (dumpAll) {
12299                pw.println("-------------------------------------------------------------------------------");
12300            }
12301            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12302            pw.println();
12303            if (dumpAll) {
12304                pw.println("-------------------------------------------------------------------------------");
12305            }
12306            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12307            pw.println();
12308            if (dumpAll) {
12309                pw.println("-------------------------------------------------------------------------------");
12310            }
12311            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12312            pw.println();
12313            if (dumpAll) {
12314                pw.println("-------------------------------------------------------------------------------");
12315            }
12316            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12317            pw.println();
12318            if (dumpAll) {
12319                pw.println("-------------------------------------------------------------------------------");
12320            }
12321            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12322        }
12323        Binder.restoreCallingIdentity(origId);
12324    }
12325
12326    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12327            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12328        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12329
12330        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12331                dumpPackage);
12332        boolean needSep = printedAnything;
12333
12334        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12335                dumpPackage, needSep, "  mFocusedActivity: ");
12336        if (printed) {
12337            printedAnything = true;
12338            needSep = false;
12339        }
12340
12341        if (dumpPackage == null) {
12342            if (needSep) {
12343                pw.println();
12344            }
12345            needSep = true;
12346            printedAnything = true;
12347            mStackSupervisor.dump(pw, "  ");
12348        }
12349
12350        if (!printedAnything) {
12351            pw.println("  (nothing)");
12352        }
12353    }
12354
12355    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12356            int opti, boolean dumpAll, String dumpPackage) {
12357        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12358
12359        boolean printedAnything = false;
12360
12361        if (mRecentTasks.size() > 0) {
12362            boolean printedHeader = false;
12363
12364            final int N = mRecentTasks.size();
12365            for (int i=0; i<N; i++) {
12366                TaskRecord tr = mRecentTasks.get(i);
12367                if (dumpPackage != null) {
12368                    if (tr.realActivity == null ||
12369                            !dumpPackage.equals(tr.realActivity)) {
12370                        continue;
12371                    }
12372                }
12373                if (!printedHeader) {
12374                    pw.println("  Recent tasks:");
12375                    printedHeader = true;
12376                    printedAnything = true;
12377                }
12378                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12379                        pw.println(tr);
12380                if (dumpAll) {
12381                    mRecentTasks.get(i).dump(pw, "    ");
12382                }
12383            }
12384        }
12385
12386        if (!printedAnything) {
12387            pw.println("  (nothing)");
12388        }
12389    }
12390
12391    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12392            int opti, boolean dumpAll, String dumpPackage) {
12393        boolean needSep = false;
12394        boolean printedAnything = false;
12395        int numPers = 0;
12396
12397        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12398
12399        if (dumpAll) {
12400            final int NP = mProcessNames.getMap().size();
12401            for (int ip=0; ip<NP; ip++) {
12402                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12403                final int NA = procs.size();
12404                for (int ia=0; ia<NA; ia++) {
12405                    ProcessRecord r = procs.valueAt(ia);
12406                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12407                        continue;
12408                    }
12409                    if (!needSep) {
12410                        pw.println("  All known processes:");
12411                        needSep = true;
12412                        printedAnything = true;
12413                    }
12414                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12415                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12416                        pw.print(" "); pw.println(r);
12417                    r.dump(pw, "    ");
12418                    if (r.persistent) {
12419                        numPers++;
12420                    }
12421                }
12422            }
12423        }
12424
12425        if (mIsolatedProcesses.size() > 0) {
12426            boolean printed = false;
12427            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12428                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12429                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12430                    continue;
12431                }
12432                if (!printed) {
12433                    if (needSep) {
12434                        pw.println();
12435                    }
12436                    pw.println("  Isolated process list (sorted by uid):");
12437                    printedAnything = true;
12438                    printed = true;
12439                    needSep = true;
12440                }
12441                pw.println(String.format("%sIsolated #%2d: %s",
12442                        "    ", i, r.toString()));
12443            }
12444        }
12445
12446        if (mLruProcesses.size() > 0) {
12447            if (needSep) {
12448                pw.println();
12449            }
12450            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12451                    pw.print(" total, non-act at ");
12452                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12453                    pw.print(", non-svc at ");
12454                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12455                    pw.println("):");
12456            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12457            needSep = true;
12458            printedAnything = true;
12459        }
12460
12461        if (dumpAll || dumpPackage != null) {
12462            synchronized (mPidsSelfLocked) {
12463                boolean printed = false;
12464                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12465                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12466                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12467                        continue;
12468                    }
12469                    if (!printed) {
12470                        if (needSep) pw.println();
12471                        needSep = true;
12472                        pw.println("  PID mappings:");
12473                        printed = true;
12474                        printedAnything = true;
12475                    }
12476                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12477                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12478                }
12479            }
12480        }
12481
12482        if (mForegroundProcesses.size() > 0) {
12483            synchronized (mPidsSelfLocked) {
12484                boolean printed = false;
12485                for (int i=0; i<mForegroundProcesses.size(); i++) {
12486                    ProcessRecord r = mPidsSelfLocked.get(
12487                            mForegroundProcesses.valueAt(i).pid);
12488                    if (dumpPackage != null && (r == null
12489                            || !r.pkgList.containsKey(dumpPackage))) {
12490                        continue;
12491                    }
12492                    if (!printed) {
12493                        if (needSep) pw.println();
12494                        needSep = true;
12495                        pw.println("  Foreground Processes:");
12496                        printed = true;
12497                        printedAnything = true;
12498                    }
12499                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12500                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12501                }
12502            }
12503        }
12504
12505        if (mPersistentStartingProcesses.size() > 0) {
12506            if (needSep) pw.println();
12507            needSep = true;
12508            printedAnything = true;
12509            pw.println("  Persisent processes that are starting:");
12510            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12511                    "Starting Norm", "Restarting PERS", dumpPackage);
12512        }
12513
12514        if (mRemovedProcesses.size() > 0) {
12515            if (needSep) pw.println();
12516            needSep = true;
12517            printedAnything = true;
12518            pw.println("  Processes that are being removed:");
12519            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12520                    "Removed Norm", "Removed PERS", dumpPackage);
12521        }
12522
12523        if (mProcessesOnHold.size() > 0) {
12524            if (needSep) pw.println();
12525            needSep = true;
12526            printedAnything = true;
12527            pw.println("  Processes that are on old until the system is ready:");
12528            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12529                    "OnHold Norm", "OnHold PERS", dumpPackage);
12530        }
12531
12532        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12533
12534        if (mProcessCrashTimes.getMap().size() > 0) {
12535            boolean printed = false;
12536            long now = SystemClock.uptimeMillis();
12537            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12538            final int NP = pmap.size();
12539            for (int ip=0; ip<NP; ip++) {
12540                String pname = pmap.keyAt(ip);
12541                SparseArray<Long> uids = pmap.valueAt(ip);
12542                final int N = uids.size();
12543                for (int i=0; i<N; i++) {
12544                    int puid = uids.keyAt(i);
12545                    ProcessRecord r = mProcessNames.get(pname, puid);
12546                    if (dumpPackage != null && (r == null
12547                            || !r.pkgList.containsKey(dumpPackage))) {
12548                        continue;
12549                    }
12550                    if (!printed) {
12551                        if (needSep) pw.println();
12552                        needSep = true;
12553                        pw.println("  Time since processes crashed:");
12554                        printed = true;
12555                        printedAnything = true;
12556                    }
12557                    pw.print("    Process "); pw.print(pname);
12558                            pw.print(" uid "); pw.print(puid);
12559                            pw.print(": last crashed ");
12560                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12561                            pw.println(" ago");
12562                }
12563            }
12564        }
12565
12566        if (mBadProcesses.getMap().size() > 0) {
12567            boolean printed = false;
12568            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12569            final int NP = pmap.size();
12570            for (int ip=0; ip<NP; ip++) {
12571                String pname = pmap.keyAt(ip);
12572                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12573                final int N = uids.size();
12574                for (int i=0; i<N; i++) {
12575                    int puid = uids.keyAt(i);
12576                    ProcessRecord r = mProcessNames.get(pname, puid);
12577                    if (dumpPackage != null && (r == null
12578                            || !r.pkgList.containsKey(dumpPackage))) {
12579                        continue;
12580                    }
12581                    if (!printed) {
12582                        if (needSep) pw.println();
12583                        needSep = true;
12584                        pw.println("  Bad processes:");
12585                        printedAnything = true;
12586                    }
12587                    BadProcessInfo info = uids.valueAt(i);
12588                    pw.print("    Bad process "); pw.print(pname);
12589                            pw.print(" uid "); pw.print(puid);
12590                            pw.print(": crashed at time "); pw.println(info.time);
12591                    if (info.shortMsg != null) {
12592                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12593                    }
12594                    if (info.longMsg != null) {
12595                        pw.print("      Long msg: "); pw.println(info.longMsg);
12596                    }
12597                    if (info.stack != null) {
12598                        pw.println("      Stack:");
12599                        int lastPos = 0;
12600                        for (int pos=0; pos<info.stack.length(); pos++) {
12601                            if (info.stack.charAt(pos) == '\n') {
12602                                pw.print("        ");
12603                                pw.write(info.stack, lastPos, pos-lastPos);
12604                                pw.println();
12605                                lastPos = pos+1;
12606                            }
12607                        }
12608                        if (lastPos < info.stack.length()) {
12609                            pw.print("        ");
12610                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12611                            pw.println();
12612                        }
12613                    }
12614                }
12615            }
12616        }
12617
12618        if (dumpPackage == null) {
12619            pw.println();
12620            needSep = false;
12621            pw.println("  mStartedUsers:");
12622            for (int i=0; i<mStartedUsers.size(); i++) {
12623                UserStartedState uss = mStartedUsers.valueAt(i);
12624                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12625                        pw.print(": "); uss.dump("", pw);
12626            }
12627            pw.print("  mStartedUserArray: [");
12628            for (int i=0; i<mStartedUserArray.length; i++) {
12629                if (i > 0) pw.print(", ");
12630                pw.print(mStartedUserArray[i]);
12631            }
12632            pw.println("]");
12633            pw.print("  mUserLru: [");
12634            for (int i=0; i<mUserLru.size(); i++) {
12635                if (i > 0) pw.print(", ");
12636                pw.print(mUserLru.get(i));
12637            }
12638            pw.println("]");
12639            if (dumpAll) {
12640                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12641            }
12642            synchronized (mUserProfileGroupIdsSelfLocked) {
12643                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12644                    pw.println("  mUserProfileGroupIds:");
12645                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12646                        pw.print("    User #");
12647                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12648                        pw.print(" -> profile #");
12649                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12650                    }
12651                }
12652            }
12653        }
12654        if (mHomeProcess != null && (dumpPackage == null
12655                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12656            if (needSep) {
12657                pw.println();
12658                needSep = false;
12659            }
12660            pw.println("  mHomeProcess: " + mHomeProcess);
12661        }
12662        if (mPreviousProcess != null && (dumpPackage == null
12663                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12664            if (needSep) {
12665                pw.println();
12666                needSep = false;
12667            }
12668            pw.println("  mPreviousProcess: " + mPreviousProcess);
12669        }
12670        if (dumpAll) {
12671            StringBuilder sb = new StringBuilder(128);
12672            sb.append("  mPreviousProcessVisibleTime: ");
12673            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12674            pw.println(sb);
12675        }
12676        if (mHeavyWeightProcess != null && (dumpPackage == null
12677                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12678            if (needSep) {
12679                pw.println();
12680                needSep = false;
12681            }
12682            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12683        }
12684        if (dumpPackage == null) {
12685            pw.println("  mConfiguration: " + mConfiguration);
12686        }
12687        if (dumpAll) {
12688            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12689            if (mCompatModePackages.getPackages().size() > 0) {
12690                boolean printed = false;
12691                for (Map.Entry<String, Integer> entry
12692                        : mCompatModePackages.getPackages().entrySet()) {
12693                    String pkg = entry.getKey();
12694                    int mode = entry.getValue();
12695                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12696                        continue;
12697                    }
12698                    if (!printed) {
12699                        pw.println("  mScreenCompatPackages:");
12700                        printed = true;
12701                    }
12702                    pw.print("    "); pw.print(pkg); pw.print(": ");
12703                            pw.print(mode); pw.println();
12704                }
12705            }
12706        }
12707        if (dumpPackage == null) {
12708            if (mSleeping || mWentToSleep || mLockScreenShown) {
12709                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12710                        + " mLockScreenShown " + mLockScreenShown);
12711            }
12712            if (mShuttingDown || mRunningVoice) {
12713                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12714            }
12715        }
12716        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12717                || mOrigWaitForDebugger) {
12718            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12719                    || dumpPackage.equals(mOrigDebugApp)) {
12720                if (needSep) {
12721                    pw.println();
12722                    needSep = false;
12723                }
12724                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12725                        + " mDebugTransient=" + mDebugTransient
12726                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12727            }
12728        }
12729        if (mOpenGlTraceApp != null) {
12730            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12731                if (needSep) {
12732                    pw.println();
12733                    needSep = false;
12734                }
12735                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12736            }
12737        }
12738        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12739                || mProfileFd != null) {
12740            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12741                if (needSep) {
12742                    pw.println();
12743                    needSep = false;
12744                }
12745                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12746                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12747                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12748                        + mAutoStopProfiler);
12749                pw.println("  mProfileType=" + mProfileType);
12750            }
12751        }
12752        if (dumpPackage == null) {
12753            if (mAlwaysFinishActivities || mController != null) {
12754                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12755                        + " mController=" + mController);
12756            }
12757            if (dumpAll) {
12758                pw.println("  Total persistent processes: " + numPers);
12759                pw.println("  mProcessesReady=" + mProcessesReady
12760                        + " mSystemReady=" + mSystemReady);
12761                pw.println("  mBooting=" + mBooting
12762                        + " mBooted=" + mBooted
12763                        + " mFactoryTest=" + mFactoryTest);
12764                pw.print("  mLastPowerCheckRealtime=");
12765                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12766                        pw.println("");
12767                pw.print("  mLastPowerCheckUptime=");
12768                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12769                        pw.println("");
12770                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12771                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12772                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12773                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12774                        + " (" + mLruProcesses.size() + " total)"
12775                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12776                        + " mNumServiceProcs=" + mNumServiceProcs
12777                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12778                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12779                        + " mLastMemoryLevel" + mLastMemoryLevel
12780                        + " mLastNumProcesses" + mLastNumProcesses);
12781                long now = SystemClock.uptimeMillis();
12782                pw.print("  mLastIdleTime=");
12783                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12784                        pw.print(" mLowRamSinceLastIdle=");
12785                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12786                        pw.println();
12787            }
12788        }
12789
12790        if (!printedAnything) {
12791            pw.println("  (nothing)");
12792        }
12793    }
12794
12795    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12796            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12797        if (mProcessesToGc.size() > 0) {
12798            boolean printed = false;
12799            long now = SystemClock.uptimeMillis();
12800            for (int i=0; i<mProcessesToGc.size(); i++) {
12801                ProcessRecord proc = mProcessesToGc.get(i);
12802                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12803                    continue;
12804                }
12805                if (!printed) {
12806                    if (needSep) pw.println();
12807                    needSep = true;
12808                    pw.println("  Processes that are waiting to GC:");
12809                    printed = true;
12810                }
12811                pw.print("    Process "); pw.println(proc);
12812                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12813                        pw.print(", last gced=");
12814                        pw.print(now-proc.lastRequestedGc);
12815                        pw.print(" ms ago, last lowMem=");
12816                        pw.print(now-proc.lastLowMemory);
12817                        pw.println(" ms ago");
12818
12819            }
12820        }
12821        return needSep;
12822    }
12823
12824    void printOomLevel(PrintWriter pw, String name, int adj) {
12825        pw.print("    ");
12826        if (adj >= 0) {
12827            pw.print(' ');
12828            if (adj < 10) pw.print(' ');
12829        } else {
12830            if (adj > -10) pw.print(' ');
12831        }
12832        pw.print(adj);
12833        pw.print(": ");
12834        pw.print(name);
12835        pw.print(" (");
12836        pw.print(mProcessList.getMemLevel(adj)/1024);
12837        pw.println(" kB)");
12838    }
12839
12840    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12841            int opti, boolean dumpAll) {
12842        boolean needSep = false;
12843
12844        if (mLruProcesses.size() > 0) {
12845            if (needSep) pw.println();
12846            needSep = true;
12847            pw.println("  OOM levels:");
12848            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12849            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12850            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12851            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12852            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12853            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12854            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12855            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12856            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12857            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12858            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12859            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12860            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12861
12862            if (needSep) pw.println();
12863            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12864                    pw.print(" total, non-act at ");
12865                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12866                    pw.print(", non-svc at ");
12867                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12868                    pw.println("):");
12869            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12870            needSep = true;
12871        }
12872
12873        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12874
12875        pw.println();
12876        pw.println("  mHomeProcess: " + mHomeProcess);
12877        pw.println("  mPreviousProcess: " + mPreviousProcess);
12878        if (mHeavyWeightProcess != null) {
12879            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12880        }
12881
12882        return true;
12883    }
12884
12885    /**
12886     * There are three ways to call this:
12887     *  - no provider specified: dump all the providers
12888     *  - a flattened component name that matched an existing provider was specified as the
12889     *    first arg: dump that one provider
12890     *  - the first arg isn't the flattened component name of an existing provider:
12891     *    dump all providers whose component contains the first arg as a substring
12892     */
12893    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12894            int opti, boolean dumpAll) {
12895        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12896    }
12897
12898    static class ItemMatcher {
12899        ArrayList<ComponentName> components;
12900        ArrayList<String> strings;
12901        ArrayList<Integer> objects;
12902        boolean all;
12903
12904        ItemMatcher() {
12905            all = true;
12906        }
12907
12908        void build(String name) {
12909            ComponentName componentName = ComponentName.unflattenFromString(name);
12910            if (componentName != null) {
12911                if (components == null) {
12912                    components = new ArrayList<ComponentName>();
12913                }
12914                components.add(componentName);
12915                all = false;
12916            } else {
12917                int objectId = 0;
12918                // Not a '/' separated full component name; maybe an object ID?
12919                try {
12920                    objectId = Integer.parseInt(name, 16);
12921                    if (objects == null) {
12922                        objects = new ArrayList<Integer>();
12923                    }
12924                    objects.add(objectId);
12925                    all = false;
12926                } catch (RuntimeException e) {
12927                    // Not an integer; just do string match.
12928                    if (strings == null) {
12929                        strings = new ArrayList<String>();
12930                    }
12931                    strings.add(name);
12932                    all = false;
12933                }
12934            }
12935        }
12936
12937        int build(String[] args, int opti) {
12938            for (; opti<args.length; opti++) {
12939                String name = args[opti];
12940                if ("--".equals(name)) {
12941                    return opti+1;
12942                }
12943                build(name);
12944            }
12945            return opti;
12946        }
12947
12948        boolean match(Object object, ComponentName comp) {
12949            if (all) {
12950                return true;
12951            }
12952            if (components != null) {
12953                for (int i=0; i<components.size(); i++) {
12954                    if (components.get(i).equals(comp)) {
12955                        return true;
12956                    }
12957                }
12958            }
12959            if (objects != null) {
12960                for (int i=0; i<objects.size(); i++) {
12961                    if (System.identityHashCode(object) == objects.get(i)) {
12962                        return true;
12963                    }
12964                }
12965            }
12966            if (strings != null) {
12967                String flat = comp.flattenToString();
12968                for (int i=0; i<strings.size(); i++) {
12969                    if (flat.contains(strings.get(i))) {
12970                        return true;
12971                    }
12972                }
12973            }
12974            return false;
12975        }
12976    }
12977
12978    /**
12979     * There are three things that cmd can be:
12980     *  - a flattened component name that matches an existing activity
12981     *  - the cmd arg isn't the flattened component name of an existing activity:
12982     *    dump all activity whose component contains the cmd as a substring
12983     *  - A hex number of the ActivityRecord object instance.
12984     */
12985    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12986            int opti, boolean dumpAll) {
12987        ArrayList<ActivityRecord> activities;
12988
12989        synchronized (this) {
12990            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12991        }
12992
12993        if (activities.size() <= 0) {
12994            return false;
12995        }
12996
12997        String[] newArgs = new String[args.length - opti];
12998        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12999
13000        TaskRecord lastTask = null;
13001        boolean needSep = false;
13002        for (int i=activities.size()-1; i>=0; i--) {
13003            ActivityRecord r = activities.get(i);
13004            if (needSep) {
13005                pw.println();
13006            }
13007            needSep = true;
13008            synchronized (this) {
13009                if (lastTask != r.task) {
13010                    lastTask = r.task;
13011                    pw.print("TASK "); pw.print(lastTask.affinity);
13012                            pw.print(" id="); pw.println(lastTask.taskId);
13013                    if (dumpAll) {
13014                        lastTask.dump(pw, "  ");
13015                    }
13016                }
13017            }
13018            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13019        }
13020        return true;
13021    }
13022
13023    /**
13024     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13025     * there is a thread associated with the activity.
13026     */
13027    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13028            final ActivityRecord r, String[] args, boolean dumpAll) {
13029        String innerPrefix = prefix + "  ";
13030        synchronized (this) {
13031            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13032                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13033                    pw.print(" pid=");
13034                    if (r.app != null) pw.println(r.app.pid);
13035                    else pw.println("(not running)");
13036            if (dumpAll) {
13037                r.dump(pw, innerPrefix);
13038            }
13039        }
13040        if (r.app != null && r.app.thread != null) {
13041            // flush anything that is already in the PrintWriter since the thread is going
13042            // to write to the file descriptor directly
13043            pw.flush();
13044            try {
13045                TransferPipe tp = new TransferPipe();
13046                try {
13047                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13048                            r.appToken, innerPrefix, args);
13049                    tp.go(fd);
13050                } finally {
13051                    tp.kill();
13052                }
13053            } catch (IOException e) {
13054                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13055            } catch (RemoteException e) {
13056                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13057            }
13058        }
13059    }
13060
13061    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13062            int opti, boolean dumpAll, String dumpPackage) {
13063        boolean needSep = false;
13064        boolean onlyHistory = false;
13065        boolean printedAnything = false;
13066
13067        if ("history".equals(dumpPackage)) {
13068            if (opti < args.length && "-s".equals(args[opti])) {
13069                dumpAll = false;
13070            }
13071            onlyHistory = true;
13072            dumpPackage = null;
13073        }
13074
13075        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13076        if (!onlyHistory && dumpAll) {
13077            if (mRegisteredReceivers.size() > 0) {
13078                boolean printed = false;
13079                Iterator it = mRegisteredReceivers.values().iterator();
13080                while (it.hasNext()) {
13081                    ReceiverList r = (ReceiverList)it.next();
13082                    if (dumpPackage != null && (r.app == null ||
13083                            !dumpPackage.equals(r.app.info.packageName))) {
13084                        continue;
13085                    }
13086                    if (!printed) {
13087                        pw.println("  Registered Receivers:");
13088                        needSep = true;
13089                        printed = true;
13090                        printedAnything = true;
13091                    }
13092                    pw.print("  * "); pw.println(r);
13093                    r.dump(pw, "    ");
13094                }
13095            }
13096
13097            if (mReceiverResolver.dump(pw, needSep ?
13098                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13099                    "    ", dumpPackage, false)) {
13100                needSep = true;
13101                printedAnything = true;
13102            }
13103        }
13104
13105        for (BroadcastQueue q : mBroadcastQueues) {
13106            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13107            printedAnything |= needSep;
13108        }
13109
13110        needSep = true;
13111
13112        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13113            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13114                if (needSep) {
13115                    pw.println();
13116                }
13117                needSep = true;
13118                printedAnything = true;
13119                pw.print("  Sticky broadcasts for user ");
13120                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13121                StringBuilder sb = new StringBuilder(128);
13122                for (Map.Entry<String, ArrayList<Intent>> ent
13123                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13124                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13125                    if (dumpAll) {
13126                        pw.println(":");
13127                        ArrayList<Intent> intents = ent.getValue();
13128                        final int N = intents.size();
13129                        for (int i=0; i<N; i++) {
13130                            sb.setLength(0);
13131                            sb.append("    Intent: ");
13132                            intents.get(i).toShortString(sb, false, true, false, false);
13133                            pw.println(sb.toString());
13134                            Bundle bundle = intents.get(i).getExtras();
13135                            if (bundle != null) {
13136                                pw.print("      ");
13137                                pw.println(bundle.toString());
13138                            }
13139                        }
13140                    } else {
13141                        pw.println("");
13142                    }
13143                }
13144            }
13145        }
13146
13147        if (!onlyHistory && dumpAll) {
13148            pw.println();
13149            for (BroadcastQueue queue : mBroadcastQueues) {
13150                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13151                        + queue.mBroadcastsScheduled);
13152            }
13153            pw.println("  mHandler:");
13154            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13155            needSep = true;
13156            printedAnything = true;
13157        }
13158
13159        if (!printedAnything) {
13160            pw.println("  (nothing)");
13161        }
13162    }
13163
13164    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13165            int opti, boolean dumpAll, String dumpPackage) {
13166        boolean needSep;
13167        boolean printedAnything = false;
13168
13169        ItemMatcher matcher = new ItemMatcher();
13170        matcher.build(args, opti);
13171
13172        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13173
13174        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13175        printedAnything |= needSep;
13176
13177        if (mLaunchingProviders.size() > 0) {
13178            boolean printed = false;
13179            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13180                ContentProviderRecord r = mLaunchingProviders.get(i);
13181                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13182                    continue;
13183                }
13184                if (!printed) {
13185                    if (needSep) pw.println();
13186                    needSep = true;
13187                    pw.println("  Launching content providers:");
13188                    printed = true;
13189                    printedAnything = true;
13190                }
13191                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13192                        pw.println(r);
13193            }
13194        }
13195
13196        if (mGrantedUriPermissions.size() > 0) {
13197            boolean printed = false;
13198            int dumpUid = -2;
13199            if (dumpPackage != null) {
13200                try {
13201                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13202                } catch (NameNotFoundException e) {
13203                    dumpUid = -1;
13204                }
13205            }
13206            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13207                int uid = mGrantedUriPermissions.keyAt(i);
13208                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13209                    continue;
13210                }
13211                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13212                if (!printed) {
13213                    if (needSep) pw.println();
13214                    needSep = true;
13215                    pw.println("  Granted Uri Permissions:");
13216                    printed = true;
13217                    printedAnything = true;
13218                }
13219                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13220                for (UriPermission perm : perms.values()) {
13221                    pw.print("    "); pw.println(perm);
13222                    if (dumpAll) {
13223                        perm.dump(pw, "      ");
13224                    }
13225                }
13226            }
13227        }
13228
13229        if (!printedAnything) {
13230            pw.println("  (nothing)");
13231        }
13232    }
13233
13234    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13235            int opti, boolean dumpAll, String dumpPackage) {
13236        boolean printed = false;
13237
13238        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13239
13240        if (mIntentSenderRecords.size() > 0) {
13241            Iterator<WeakReference<PendingIntentRecord>> it
13242                    = mIntentSenderRecords.values().iterator();
13243            while (it.hasNext()) {
13244                WeakReference<PendingIntentRecord> ref = it.next();
13245                PendingIntentRecord rec = ref != null ? ref.get(): null;
13246                if (dumpPackage != null && (rec == null
13247                        || !dumpPackage.equals(rec.key.packageName))) {
13248                    continue;
13249                }
13250                printed = true;
13251                if (rec != null) {
13252                    pw.print("  * "); pw.println(rec);
13253                    if (dumpAll) {
13254                        rec.dump(pw, "    ");
13255                    }
13256                } else {
13257                    pw.print("  * "); pw.println(ref);
13258                }
13259            }
13260        }
13261
13262        if (!printed) {
13263            pw.println("  (nothing)");
13264        }
13265    }
13266
13267    private static final int dumpProcessList(PrintWriter pw,
13268            ActivityManagerService service, List list,
13269            String prefix, String normalLabel, String persistentLabel,
13270            String dumpPackage) {
13271        int numPers = 0;
13272        final int N = list.size()-1;
13273        for (int i=N; i>=0; i--) {
13274            ProcessRecord r = (ProcessRecord)list.get(i);
13275            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13276                continue;
13277            }
13278            pw.println(String.format("%s%s #%2d: %s",
13279                    prefix, (r.persistent ? persistentLabel : normalLabel),
13280                    i, r.toString()));
13281            if (r.persistent) {
13282                numPers++;
13283            }
13284        }
13285        return numPers;
13286    }
13287
13288    private static final boolean dumpProcessOomList(PrintWriter pw,
13289            ActivityManagerService service, List<ProcessRecord> origList,
13290            String prefix, String normalLabel, String persistentLabel,
13291            boolean inclDetails, String dumpPackage) {
13292
13293        ArrayList<Pair<ProcessRecord, Integer>> list
13294                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13295        for (int i=0; i<origList.size(); i++) {
13296            ProcessRecord r = origList.get(i);
13297            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13298                continue;
13299            }
13300            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13301        }
13302
13303        if (list.size() <= 0) {
13304            return false;
13305        }
13306
13307        Comparator<Pair<ProcessRecord, Integer>> comparator
13308                = new Comparator<Pair<ProcessRecord, Integer>>() {
13309            @Override
13310            public int compare(Pair<ProcessRecord, Integer> object1,
13311                    Pair<ProcessRecord, Integer> object2) {
13312                if (object1.first.setAdj != object2.first.setAdj) {
13313                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13314                }
13315                if (object1.second.intValue() != object2.second.intValue()) {
13316                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13317                }
13318                return 0;
13319            }
13320        };
13321
13322        Collections.sort(list, comparator);
13323
13324        final long curRealtime = SystemClock.elapsedRealtime();
13325        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13326        final long curUptime = SystemClock.uptimeMillis();
13327        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13328
13329        for (int i=list.size()-1; i>=0; i--) {
13330            ProcessRecord r = list.get(i).first;
13331            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13332            char schedGroup;
13333            switch (r.setSchedGroup) {
13334                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13335                    schedGroup = 'B';
13336                    break;
13337                case Process.THREAD_GROUP_DEFAULT:
13338                    schedGroup = 'F';
13339                    break;
13340                default:
13341                    schedGroup = '?';
13342                    break;
13343            }
13344            char foreground;
13345            if (r.foregroundActivities) {
13346                foreground = 'A';
13347            } else if (r.foregroundServices) {
13348                foreground = 'S';
13349            } else {
13350                foreground = ' ';
13351            }
13352            String procState = ProcessList.makeProcStateString(r.curProcState);
13353            pw.print(prefix);
13354            pw.print(r.persistent ? persistentLabel : normalLabel);
13355            pw.print(" #");
13356            int num = (origList.size()-1)-list.get(i).second;
13357            if (num < 10) pw.print(' ');
13358            pw.print(num);
13359            pw.print(": ");
13360            pw.print(oomAdj);
13361            pw.print(' ');
13362            pw.print(schedGroup);
13363            pw.print('/');
13364            pw.print(foreground);
13365            pw.print('/');
13366            pw.print(procState);
13367            pw.print(" trm:");
13368            if (r.trimMemoryLevel < 10) pw.print(' ');
13369            pw.print(r.trimMemoryLevel);
13370            pw.print(' ');
13371            pw.print(r.toShortString());
13372            pw.print(" (");
13373            pw.print(r.adjType);
13374            pw.println(')');
13375            if (r.adjSource != null || r.adjTarget != null) {
13376                pw.print(prefix);
13377                pw.print("    ");
13378                if (r.adjTarget instanceof ComponentName) {
13379                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13380                } else if (r.adjTarget != null) {
13381                    pw.print(r.adjTarget.toString());
13382                } else {
13383                    pw.print("{null}");
13384                }
13385                pw.print("<=");
13386                if (r.adjSource instanceof ProcessRecord) {
13387                    pw.print("Proc{");
13388                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13389                    pw.println("}");
13390                } else if (r.adjSource != null) {
13391                    pw.println(r.adjSource.toString());
13392                } else {
13393                    pw.println("{null}");
13394                }
13395            }
13396            if (inclDetails) {
13397                pw.print(prefix);
13398                pw.print("    ");
13399                pw.print("oom: max="); pw.print(r.maxAdj);
13400                pw.print(" curRaw="); pw.print(r.curRawAdj);
13401                pw.print(" setRaw="); pw.print(r.setRawAdj);
13402                pw.print(" cur="); pw.print(r.curAdj);
13403                pw.print(" set="); pw.println(r.setAdj);
13404                pw.print(prefix);
13405                pw.print("    ");
13406                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13407                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13408                pw.print(" lastPss="); pw.print(r.lastPss);
13409                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13410                pw.print(prefix);
13411                pw.print("    ");
13412                pw.print("cached="); pw.print(r.cached);
13413                pw.print(" empty="); pw.print(r.empty);
13414                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13415
13416                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13417                    if (r.lastWakeTime != 0) {
13418                        long wtime;
13419                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13420                        synchronized (stats) {
13421                            wtime = stats.getProcessWakeTime(r.info.uid,
13422                                    r.pid, curRealtime);
13423                        }
13424                        long timeUsed = wtime - r.lastWakeTime;
13425                        pw.print(prefix);
13426                        pw.print("    ");
13427                        pw.print("keep awake over ");
13428                        TimeUtils.formatDuration(realtimeSince, pw);
13429                        pw.print(" used ");
13430                        TimeUtils.formatDuration(timeUsed, pw);
13431                        pw.print(" (");
13432                        pw.print((timeUsed*100)/realtimeSince);
13433                        pw.println("%)");
13434                    }
13435                    if (r.lastCpuTime != 0) {
13436                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13437                        pw.print(prefix);
13438                        pw.print("    ");
13439                        pw.print("run cpu over ");
13440                        TimeUtils.formatDuration(uptimeSince, pw);
13441                        pw.print(" used ");
13442                        TimeUtils.formatDuration(timeUsed, pw);
13443                        pw.print(" (");
13444                        pw.print((timeUsed*100)/uptimeSince);
13445                        pw.println("%)");
13446                    }
13447                }
13448            }
13449        }
13450        return true;
13451    }
13452
13453    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13454        ArrayList<ProcessRecord> procs;
13455        synchronized (this) {
13456            if (args != null && args.length > start
13457                    && args[start].charAt(0) != '-') {
13458                procs = new ArrayList<ProcessRecord>();
13459                int pid = -1;
13460                try {
13461                    pid = Integer.parseInt(args[start]);
13462                } catch (NumberFormatException e) {
13463                }
13464                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13465                    ProcessRecord proc = mLruProcesses.get(i);
13466                    if (proc.pid == pid) {
13467                        procs.add(proc);
13468                    } else if (proc.processName.equals(args[start])) {
13469                        procs.add(proc);
13470                    }
13471                }
13472                if (procs.size() <= 0) {
13473                    return null;
13474                }
13475            } else {
13476                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13477            }
13478        }
13479        return procs;
13480    }
13481
13482    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13483            PrintWriter pw, String[] args) {
13484        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13485        if (procs == null) {
13486            pw.println("No process found for: " + args[0]);
13487            return;
13488        }
13489
13490        long uptime = SystemClock.uptimeMillis();
13491        long realtime = SystemClock.elapsedRealtime();
13492        pw.println("Applications Graphics Acceleration Info:");
13493        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13494
13495        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13496            ProcessRecord r = procs.get(i);
13497            if (r.thread != null) {
13498                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13499                pw.flush();
13500                try {
13501                    TransferPipe tp = new TransferPipe();
13502                    try {
13503                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13504                        tp.go(fd);
13505                    } finally {
13506                        tp.kill();
13507                    }
13508                } catch (IOException e) {
13509                    pw.println("Failure while dumping the app: " + r);
13510                    pw.flush();
13511                } catch (RemoteException e) {
13512                    pw.println("Got a RemoteException while dumping the app " + r);
13513                    pw.flush();
13514                }
13515            }
13516        }
13517    }
13518
13519    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13520        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13521        if (procs == null) {
13522            pw.println("No process found for: " + args[0]);
13523            return;
13524        }
13525
13526        pw.println("Applications Database Info:");
13527
13528        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13529            ProcessRecord r = procs.get(i);
13530            if (r.thread != null) {
13531                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13532                pw.flush();
13533                try {
13534                    TransferPipe tp = new TransferPipe();
13535                    try {
13536                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13537                        tp.go(fd);
13538                    } finally {
13539                        tp.kill();
13540                    }
13541                } catch (IOException e) {
13542                    pw.println("Failure while dumping the app: " + r);
13543                    pw.flush();
13544                } catch (RemoteException e) {
13545                    pw.println("Got a RemoteException while dumping the app " + r);
13546                    pw.flush();
13547                }
13548            }
13549        }
13550    }
13551
13552    final static class MemItem {
13553        final boolean isProc;
13554        final String label;
13555        final String shortLabel;
13556        final long pss;
13557        final int id;
13558        final boolean hasActivities;
13559        ArrayList<MemItem> subitems;
13560
13561        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13562                boolean _hasActivities) {
13563            isProc = true;
13564            label = _label;
13565            shortLabel = _shortLabel;
13566            pss = _pss;
13567            id = _id;
13568            hasActivities = _hasActivities;
13569        }
13570
13571        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13572            isProc = false;
13573            label = _label;
13574            shortLabel = _shortLabel;
13575            pss = _pss;
13576            id = _id;
13577            hasActivities = false;
13578        }
13579    }
13580
13581    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13582            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13583        if (sort && !isCompact) {
13584            Collections.sort(items, new Comparator<MemItem>() {
13585                @Override
13586                public int compare(MemItem lhs, MemItem rhs) {
13587                    if (lhs.pss < rhs.pss) {
13588                        return 1;
13589                    } else if (lhs.pss > rhs.pss) {
13590                        return -1;
13591                    }
13592                    return 0;
13593                }
13594            });
13595        }
13596
13597        for (int i=0; i<items.size(); i++) {
13598            MemItem mi = items.get(i);
13599            if (!isCompact) {
13600                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13601            } else if (mi.isProc) {
13602                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13603                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13604                pw.println(mi.hasActivities ? ",a" : ",e");
13605            } else {
13606                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13607                pw.println(mi.pss);
13608            }
13609            if (mi.subitems != null) {
13610                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13611                        true, isCompact);
13612            }
13613        }
13614    }
13615
13616    // These are in KB.
13617    static final long[] DUMP_MEM_BUCKETS = new long[] {
13618        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13619        120*1024, 160*1024, 200*1024,
13620        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13621        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13622    };
13623
13624    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13625            boolean stackLike) {
13626        int start = label.lastIndexOf('.');
13627        if (start >= 0) start++;
13628        else start = 0;
13629        int end = label.length();
13630        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13631            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13632                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13633                out.append(bucket);
13634                out.append(stackLike ? "MB." : "MB ");
13635                out.append(label, start, end);
13636                return;
13637            }
13638        }
13639        out.append(memKB/1024);
13640        out.append(stackLike ? "MB." : "MB ");
13641        out.append(label, start, end);
13642    }
13643
13644    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13645            ProcessList.NATIVE_ADJ,
13646            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13647            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13648            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13649            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13650            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13651    };
13652    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13653            "Native",
13654            "System", "Persistent", "Foreground",
13655            "Visible", "Perceptible",
13656            "Heavy Weight", "Backup",
13657            "A Services", "Home",
13658            "Previous", "B Services", "Cached"
13659    };
13660    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13661            "native",
13662            "sys", "pers", "fore",
13663            "vis", "percept",
13664            "heavy", "backup",
13665            "servicea", "home",
13666            "prev", "serviceb", "cached"
13667    };
13668
13669    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13670            long realtime, boolean isCheckinRequest, boolean isCompact) {
13671        if (isCheckinRequest || isCompact) {
13672            // short checkin version
13673            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13674        } else {
13675            pw.println("Applications Memory Usage (kB):");
13676            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13677        }
13678    }
13679
13680    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13681            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13682        boolean dumpDetails = false;
13683        boolean dumpFullDetails = false;
13684        boolean dumpDalvik = false;
13685        boolean oomOnly = false;
13686        boolean isCompact = false;
13687        boolean localOnly = false;
13688
13689        int opti = 0;
13690        while (opti < args.length) {
13691            String opt = args[opti];
13692            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13693                break;
13694            }
13695            opti++;
13696            if ("-a".equals(opt)) {
13697                dumpDetails = true;
13698                dumpFullDetails = true;
13699                dumpDalvik = true;
13700            } else if ("-d".equals(opt)) {
13701                dumpDalvik = true;
13702            } else if ("-c".equals(opt)) {
13703                isCompact = true;
13704            } else if ("--oom".equals(opt)) {
13705                oomOnly = true;
13706            } else if ("--local".equals(opt)) {
13707                localOnly = true;
13708            } else if ("-h".equals(opt)) {
13709                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13710                pw.println("  -a: include all available information for each process.");
13711                pw.println("  -d: include dalvik details when dumping process details.");
13712                pw.println("  -c: dump in a compact machine-parseable representation.");
13713                pw.println("  --oom: only show processes organized by oom adj.");
13714                pw.println("  --local: only collect details locally, don't call process.");
13715                pw.println("If [process] is specified it can be the name or ");
13716                pw.println("pid of a specific process to dump.");
13717                return;
13718            } else {
13719                pw.println("Unknown argument: " + opt + "; use -h for help");
13720            }
13721        }
13722
13723        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13724        long uptime = SystemClock.uptimeMillis();
13725        long realtime = SystemClock.elapsedRealtime();
13726        final long[] tmpLong = new long[1];
13727
13728        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13729        if (procs == null) {
13730            // No Java processes.  Maybe they want to print a native process.
13731            if (args != null && args.length > opti
13732                    && args[opti].charAt(0) != '-') {
13733                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13734                        = new ArrayList<ProcessCpuTracker.Stats>();
13735                updateCpuStatsNow();
13736                int findPid = -1;
13737                try {
13738                    findPid = Integer.parseInt(args[opti]);
13739                } catch (NumberFormatException e) {
13740                }
13741                synchronized (mProcessCpuThread) {
13742                    final int N = mProcessCpuTracker.countStats();
13743                    for (int i=0; i<N; i++) {
13744                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13745                        if (st.pid == findPid || (st.baseName != null
13746                                && st.baseName.equals(args[opti]))) {
13747                            nativeProcs.add(st);
13748                        }
13749                    }
13750                }
13751                if (nativeProcs.size() > 0) {
13752                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13753                            isCompact);
13754                    Debug.MemoryInfo mi = null;
13755                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13756                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13757                        final int pid = r.pid;
13758                        if (!isCheckinRequest && dumpDetails) {
13759                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13760                        }
13761                        if (mi == null) {
13762                            mi = new Debug.MemoryInfo();
13763                        }
13764                        if (dumpDetails || (!brief && !oomOnly)) {
13765                            Debug.getMemoryInfo(pid, mi);
13766                        } else {
13767                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13768                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13769                        }
13770                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13771                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13772                        if (isCheckinRequest) {
13773                            pw.println();
13774                        }
13775                    }
13776                    return;
13777                }
13778            }
13779            pw.println("No process found for: " + args[opti]);
13780            return;
13781        }
13782
13783        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13784            dumpDetails = true;
13785        }
13786
13787        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13788
13789        String[] innerArgs = new String[args.length-opti];
13790        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13791
13792        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13793        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13794        long nativePss=0, dalvikPss=0, otherPss=0;
13795        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13796
13797        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13798        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13799                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13800
13801        long totalPss = 0;
13802        long cachedPss = 0;
13803
13804        Debug.MemoryInfo mi = null;
13805        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13806            final ProcessRecord r = procs.get(i);
13807            final IApplicationThread thread;
13808            final int pid;
13809            final int oomAdj;
13810            final boolean hasActivities;
13811            synchronized (this) {
13812                thread = r.thread;
13813                pid = r.pid;
13814                oomAdj = r.getSetAdjWithServices();
13815                hasActivities = r.activities.size() > 0;
13816            }
13817            if (thread != null) {
13818                if (!isCheckinRequest && dumpDetails) {
13819                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13820                }
13821                if (mi == null) {
13822                    mi = new Debug.MemoryInfo();
13823                }
13824                if (dumpDetails || (!brief && !oomOnly)) {
13825                    Debug.getMemoryInfo(pid, mi);
13826                } else {
13827                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13828                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13829                }
13830                if (dumpDetails) {
13831                    if (localOnly) {
13832                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13833                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13834                        if (isCheckinRequest) {
13835                            pw.println();
13836                        }
13837                    } else {
13838                        try {
13839                            pw.flush();
13840                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13841                                    dumpDalvik, innerArgs);
13842                        } catch (RemoteException e) {
13843                            if (!isCheckinRequest) {
13844                                pw.println("Got RemoteException!");
13845                                pw.flush();
13846                            }
13847                        }
13848                    }
13849                }
13850
13851                final long myTotalPss = mi.getTotalPss();
13852                final long myTotalUss = mi.getTotalUss();
13853
13854                synchronized (this) {
13855                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13856                        // Record this for posterity if the process has been stable.
13857                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13858                    }
13859                }
13860
13861                if (!isCheckinRequest && mi != null) {
13862                    totalPss += myTotalPss;
13863                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13864                            (hasActivities ? " / activities)" : ")"),
13865                            r.processName, myTotalPss, pid, hasActivities);
13866                    procMems.add(pssItem);
13867                    procMemsMap.put(pid, pssItem);
13868
13869                    nativePss += mi.nativePss;
13870                    dalvikPss += mi.dalvikPss;
13871                    otherPss += mi.otherPss;
13872                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13873                        long mem = mi.getOtherPss(j);
13874                        miscPss[j] += mem;
13875                        otherPss -= mem;
13876                    }
13877
13878                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13879                        cachedPss += myTotalPss;
13880                    }
13881
13882                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13883                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13884                                || oomIndex == (oomPss.length-1)) {
13885                            oomPss[oomIndex] += myTotalPss;
13886                            if (oomProcs[oomIndex] == null) {
13887                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13888                            }
13889                            oomProcs[oomIndex].add(pssItem);
13890                            break;
13891                        }
13892                    }
13893                }
13894            }
13895        }
13896
13897        long nativeProcTotalPss = 0;
13898
13899        if (!isCheckinRequest && procs.size() > 1) {
13900            // If we are showing aggregations, also look for native processes to
13901            // include so that our aggregations are more accurate.
13902            updateCpuStatsNow();
13903            synchronized (mProcessCpuThread) {
13904                final int N = mProcessCpuTracker.countStats();
13905                for (int i=0; i<N; i++) {
13906                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13907                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13908                        if (mi == null) {
13909                            mi = new Debug.MemoryInfo();
13910                        }
13911                        if (!brief && !oomOnly) {
13912                            Debug.getMemoryInfo(st.pid, mi);
13913                        } else {
13914                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13915                            mi.nativePrivateDirty = (int)tmpLong[0];
13916                        }
13917
13918                        final long myTotalPss = mi.getTotalPss();
13919                        totalPss += myTotalPss;
13920                        nativeProcTotalPss += myTotalPss;
13921
13922                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13923                                st.name, myTotalPss, st.pid, false);
13924                        procMems.add(pssItem);
13925
13926                        nativePss += mi.nativePss;
13927                        dalvikPss += mi.dalvikPss;
13928                        otherPss += mi.otherPss;
13929                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13930                            long mem = mi.getOtherPss(j);
13931                            miscPss[j] += mem;
13932                            otherPss -= mem;
13933                        }
13934                        oomPss[0] += myTotalPss;
13935                        if (oomProcs[0] == null) {
13936                            oomProcs[0] = new ArrayList<MemItem>();
13937                        }
13938                        oomProcs[0].add(pssItem);
13939                    }
13940                }
13941            }
13942
13943            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13944
13945            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13946            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13947            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13948            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13949                String label = Debug.MemoryInfo.getOtherLabel(j);
13950                catMems.add(new MemItem(label, label, miscPss[j], j));
13951            }
13952
13953            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13954            for (int j=0; j<oomPss.length; j++) {
13955                if (oomPss[j] != 0) {
13956                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13957                            : DUMP_MEM_OOM_LABEL[j];
13958                    MemItem item = new MemItem(label, label, oomPss[j],
13959                            DUMP_MEM_OOM_ADJ[j]);
13960                    item.subitems = oomProcs[j];
13961                    oomMems.add(item);
13962                }
13963            }
13964
13965            if (!brief && !oomOnly && !isCompact) {
13966                pw.println();
13967                pw.println("Total PSS by process:");
13968                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13969                pw.println();
13970            }
13971            if (!isCompact) {
13972                pw.println("Total PSS by OOM adjustment:");
13973            }
13974            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13975            if (!brief && !oomOnly) {
13976                PrintWriter out = categoryPw != null ? categoryPw : pw;
13977                if (!isCompact) {
13978                    out.println();
13979                    out.println("Total PSS by category:");
13980                }
13981                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13982            }
13983            if (!isCompact) {
13984                pw.println();
13985            }
13986            MemInfoReader memInfo = new MemInfoReader();
13987            memInfo.readMemInfo();
13988            if (nativeProcTotalPss > 0) {
13989                synchronized (this) {
13990                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13991                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13992                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13993                            nativeProcTotalPss);
13994                }
13995            }
13996            if (!brief) {
13997                if (!isCompact) {
13998                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13999                    pw.print(" kB (status ");
14000                    switch (mLastMemoryLevel) {
14001                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14002                            pw.println("normal)");
14003                            break;
14004                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14005                            pw.println("moderate)");
14006                            break;
14007                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14008                            pw.println("low)");
14009                            break;
14010                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14011                            pw.println("critical)");
14012                            break;
14013                        default:
14014                            pw.print(mLastMemoryLevel);
14015                            pw.println(")");
14016                            break;
14017                    }
14018                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14019                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14020                            pw.print(cachedPss); pw.print(" cached pss + ");
14021                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14022                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14023                } else {
14024                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14025                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14026                            + memInfo.getFreeSizeKb()); pw.print(",");
14027                    pw.println(totalPss - cachedPss);
14028                }
14029            }
14030            if (!isCompact) {
14031                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14032                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14033                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14034                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14035                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14036                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14037                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14038                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14039                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14040                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14041                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14042            }
14043            if (!brief) {
14044                if (memInfo.getZramTotalSizeKb() != 0) {
14045                    if (!isCompact) {
14046                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14047                                pw.print(" kB physical used for ");
14048                                pw.print(memInfo.getSwapTotalSizeKb()
14049                                        - memInfo.getSwapFreeSizeKb());
14050                                pw.print(" kB in swap (");
14051                                pw.print(memInfo.getSwapTotalSizeKb());
14052                                pw.println(" kB total swap)");
14053                    } else {
14054                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14055                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14056                                pw.println(memInfo.getSwapFreeSizeKb());
14057                    }
14058                }
14059                final int[] SINGLE_LONG_FORMAT = new int[] {
14060                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14061                };
14062                long[] longOut = new long[1];
14063                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14064                        SINGLE_LONG_FORMAT, null, longOut, null);
14065                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14066                longOut[0] = 0;
14067                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14068                        SINGLE_LONG_FORMAT, null, longOut, null);
14069                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14070                longOut[0] = 0;
14071                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14072                        SINGLE_LONG_FORMAT, null, longOut, null);
14073                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14074                longOut[0] = 0;
14075                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14076                        SINGLE_LONG_FORMAT, null, longOut, null);
14077                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14078                if (!isCompact) {
14079                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14080                        pw.print("      KSM: "); pw.print(sharing);
14081                                pw.print(" kB saved from shared ");
14082                                pw.print(shared); pw.println(" kB");
14083                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14084                                pw.print(voltile); pw.println(" kB volatile");
14085                    }
14086                    pw.print("   Tuning: ");
14087                    pw.print(ActivityManager.staticGetMemoryClass());
14088                    pw.print(" (large ");
14089                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14090                    pw.print("), oom ");
14091                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14092                    pw.print(" kB");
14093                    pw.print(", restore limit ");
14094                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14095                    pw.print(" kB");
14096                    if (ActivityManager.isLowRamDeviceStatic()) {
14097                        pw.print(" (low-ram)");
14098                    }
14099                    if (ActivityManager.isHighEndGfx()) {
14100                        pw.print(" (high-end-gfx)");
14101                    }
14102                    pw.println();
14103                } else {
14104                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14105                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14106                    pw.println(voltile);
14107                    pw.print("tuning,");
14108                    pw.print(ActivityManager.staticGetMemoryClass());
14109                    pw.print(',');
14110                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14111                    pw.print(',');
14112                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14113                    if (ActivityManager.isLowRamDeviceStatic()) {
14114                        pw.print(",low-ram");
14115                    }
14116                    if (ActivityManager.isHighEndGfx()) {
14117                        pw.print(",high-end-gfx");
14118                    }
14119                    pw.println();
14120                }
14121            }
14122        }
14123    }
14124
14125    /**
14126     * Searches array of arguments for the specified string
14127     * @param args array of argument strings
14128     * @param value value to search for
14129     * @return true if the value is contained in the array
14130     */
14131    private static boolean scanArgs(String[] args, String value) {
14132        if (args != null) {
14133            for (String arg : args) {
14134                if (value.equals(arg)) {
14135                    return true;
14136                }
14137            }
14138        }
14139        return false;
14140    }
14141
14142    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14143            ContentProviderRecord cpr, boolean always) {
14144        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14145
14146        if (!inLaunching || always) {
14147            synchronized (cpr) {
14148                cpr.launchingApp = null;
14149                cpr.notifyAll();
14150            }
14151            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14152            String names[] = cpr.info.authority.split(";");
14153            for (int j = 0; j < names.length; j++) {
14154                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14155            }
14156        }
14157
14158        for (int i=0; i<cpr.connections.size(); i++) {
14159            ContentProviderConnection conn = cpr.connections.get(i);
14160            if (conn.waiting) {
14161                // If this connection is waiting for the provider, then we don't
14162                // need to mess with its process unless we are always removing
14163                // or for some reason the provider is not currently launching.
14164                if (inLaunching && !always) {
14165                    continue;
14166                }
14167            }
14168            ProcessRecord capp = conn.client;
14169            conn.dead = true;
14170            if (conn.stableCount > 0) {
14171                if (!capp.persistent && capp.thread != null
14172                        && capp.pid != 0
14173                        && capp.pid != MY_PID) {
14174                    capp.kill("depends on provider "
14175                            + cpr.name.flattenToShortString()
14176                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14177                }
14178            } else if (capp.thread != null && conn.provider.provider != null) {
14179                try {
14180                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14181                } catch (RemoteException e) {
14182                }
14183                // In the protocol here, we don't expect the client to correctly
14184                // clean up this connection, we'll just remove it.
14185                cpr.connections.remove(i);
14186                conn.client.conProviders.remove(conn);
14187            }
14188        }
14189
14190        if (inLaunching && always) {
14191            mLaunchingProviders.remove(cpr);
14192        }
14193        return inLaunching;
14194    }
14195
14196    /**
14197     * Main code for cleaning up a process when it has gone away.  This is
14198     * called both as a result of the process dying, or directly when stopping
14199     * a process when running in single process mode.
14200     */
14201    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14202            boolean restarting, boolean allowRestart, int index) {
14203        if (index >= 0) {
14204            removeLruProcessLocked(app);
14205            ProcessList.remove(app.pid);
14206        }
14207
14208        mProcessesToGc.remove(app);
14209        mPendingPssProcesses.remove(app);
14210
14211        // Dismiss any open dialogs.
14212        if (app.crashDialog != null && !app.forceCrashReport) {
14213            app.crashDialog.dismiss();
14214            app.crashDialog = null;
14215        }
14216        if (app.anrDialog != null) {
14217            app.anrDialog.dismiss();
14218            app.anrDialog = null;
14219        }
14220        if (app.waitDialog != null) {
14221            app.waitDialog.dismiss();
14222            app.waitDialog = null;
14223        }
14224
14225        app.crashing = false;
14226        app.notResponding = false;
14227
14228        app.resetPackageList(mProcessStats);
14229        app.unlinkDeathRecipient();
14230        app.makeInactive(mProcessStats);
14231        app.waitingToKill = null;
14232        app.forcingToForeground = null;
14233        updateProcessForegroundLocked(app, false, false);
14234        app.foregroundActivities = false;
14235        app.hasShownUi = false;
14236        app.treatLikeActivity = false;
14237        app.hasAboveClient = false;
14238        app.hasClientActivities = false;
14239
14240        mServices.killServicesLocked(app, allowRestart);
14241
14242        boolean restart = false;
14243
14244        // Remove published content providers.
14245        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14246            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14247            final boolean always = app.bad || !allowRestart;
14248            if (removeDyingProviderLocked(app, cpr, always) || always) {
14249                // We left the provider in the launching list, need to
14250                // restart it.
14251                restart = true;
14252            }
14253
14254            cpr.provider = null;
14255            cpr.proc = null;
14256        }
14257        app.pubProviders.clear();
14258
14259        // Take care of any launching providers waiting for this process.
14260        if (checkAppInLaunchingProvidersLocked(app, false)) {
14261            restart = true;
14262        }
14263
14264        // Unregister from connected content providers.
14265        if (!app.conProviders.isEmpty()) {
14266            for (int i=0; i<app.conProviders.size(); i++) {
14267                ContentProviderConnection conn = app.conProviders.get(i);
14268                conn.provider.connections.remove(conn);
14269            }
14270            app.conProviders.clear();
14271        }
14272
14273        // At this point there may be remaining entries in mLaunchingProviders
14274        // where we were the only one waiting, so they are no longer of use.
14275        // Look for these and clean up if found.
14276        // XXX Commented out for now.  Trying to figure out a way to reproduce
14277        // the actual situation to identify what is actually going on.
14278        if (false) {
14279            for (int i=0; i<mLaunchingProviders.size(); i++) {
14280                ContentProviderRecord cpr = (ContentProviderRecord)
14281                        mLaunchingProviders.get(i);
14282                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14283                    synchronized (cpr) {
14284                        cpr.launchingApp = null;
14285                        cpr.notifyAll();
14286                    }
14287                }
14288            }
14289        }
14290
14291        skipCurrentReceiverLocked(app);
14292
14293        // Unregister any receivers.
14294        for (int i=app.receivers.size()-1; i>=0; i--) {
14295            removeReceiverLocked(app.receivers.valueAt(i));
14296        }
14297        app.receivers.clear();
14298
14299        // If the app is undergoing backup, tell the backup manager about it
14300        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14301            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14302                    + mBackupTarget.appInfo + " died during backup");
14303            try {
14304                IBackupManager bm = IBackupManager.Stub.asInterface(
14305                        ServiceManager.getService(Context.BACKUP_SERVICE));
14306                bm.agentDisconnected(app.info.packageName);
14307            } catch (RemoteException e) {
14308                // can't happen; backup manager is local
14309            }
14310        }
14311
14312        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14313            ProcessChangeItem item = mPendingProcessChanges.get(i);
14314            if (item.pid == app.pid) {
14315                mPendingProcessChanges.remove(i);
14316                mAvailProcessChanges.add(item);
14317            }
14318        }
14319        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14320
14321        // If the caller is restarting this app, then leave it in its
14322        // current lists and let the caller take care of it.
14323        if (restarting) {
14324            return;
14325        }
14326
14327        if (!app.persistent || app.isolated) {
14328            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14329                    "Removing non-persistent process during cleanup: " + app);
14330            mProcessNames.remove(app.processName, app.uid);
14331            mIsolatedProcesses.remove(app.uid);
14332            if (mHeavyWeightProcess == app) {
14333                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14334                        mHeavyWeightProcess.userId, 0));
14335                mHeavyWeightProcess = null;
14336            }
14337        } else if (!app.removed) {
14338            // This app is persistent, so we need to keep its record around.
14339            // If it is not already on the pending app list, add it there
14340            // and start a new process for it.
14341            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14342                mPersistentStartingProcesses.add(app);
14343                restart = true;
14344            }
14345        }
14346        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14347                "Clean-up removing on hold: " + app);
14348        mProcessesOnHold.remove(app);
14349
14350        if (app == mHomeProcess) {
14351            mHomeProcess = null;
14352        }
14353        if (app == mPreviousProcess) {
14354            mPreviousProcess = null;
14355        }
14356
14357        if (restart && !app.isolated) {
14358            // We have components that still need to be running in the
14359            // process, so re-launch it.
14360            mProcessNames.put(app.processName, app.uid, app);
14361            startProcessLocked(app, "restart", app.processName);
14362        } else if (app.pid > 0 && app.pid != MY_PID) {
14363            // Goodbye!
14364            boolean removed;
14365            synchronized (mPidsSelfLocked) {
14366                mPidsSelfLocked.remove(app.pid);
14367                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14368            }
14369            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14370            if (app.isolated) {
14371                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14372            }
14373            app.setPid(0);
14374        }
14375    }
14376
14377    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14378        // Look through the content providers we are waiting to have launched,
14379        // and if any run in this process then either schedule a restart of
14380        // the process or kill the client waiting for it if this process has
14381        // gone bad.
14382        int NL = mLaunchingProviders.size();
14383        boolean restart = false;
14384        for (int i=0; i<NL; i++) {
14385            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14386            if (cpr.launchingApp == app) {
14387                if (!alwaysBad && !app.bad) {
14388                    restart = true;
14389                } else {
14390                    removeDyingProviderLocked(app, cpr, true);
14391                    // cpr should have been removed from mLaunchingProviders
14392                    NL = mLaunchingProviders.size();
14393                    i--;
14394                }
14395            }
14396        }
14397        return restart;
14398    }
14399
14400    // =========================================================
14401    // SERVICES
14402    // =========================================================
14403
14404    @Override
14405    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14406            int flags) {
14407        enforceNotIsolatedCaller("getServices");
14408        synchronized (this) {
14409            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14410        }
14411    }
14412
14413    @Override
14414    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14415        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14416        synchronized (this) {
14417            return mServices.getRunningServiceControlPanelLocked(name);
14418        }
14419    }
14420
14421    @Override
14422    public ComponentName startService(IApplicationThread caller, Intent service,
14423            String resolvedType, int userId) {
14424        enforceNotIsolatedCaller("startService");
14425        // Refuse possible leaked file descriptors
14426        if (service != null && service.hasFileDescriptors() == true) {
14427            throw new IllegalArgumentException("File descriptors passed in Intent");
14428        }
14429
14430        if (DEBUG_SERVICE)
14431            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14432        synchronized(this) {
14433            final int callingPid = Binder.getCallingPid();
14434            final int callingUid = Binder.getCallingUid();
14435            final long origId = Binder.clearCallingIdentity();
14436            ComponentName res = mServices.startServiceLocked(caller, service,
14437                    resolvedType, callingPid, callingUid, userId);
14438            Binder.restoreCallingIdentity(origId);
14439            return res;
14440        }
14441    }
14442
14443    ComponentName startServiceInPackage(int uid,
14444            Intent service, String resolvedType, int userId) {
14445        synchronized(this) {
14446            if (DEBUG_SERVICE)
14447                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14448            final long origId = Binder.clearCallingIdentity();
14449            ComponentName res = mServices.startServiceLocked(null, service,
14450                    resolvedType, -1, uid, userId);
14451            Binder.restoreCallingIdentity(origId);
14452            return res;
14453        }
14454    }
14455
14456    @Override
14457    public int stopService(IApplicationThread caller, Intent service,
14458            String resolvedType, int userId) {
14459        enforceNotIsolatedCaller("stopService");
14460        // Refuse possible leaked file descriptors
14461        if (service != null && service.hasFileDescriptors() == true) {
14462            throw new IllegalArgumentException("File descriptors passed in Intent");
14463        }
14464
14465        synchronized(this) {
14466            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14467        }
14468    }
14469
14470    @Override
14471    public IBinder peekService(Intent service, String resolvedType) {
14472        enforceNotIsolatedCaller("peekService");
14473        // Refuse possible leaked file descriptors
14474        if (service != null && service.hasFileDescriptors() == true) {
14475            throw new IllegalArgumentException("File descriptors passed in Intent");
14476        }
14477        synchronized(this) {
14478            return mServices.peekServiceLocked(service, resolvedType);
14479        }
14480    }
14481
14482    @Override
14483    public boolean stopServiceToken(ComponentName className, IBinder token,
14484            int startId) {
14485        synchronized(this) {
14486            return mServices.stopServiceTokenLocked(className, token, startId);
14487        }
14488    }
14489
14490    @Override
14491    public void setServiceForeground(ComponentName className, IBinder token,
14492            int id, Notification notification, boolean removeNotification) {
14493        synchronized(this) {
14494            mServices.setServiceForegroundLocked(className, token, id, notification,
14495                    removeNotification);
14496        }
14497    }
14498
14499    @Override
14500    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14501            boolean requireFull, String name, String callerPackage) {
14502        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14503                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14504    }
14505
14506    int unsafeConvertIncomingUser(int userId) {
14507        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14508                ? mCurrentUserId : userId;
14509    }
14510
14511    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14512            int allowMode, String name, String callerPackage) {
14513        final int callingUserId = UserHandle.getUserId(callingUid);
14514        if (callingUserId == userId) {
14515            return userId;
14516        }
14517
14518        // Note that we may be accessing mCurrentUserId outside of a lock...
14519        // shouldn't be a big deal, if this is being called outside
14520        // of a locked context there is intrinsically a race with
14521        // the value the caller will receive and someone else changing it.
14522        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14523        // we will switch to the calling user if access to the current user fails.
14524        int targetUserId = unsafeConvertIncomingUser(userId);
14525
14526        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14527            final boolean allow;
14528            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14529                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14530                // If the caller has this permission, they always pass go.  And collect $200.
14531                allow = true;
14532            } else if (allowMode == ALLOW_FULL_ONLY) {
14533                // We require full access, sucks to be you.
14534                allow = false;
14535            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14536                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14537                // If the caller does not have either permission, they are always doomed.
14538                allow = false;
14539            } else if (allowMode == ALLOW_NON_FULL) {
14540                // We are blanket allowing non-full access, you lucky caller!
14541                allow = true;
14542            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14543                // We may or may not allow this depending on whether the two users are
14544                // in the same profile.
14545                synchronized (mUserProfileGroupIdsSelfLocked) {
14546                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14547                            UserInfo.NO_PROFILE_GROUP_ID);
14548                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14549                            UserInfo.NO_PROFILE_GROUP_ID);
14550                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14551                            && callingProfile == targetProfile;
14552                }
14553            } else {
14554                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14555            }
14556            if (!allow) {
14557                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14558                    // In this case, they would like to just execute as their
14559                    // owner user instead of failing.
14560                    targetUserId = callingUserId;
14561                } else {
14562                    StringBuilder builder = new StringBuilder(128);
14563                    builder.append("Permission Denial: ");
14564                    builder.append(name);
14565                    if (callerPackage != null) {
14566                        builder.append(" from ");
14567                        builder.append(callerPackage);
14568                    }
14569                    builder.append(" asks to run as user ");
14570                    builder.append(userId);
14571                    builder.append(" but is calling from user ");
14572                    builder.append(UserHandle.getUserId(callingUid));
14573                    builder.append("; this requires ");
14574                    builder.append(INTERACT_ACROSS_USERS_FULL);
14575                    if (allowMode != ALLOW_FULL_ONLY) {
14576                        builder.append(" or ");
14577                        builder.append(INTERACT_ACROSS_USERS);
14578                    }
14579                    String msg = builder.toString();
14580                    Slog.w(TAG, msg);
14581                    throw new SecurityException(msg);
14582                }
14583            }
14584        }
14585        if (!allowAll && targetUserId < 0) {
14586            throw new IllegalArgumentException(
14587                    "Call does not support special user #" + targetUserId);
14588        }
14589        return targetUserId;
14590    }
14591
14592    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14593            String className, int flags) {
14594        boolean result = false;
14595        // For apps that don't have pre-defined UIDs, check for permission
14596        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14597            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14598                if (ActivityManager.checkUidPermission(
14599                        INTERACT_ACROSS_USERS,
14600                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14601                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14602                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14603                            + " requests FLAG_SINGLE_USER, but app does not hold "
14604                            + INTERACT_ACROSS_USERS;
14605                    Slog.w(TAG, msg);
14606                    throw new SecurityException(msg);
14607                }
14608                // Permission passed
14609                result = true;
14610            }
14611        } else if ("system".equals(componentProcessName)) {
14612            result = true;
14613        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14614                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14615            // Phone app is allowed to export singleuser providers.
14616            result = true;
14617        } else {
14618            // App with pre-defined UID, check if it's a persistent app
14619            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14620        }
14621        if (DEBUG_MU) {
14622            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14623                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14624        }
14625        return result;
14626    }
14627
14628    /**
14629     * Checks to see if the caller is in the same app as the singleton
14630     * component, or the component is in a special app. It allows special apps
14631     * to export singleton components but prevents exporting singleton
14632     * components for regular apps.
14633     */
14634    boolean isValidSingletonCall(int callingUid, int componentUid) {
14635        int componentAppId = UserHandle.getAppId(componentUid);
14636        return UserHandle.isSameApp(callingUid, componentUid)
14637                || componentAppId == Process.SYSTEM_UID
14638                || componentAppId == Process.PHONE_UID
14639                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14640                        == PackageManager.PERMISSION_GRANTED;
14641    }
14642
14643    public int bindService(IApplicationThread caller, IBinder token,
14644            Intent service, String resolvedType,
14645            IServiceConnection connection, int flags, int userId) {
14646        enforceNotIsolatedCaller("bindService");
14647        // Refuse possible leaked file descriptors
14648        if (service != null && service.hasFileDescriptors() == true) {
14649            throw new IllegalArgumentException("File descriptors passed in Intent");
14650        }
14651
14652        synchronized(this) {
14653            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14654                    connection, flags, userId);
14655        }
14656    }
14657
14658    public boolean unbindService(IServiceConnection connection) {
14659        synchronized (this) {
14660            return mServices.unbindServiceLocked(connection);
14661        }
14662    }
14663
14664    public void publishService(IBinder token, Intent intent, IBinder service) {
14665        // Refuse possible leaked file descriptors
14666        if (intent != null && intent.hasFileDescriptors() == true) {
14667            throw new IllegalArgumentException("File descriptors passed in Intent");
14668        }
14669
14670        synchronized(this) {
14671            if (!(token instanceof ServiceRecord)) {
14672                throw new IllegalArgumentException("Invalid service token");
14673            }
14674            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14675        }
14676    }
14677
14678    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14679        // Refuse possible leaked file descriptors
14680        if (intent != null && intent.hasFileDescriptors() == true) {
14681            throw new IllegalArgumentException("File descriptors passed in Intent");
14682        }
14683
14684        synchronized(this) {
14685            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14686        }
14687    }
14688
14689    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14690        synchronized(this) {
14691            if (!(token instanceof ServiceRecord)) {
14692                throw new IllegalArgumentException("Invalid service token");
14693            }
14694            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14695        }
14696    }
14697
14698    // =========================================================
14699    // BACKUP AND RESTORE
14700    // =========================================================
14701
14702    // Cause the target app to be launched if necessary and its backup agent
14703    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14704    // activity manager to announce its creation.
14705    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14706        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14707        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14708
14709        synchronized(this) {
14710            // !!! TODO: currently no check here that we're already bound
14711            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14712            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14713            synchronized (stats) {
14714                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14715            }
14716
14717            // Backup agent is now in use, its package can't be stopped.
14718            try {
14719                AppGlobals.getPackageManager().setPackageStoppedState(
14720                        app.packageName, false, UserHandle.getUserId(app.uid));
14721            } catch (RemoteException e) {
14722            } catch (IllegalArgumentException e) {
14723                Slog.w(TAG, "Failed trying to unstop package "
14724                        + app.packageName + ": " + e);
14725            }
14726
14727            BackupRecord r = new BackupRecord(ss, app, backupMode);
14728            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14729                    ? new ComponentName(app.packageName, app.backupAgentName)
14730                    : new ComponentName("android", "FullBackupAgent");
14731            // startProcessLocked() returns existing proc's record if it's already running
14732            ProcessRecord proc = startProcessLocked(app.processName, app,
14733                    false, 0, "backup", hostingName, false, false, false);
14734            if (proc == null) {
14735                Slog.e(TAG, "Unable to start backup agent process " + r);
14736                return false;
14737            }
14738
14739            r.app = proc;
14740            mBackupTarget = r;
14741            mBackupAppName = app.packageName;
14742
14743            // Try not to kill the process during backup
14744            updateOomAdjLocked(proc);
14745
14746            // If the process is already attached, schedule the creation of the backup agent now.
14747            // If it is not yet live, this will be done when it attaches to the framework.
14748            if (proc.thread != null) {
14749                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14750                try {
14751                    proc.thread.scheduleCreateBackupAgent(app,
14752                            compatibilityInfoForPackageLocked(app), backupMode);
14753                } catch (RemoteException e) {
14754                    // Will time out on the backup manager side
14755                }
14756            } else {
14757                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14758            }
14759            // Invariants: at this point, the target app process exists and the application
14760            // is either already running or in the process of coming up.  mBackupTarget and
14761            // mBackupAppName describe the app, so that when it binds back to the AM we
14762            // know that it's scheduled for a backup-agent operation.
14763        }
14764
14765        return true;
14766    }
14767
14768    @Override
14769    public void clearPendingBackup() {
14770        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14771        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14772
14773        synchronized (this) {
14774            mBackupTarget = null;
14775            mBackupAppName = null;
14776        }
14777    }
14778
14779    // A backup agent has just come up
14780    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14781        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14782                + " = " + agent);
14783
14784        synchronized(this) {
14785            if (!agentPackageName.equals(mBackupAppName)) {
14786                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14787                return;
14788            }
14789        }
14790
14791        long oldIdent = Binder.clearCallingIdentity();
14792        try {
14793            IBackupManager bm = IBackupManager.Stub.asInterface(
14794                    ServiceManager.getService(Context.BACKUP_SERVICE));
14795            bm.agentConnected(agentPackageName, agent);
14796        } catch (RemoteException e) {
14797            // can't happen; the backup manager service is local
14798        } catch (Exception e) {
14799            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14800            e.printStackTrace();
14801        } finally {
14802            Binder.restoreCallingIdentity(oldIdent);
14803        }
14804    }
14805
14806    // done with this agent
14807    public void unbindBackupAgent(ApplicationInfo appInfo) {
14808        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14809        if (appInfo == null) {
14810            Slog.w(TAG, "unbind backup agent for null app");
14811            return;
14812        }
14813
14814        synchronized(this) {
14815            try {
14816                if (mBackupAppName == null) {
14817                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14818                    return;
14819                }
14820
14821                if (!mBackupAppName.equals(appInfo.packageName)) {
14822                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14823                    return;
14824                }
14825
14826                // Not backing this app up any more; reset its OOM adjustment
14827                final ProcessRecord proc = mBackupTarget.app;
14828                updateOomAdjLocked(proc);
14829
14830                // If the app crashed during backup, 'thread' will be null here
14831                if (proc.thread != null) {
14832                    try {
14833                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14834                                compatibilityInfoForPackageLocked(appInfo));
14835                    } catch (Exception e) {
14836                        Slog.e(TAG, "Exception when unbinding backup agent:");
14837                        e.printStackTrace();
14838                    }
14839                }
14840            } finally {
14841                mBackupTarget = null;
14842                mBackupAppName = null;
14843            }
14844        }
14845    }
14846    // =========================================================
14847    // BROADCASTS
14848    // =========================================================
14849
14850    private final List getStickiesLocked(String action, IntentFilter filter,
14851            List cur, int userId) {
14852        final ContentResolver resolver = mContext.getContentResolver();
14853        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14854        if (stickies == null) {
14855            return cur;
14856        }
14857        final ArrayList<Intent> list = stickies.get(action);
14858        if (list == null) {
14859            return cur;
14860        }
14861        int N = list.size();
14862        for (int i=0; i<N; i++) {
14863            Intent intent = list.get(i);
14864            if (filter.match(resolver, intent, true, TAG) >= 0) {
14865                if (cur == null) {
14866                    cur = new ArrayList<Intent>();
14867                }
14868                cur.add(intent);
14869            }
14870        }
14871        return cur;
14872    }
14873
14874    boolean isPendingBroadcastProcessLocked(int pid) {
14875        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14876                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14877    }
14878
14879    void skipPendingBroadcastLocked(int pid) {
14880            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14881            for (BroadcastQueue queue : mBroadcastQueues) {
14882                queue.skipPendingBroadcastLocked(pid);
14883            }
14884    }
14885
14886    // The app just attached; send any pending broadcasts that it should receive
14887    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14888        boolean didSomething = false;
14889        for (BroadcastQueue queue : mBroadcastQueues) {
14890            didSomething |= queue.sendPendingBroadcastsLocked(app);
14891        }
14892        return didSomething;
14893    }
14894
14895    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14896            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14897        enforceNotIsolatedCaller("registerReceiver");
14898        int callingUid;
14899        int callingPid;
14900        synchronized(this) {
14901            ProcessRecord callerApp = null;
14902            if (caller != null) {
14903                callerApp = getRecordForAppLocked(caller);
14904                if (callerApp == null) {
14905                    throw new SecurityException(
14906                            "Unable to find app for caller " + caller
14907                            + " (pid=" + Binder.getCallingPid()
14908                            + ") when registering receiver " + receiver);
14909                }
14910                if (callerApp.info.uid != Process.SYSTEM_UID &&
14911                        !callerApp.pkgList.containsKey(callerPackage) &&
14912                        !"android".equals(callerPackage)) {
14913                    throw new SecurityException("Given caller package " + callerPackage
14914                            + " is not running in process " + callerApp);
14915                }
14916                callingUid = callerApp.info.uid;
14917                callingPid = callerApp.pid;
14918            } else {
14919                callerPackage = null;
14920                callingUid = Binder.getCallingUid();
14921                callingPid = Binder.getCallingPid();
14922            }
14923
14924            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14925                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14926
14927            List allSticky = null;
14928
14929            // Look for any matching sticky broadcasts...
14930            Iterator actions = filter.actionsIterator();
14931            if (actions != null) {
14932                while (actions.hasNext()) {
14933                    String action = (String)actions.next();
14934                    allSticky = getStickiesLocked(action, filter, allSticky,
14935                            UserHandle.USER_ALL);
14936                    allSticky = getStickiesLocked(action, filter, allSticky,
14937                            UserHandle.getUserId(callingUid));
14938                }
14939            } else {
14940                allSticky = getStickiesLocked(null, filter, allSticky,
14941                        UserHandle.USER_ALL);
14942                allSticky = getStickiesLocked(null, filter, allSticky,
14943                        UserHandle.getUserId(callingUid));
14944            }
14945
14946            // The first sticky in the list is returned directly back to
14947            // the client.
14948            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14949
14950            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14951                    + ": " + sticky);
14952
14953            if (receiver == null) {
14954                return sticky;
14955            }
14956
14957            ReceiverList rl
14958                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14959            if (rl == null) {
14960                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14961                        userId, receiver);
14962                if (rl.app != null) {
14963                    rl.app.receivers.add(rl);
14964                } else {
14965                    try {
14966                        receiver.asBinder().linkToDeath(rl, 0);
14967                    } catch (RemoteException e) {
14968                        return sticky;
14969                    }
14970                    rl.linkedToDeath = true;
14971                }
14972                mRegisteredReceivers.put(receiver.asBinder(), rl);
14973            } else if (rl.uid != callingUid) {
14974                throw new IllegalArgumentException(
14975                        "Receiver requested to register for uid " + callingUid
14976                        + " was previously registered for uid " + rl.uid);
14977            } else if (rl.pid != callingPid) {
14978                throw new IllegalArgumentException(
14979                        "Receiver requested to register for pid " + callingPid
14980                        + " was previously registered for pid " + rl.pid);
14981            } else if (rl.userId != userId) {
14982                throw new IllegalArgumentException(
14983                        "Receiver requested to register for user " + userId
14984                        + " was previously registered for user " + rl.userId);
14985            }
14986            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14987                    permission, callingUid, userId);
14988            rl.add(bf);
14989            if (!bf.debugCheck()) {
14990                Slog.w(TAG, "==> For Dynamic broadast");
14991            }
14992            mReceiverResolver.addFilter(bf);
14993
14994            // Enqueue broadcasts for all existing stickies that match
14995            // this filter.
14996            if (allSticky != null) {
14997                ArrayList receivers = new ArrayList();
14998                receivers.add(bf);
14999
15000                int N = allSticky.size();
15001                for (int i=0; i<N; i++) {
15002                    Intent intent = (Intent)allSticky.get(i);
15003                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15004                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15005                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15006                            null, null, false, true, true, -1);
15007                    queue.enqueueParallelBroadcastLocked(r);
15008                    queue.scheduleBroadcastsLocked();
15009                }
15010            }
15011
15012            return sticky;
15013        }
15014    }
15015
15016    public void unregisterReceiver(IIntentReceiver receiver) {
15017        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15018
15019        final long origId = Binder.clearCallingIdentity();
15020        try {
15021            boolean doTrim = false;
15022
15023            synchronized(this) {
15024                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15025                if (rl != null) {
15026                    if (rl.curBroadcast != null) {
15027                        BroadcastRecord r = rl.curBroadcast;
15028                        final boolean doNext = finishReceiverLocked(
15029                                receiver.asBinder(), r.resultCode, r.resultData,
15030                                r.resultExtras, r.resultAbort);
15031                        if (doNext) {
15032                            doTrim = true;
15033                            r.queue.processNextBroadcast(false);
15034                        }
15035                    }
15036
15037                    if (rl.app != null) {
15038                        rl.app.receivers.remove(rl);
15039                    }
15040                    removeReceiverLocked(rl);
15041                    if (rl.linkedToDeath) {
15042                        rl.linkedToDeath = false;
15043                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15044                    }
15045                }
15046            }
15047
15048            // If we actually concluded any broadcasts, we might now be able
15049            // to trim the recipients' apps from our working set
15050            if (doTrim) {
15051                trimApplications();
15052                return;
15053            }
15054
15055        } finally {
15056            Binder.restoreCallingIdentity(origId);
15057        }
15058    }
15059
15060    void removeReceiverLocked(ReceiverList rl) {
15061        mRegisteredReceivers.remove(rl.receiver.asBinder());
15062        int N = rl.size();
15063        for (int i=0; i<N; i++) {
15064            mReceiverResolver.removeFilter(rl.get(i));
15065        }
15066    }
15067
15068    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15069        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15070            ProcessRecord r = mLruProcesses.get(i);
15071            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15072                try {
15073                    r.thread.dispatchPackageBroadcast(cmd, packages);
15074                } catch (RemoteException ex) {
15075                }
15076            }
15077        }
15078    }
15079
15080    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15081            int[] users) {
15082        List<ResolveInfo> receivers = null;
15083        try {
15084            HashSet<ComponentName> singleUserReceivers = null;
15085            boolean scannedFirstReceivers = false;
15086            for (int user : users) {
15087                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15088                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15089                if (user != 0 && newReceivers != null) {
15090                    // If this is not the primary user, we need to check for
15091                    // any receivers that should be filtered out.
15092                    for (int i=0; i<newReceivers.size(); i++) {
15093                        ResolveInfo ri = newReceivers.get(i);
15094                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15095                            newReceivers.remove(i);
15096                            i--;
15097                        }
15098                    }
15099                }
15100                if (newReceivers != null && newReceivers.size() == 0) {
15101                    newReceivers = null;
15102                }
15103                if (receivers == null) {
15104                    receivers = newReceivers;
15105                } else if (newReceivers != null) {
15106                    // We need to concatenate the additional receivers
15107                    // found with what we have do far.  This would be easy,
15108                    // but we also need to de-dup any receivers that are
15109                    // singleUser.
15110                    if (!scannedFirstReceivers) {
15111                        // Collect any single user receivers we had already retrieved.
15112                        scannedFirstReceivers = true;
15113                        for (int i=0; i<receivers.size(); i++) {
15114                            ResolveInfo ri = receivers.get(i);
15115                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15116                                ComponentName cn = new ComponentName(
15117                                        ri.activityInfo.packageName, ri.activityInfo.name);
15118                                if (singleUserReceivers == null) {
15119                                    singleUserReceivers = new HashSet<ComponentName>();
15120                                }
15121                                singleUserReceivers.add(cn);
15122                            }
15123                        }
15124                    }
15125                    // Add the new results to the existing results, tracking
15126                    // and de-dupping single user receivers.
15127                    for (int i=0; i<newReceivers.size(); i++) {
15128                        ResolveInfo ri = newReceivers.get(i);
15129                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15130                            ComponentName cn = new ComponentName(
15131                                    ri.activityInfo.packageName, ri.activityInfo.name);
15132                            if (singleUserReceivers == null) {
15133                                singleUserReceivers = new HashSet<ComponentName>();
15134                            }
15135                            if (!singleUserReceivers.contains(cn)) {
15136                                singleUserReceivers.add(cn);
15137                                receivers.add(ri);
15138                            }
15139                        } else {
15140                            receivers.add(ri);
15141                        }
15142                    }
15143                }
15144            }
15145        } catch (RemoteException ex) {
15146            // pm is in same process, this will never happen.
15147        }
15148        return receivers;
15149    }
15150
15151    private final int broadcastIntentLocked(ProcessRecord callerApp,
15152            String callerPackage, Intent intent, String resolvedType,
15153            IIntentReceiver resultTo, int resultCode, String resultData,
15154            Bundle map, String requiredPermission, int appOp,
15155            boolean ordered, boolean sticky, int callingPid, int callingUid,
15156            int userId) {
15157        intent = new Intent(intent);
15158
15159        // By default broadcasts do not go to stopped apps.
15160        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15161
15162        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15163            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15164            + " ordered=" + ordered + " userid=" + userId);
15165        if ((resultTo != null) && !ordered) {
15166            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15167        }
15168
15169        userId = handleIncomingUser(callingPid, callingUid, userId,
15170                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15171
15172        // Make sure that the user who is receiving this broadcast is started.
15173        // If not, we will just skip it.
15174
15175
15176        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15177            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15178                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15179                Slog.w(TAG, "Skipping broadcast of " + intent
15180                        + ": user " + userId + " is stopped");
15181                return ActivityManager.BROADCAST_SUCCESS;
15182            }
15183        }
15184
15185        /*
15186         * Prevent non-system code (defined here to be non-persistent
15187         * processes) from sending protected broadcasts.
15188         */
15189        int callingAppId = UserHandle.getAppId(callingUid);
15190        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15191            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15192            || callingAppId == Process.NFC_UID || callingUid == 0) {
15193            // Always okay.
15194        } else if (callerApp == null || !callerApp.persistent) {
15195            try {
15196                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15197                        intent.getAction())) {
15198                    String msg = "Permission Denial: not allowed to send broadcast "
15199                            + intent.getAction() + " from pid="
15200                            + callingPid + ", uid=" + callingUid;
15201                    Slog.w(TAG, msg);
15202                    throw new SecurityException(msg);
15203                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15204                    // Special case for compatibility: we don't want apps to send this,
15205                    // but historically it has not been protected and apps may be using it
15206                    // to poke their own app widget.  So, instead of making it protected,
15207                    // just limit it to the caller.
15208                    if (callerApp == null) {
15209                        String msg = "Permission Denial: not allowed to send broadcast "
15210                                + intent.getAction() + " from unknown caller.";
15211                        Slog.w(TAG, msg);
15212                        throw new SecurityException(msg);
15213                    } else if (intent.getComponent() != null) {
15214                        // They are good enough to send to an explicit component...  verify
15215                        // it is being sent to the calling app.
15216                        if (!intent.getComponent().getPackageName().equals(
15217                                callerApp.info.packageName)) {
15218                            String msg = "Permission Denial: not allowed to send broadcast "
15219                                    + intent.getAction() + " to "
15220                                    + intent.getComponent().getPackageName() + " from "
15221                                    + callerApp.info.packageName;
15222                            Slog.w(TAG, msg);
15223                            throw new SecurityException(msg);
15224                        }
15225                    } else {
15226                        // Limit broadcast to their own package.
15227                        intent.setPackage(callerApp.info.packageName);
15228                    }
15229                }
15230            } catch (RemoteException e) {
15231                Slog.w(TAG, "Remote exception", e);
15232                return ActivityManager.BROADCAST_SUCCESS;
15233            }
15234        }
15235
15236        // Handle special intents: if this broadcast is from the package
15237        // manager about a package being removed, we need to remove all of
15238        // its activities from the history stack.
15239        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15240                intent.getAction());
15241        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15242                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15243                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15244                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15245                || uidRemoved) {
15246            if (checkComponentPermission(
15247                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15248                    callingPid, callingUid, -1, true)
15249                    == PackageManager.PERMISSION_GRANTED) {
15250                if (uidRemoved) {
15251                    final Bundle intentExtras = intent.getExtras();
15252                    final int uid = intentExtras != null
15253                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15254                    if (uid >= 0) {
15255                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15256                        synchronized (bs) {
15257                            bs.removeUidStatsLocked(uid);
15258                        }
15259                        mAppOpsService.uidRemoved(uid);
15260                    }
15261                } else {
15262                    // If resources are unavailable just force stop all
15263                    // those packages and flush the attribute cache as well.
15264                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15265                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15266                        if (list != null && (list.length > 0)) {
15267                            for (String pkg : list) {
15268                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15269                                        "storage unmount");
15270                            }
15271                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15272                            sendPackageBroadcastLocked(
15273                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15274                        }
15275                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15276                            intent.getAction())) {
15277                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15278                    } else {
15279                        Uri data = intent.getData();
15280                        String ssp;
15281                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15282                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15283                                    intent.getAction());
15284                            boolean fullUninstall = removed &&
15285                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15286                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15287                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15288                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15289                                        false, fullUninstall, userId,
15290                                        removed ? "pkg removed" : "pkg changed");
15291                            }
15292                            if (removed) {
15293                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15294                                        new String[] {ssp}, userId);
15295                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15296                                    mAppOpsService.packageRemoved(
15297                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15298
15299                                    // Remove all permissions granted from/to this package
15300                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15301                                }
15302                            }
15303                        }
15304                    }
15305                }
15306            } else {
15307                String msg = "Permission Denial: " + intent.getAction()
15308                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15309                        + ", uid=" + callingUid + ")"
15310                        + " requires "
15311                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15312                Slog.w(TAG, msg);
15313                throw new SecurityException(msg);
15314            }
15315
15316        // Special case for adding a package: by default turn on compatibility
15317        // mode.
15318        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15319            Uri data = intent.getData();
15320            String ssp;
15321            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15322                mCompatModePackages.handlePackageAddedLocked(ssp,
15323                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15324            }
15325        }
15326
15327        /*
15328         * If this is the time zone changed action, queue up a message that will reset the timezone
15329         * of all currently running processes. This message will get queued up before the broadcast
15330         * happens.
15331         */
15332        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15333            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15334        }
15335
15336        /*
15337         * If the user set the time, let all running processes know.
15338         */
15339        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15340            final int is24Hour = intent.getBooleanExtra(
15341                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15342            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15343            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15344            synchronized (stats) {
15345                stats.noteCurrentTimeChangedLocked();
15346            }
15347        }
15348
15349        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15350            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15351        }
15352
15353        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15354            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15355            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15356        }
15357
15358        // Add to the sticky list if requested.
15359        if (sticky) {
15360            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15361                    callingPid, callingUid)
15362                    != PackageManager.PERMISSION_GRANTED) {
15363                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15364                        + callingPid + ", uid=" + callingUid
15365                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15366                Slog.w(TAG, msg);
15367                throw new SecurityException(msg);
15368            }
15369            if (requiredPermission != null) {
15370                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15371                        + " and enforce permission " + requiredPermission);
15372                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15373            }
15374            if (intent.getComponent() != null) {
15375                throw new SecurityException(
15376                        "Sticky broadcasts can't target a specific component");
15377            }
15378            // We use userId directly here, since the "all" target is maintained
15379            // as a separate set of sticky broadcasts.
15380            if (userId != UserHandle.USER_ALL) {
15381                // But first, if this is not a broadcast to all users, then
15382                // make sure it doesn't conflict with an existing broadcast to
15383                // all users.
15384                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15385                        UserHandle.USER_ALL);
15386                if (stickies != null) {
15387                    ArrayList<Intent> list = stickies.get(intent.getAction());
15388                    if (list != null) {
15389                        int N = list.size();
15390                        int i;
15391                        for (i=0; i<N; i++) {
15392                            if (intent.filterEquals(list.get(i))) {
15393                                throw new IllegalArgumentException(
15394                                        "Sticky broadcast " + intent + " for user "
15395                                        + userId + " conflicts with existing global broadcast");
15396                            }
15397                        }
15398                    }
15399                }
15400            }
15401            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15402            if (stickies == null) {
15403                stickies = new ArrayMap<String, ArrayList<Intent>>();
15404                mStickyBroadcasts.put(userId, stickies);
15405            }
15406            ArrayList<Intent> list = stickies.get(intent.getAction());
15407            if (list == null) {
15408                list = new ArrayList<Intent>();
15409                stickies.put(intent.getAction(), list);
15410            }
15411            int N = list.size();
15412            int i;
15413            for (i=0; i<N; i++) {
15414                if (intent.filterEquals(list.get(i))) {
15415                    // This sticky already exists, replace it.
15416                    list.set(i, new Intent(intent));
15417                    break;
15418                }
15419            }
15420            if (i >= N) {
15421                list.add(new Intent(intent));
15422            }
15423        }
15424
15425        int[] users;
15426        if (userId == UserHandle.USER_ALL) {
15427            // Caller wants broadcast to go to all started users.
15428            users = mStartedUserArray;
15429        } else {
15430            // Caller wants broadcast to go to one specific user.
15431            users = new int[] {userId};
15432        }
15433
15434        // Figure out who all will receive this broadcast.
15435        List receivers = null;
15436        List<BroadcastFilter> registeredReceivers = null;
15437        // Need to resolve the intent to interested receivers...
15438        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15439                 == 0) {
15440            receivers = collectReceiverComponents(intent, resolvedType, users);
15441        }
15442        if (intent.getComponent() == null) {
15443            registeredReceivers = mReceiverResolver.queryIntent(intent,
15444                    resolvedType, false, userId);
15445        }
15446
15447        final boolean replacePending =
15448                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15449
15450        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15451                + " replacePending=" + replacePending);
15452
15453        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15454        if (!ordered && NR > 0) {
15455            // If we are not serializing this broadcast, then send the
15456            // registered receivers separately so they don't wait for the
15457            // components to be launched.
15458            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15459            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15460                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15461                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15462                    ordered, sticky, false, userId);
15463            if (DEBUG_BROADCAST) Slog.v(
15464                    TAG, "Enqueueing parallel broadcast " + r);
15465            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15466            if (!replaced) {
15467                queue.enqueueParallelBroadcastLocked(r);
15468                queue.scheduleBroadcastsLocked();
15469            }
15470            registeredReceivers = null;
15471            NR = 0;
15472        }
15473
15474        // Merge into one list.
15475        int ir = 0;
15476        if (receivers != null) {
15477            // A special case for PACKAGE_ADDED: do not allow the package
15478            // being added to see this broadcast.  This prevents them from
15479            // using this as a back door to get run as soon as they are
15480            // installed.  Maybe in the future we want to have a special install
15481            // broadcast or such for apps, but we'd like to deliberately make
15482            // this decision.
15483            String skipPackages[] = null;
15484            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15485                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15486                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15487                Uri data = intent.getData();
15488                if (data != null) {
15489                    String pkgName = data.getSchemeSpecificPart();
15490                    if (pkgName != null) {
15491                        skipPackages = new String[] { pkgName };
15492                    }
15493                }
15494            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15495                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15496            }
15497            if (skipPackages != null && (skipPackages.length > 0)) {
15498                for (String skipPackage : skipPackages) {
15499                    if (skipPackage != null) {
15500                        int NT = receivers.size();
15501                        for (int it=0; it<NT; it++) {
15502                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15503                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15504                                receivers.remove(it);
15505                                it--;
15506                                NT--;
15507                            }
15508                        }
15509                    }
15510                }
15511            }
15512
15513            int NT = receivers != null ? receivers.size() : 0;
15514            int it = 0;
15515            ResolveInfo curt = null;
15516            BroadcastFilter curr = null;
15517            while (it < NT && ir < NR) {
15518                if (curt == null) {
15519                    curt = (ResolveInfo)receivers.get(it);
15520                }
15521                if (curr == null) {
15522                    curr = registeredReceivers.get(ir);
15523                }
15524                if (curr.getPriority() >= curt.priority) {
15525                    // Insert this broadcast record into the final list.
15526                    receivers.add(it, curr);
15527                    ir++;
15528                    curr = null;
15529                    it++;
15530                    NT++;
15531                } else {
15532                    // Skip to the next ResolveInfo in the final list.
15533                    it++;
15534                    curt = null;
15535                }
15536            }
15537        }
15538        while (ir < NR) {
15539            if (receivers == null) {
15540                receivers = new ArrayList();
15541            }
15542            receivers.add(registeredReceivers.get(ir));
15543            ir++;
15544        }
15545
15546        if ((receivers != null && receivers.size() > 0)
15547                || resultTo != null) {
15548            BroadcastQueue queue = broadcastQueueForIntent(intent);
15549            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15550                    callerPackage, callingPid, callingUid, resolvedType,
15551                    requiredPermission, appOp, receivers, resultTo, resultCode,
15552                    resultData, map, ordered, sticky, false, userId);
15553            if (DEBUG_BROADCAST) Slog.v(
15554                    TAG, "Enqueueing ordered broadcast " + r
15555                    + ": prev had " + queue.mOrderedBroadcasts.size());
15556            if (DEBUG_BROADCAST) {
15557                int seq = r.intent.getIntExtra("seq", -1);
15558                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15559            }
15560            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15561            if (!replaced) {
15562                queue.enqueueOrderedBroadcastLocked(r);
15563                queue.scheduleBroadcastsLocked();
15564            }
15565        }
15566
15567        return ActivityManager.BROADCAST_SUCCESS;
15568    }
15569
15570    final Intent verifyBroadcastLocked(Intent intent) {
15571        // Refuse possible leaked file descriptors
15572        if (intent != null && intent.hasFileDescriptors() == true) {
15573            throw new IllegalArgumentException("File descriptors passed in Intent");
15574        }
15575
15576        int flags = intent.getFlags();
15577
15578        if (!mProcessesReady) {
15579            // if the caller really truly claims to know what they're doing, go
15580            // ahead and allow the broadcast without launching any receivers
15581            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15582                intent = new Intent(intent);
15583                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15584            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15585                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15586                        + " before boot completion");
15587                throw new IllegalStateException("Cannot broadcast before boot completed");
15588            }
15589        }
15590
15591        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15592            throw new IllegalArgumentException(
15593                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15594        }
15595
15596        return intent;
15597    }
15598
15599    public final int broadcastIntent(IApplicationThread caller,
15600            Intent intent, String resolvedType, IIntentReceiver resultTo,
15601            int resultCode, String resultData, Bundle map,
15602            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15603        enforceNotIsolatedCaller("broadcastIntent");
15604        synchronized(this) {
15605            intent = verifyBroadcastLocked(intent);
15606
15607            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15608            final int callingPid = Binder.getCallingPid();
15609            final int callingUid = Binder.getCallingUid();
15610            final long origId = Binder.clearCallingIdentity();
15611            int res = broadcastIntentLocked(callerApp,
15612                    callerApp != null ? callerApp.info.packageName : null,
15613                    intent, resolvedType, resultTo,
15614                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15615                    callingPid, callingUid, userId);
15616            Binder.restoreCallingIdentity(origId);
15617            return res;
15618        }
15619    }
15620
15621    int broadcastIntentInPackage(String packageName, int uid,
15622            Intent intent, String resolvedType, IIntentReceiver resultTo,
15623            int resultCode, String resultData, Bundle map,
15624            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15625        synchronized(this) {
15626            intent = verifyBroadcastLocked(intent);
15627
15628            final long origId = Binder.clearCallingIdentity();
15629            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15630                    resultTo, resultCode, resultData, map, requiredPermission,
15631                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15632            Binder.restoreCallingIdentity(origId);
15633            return res;
15634        }
15635    }
15636
15637    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15638        // Refuse possible leaked file descriptors
15639        if (intent != null && intent.hasFileDescriptors() == true) {
15640            throw new IllegalArgumentException("File descriptors passed in Intent");
15641        }
15642
15643        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15644                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15645
15646        synchronized(this) {
15647            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15648                    != PackageManager.PERMISSION_GRANTED) {
15649                String msg = "Permission Denial: unbroadcastIntent() from pid="
15650                        + Binder.getCallingPid()
15651                        + ", uid=" + Binder.getCallingUid()
15652                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15653                Slog.w(TAG, msg);
15654                throw new SecurityException(msg);
15655            }
15656            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15657            if (stickies != null) {
15658                ArrayList<Intent> list = stickies.get(intent.getAction());
15659                if (list != null) {
15660                    int N = list.size();
15661                    int i;
15662                    for (i=0; i<N; i++) {
15663                        if (intent.filterEquals(list.get(i))) {
15664                            list.remove(i);
15665                            break;
15666                        }
15667                    }
15668                    if (list.size() <= 0) {
15669                        stickies.remove(intent.getAction());
15670                    }
15671                }
15672                if (stickies.size() <= 0) {
15673                    mStickyBroadcasts.remove(userId);
15674                }
15675            }
15676        }
15677    }
15678
15679    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15680            String resultData, Bundle resultExtras, boolean resultAbort) {
15681        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15682        if (r == null) {
15683            Slog.w(TAG, "finishReceiver called but not found on queue");
15684            return false;
15685        }
15686
15687        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15688    }
15689
15690    void backgroundServicesFinishedLocked(int userId) {
15691        for (BroadcastQueue queue : mBroadcastQueues) {
15692            queue.backgroundServicesFinishedLocked(userId);
15693        }
15694    }
15695
15696    public void finishReceiver(IBinder who, int resultCode, String resultData,
15697            Bundle resultExtras, boolean resultAbort) {
15698        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15699
15700        // Refuse possible leaked file descriptors
15701        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15702            throw new IllegalArgumentException("File descriptors passed in Bundle");
15703        }
15704
15705        final long origId = Binder.clearCallingIdentity();
15706        try {
15707            boolean doNext = false;
15708            BroadcastRecord r;
15709
15710            synchronized(this) {
15711                r = broadcastRecordForReceiverLocked(who);
15712                if (r != null) {
15713                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15714                        resultData, resultExtras, resultAbort, true);
15715                }
15716            }
15717
15718            if (doNext) {
15719                r.queue.processNextBroadcast(false);
15720            }
15721            trimApplications();
15722        } finally {
15723            Binder.restoreCallingIdentity(origId);
15724        }
15725    }
15726
15727    // =========================================================
15728    // INSTRUMENTATION
15729    // =========================================================
15730
15731    public boolean startInstrumentation(ComponentName className,
15732            String profileFile, int flags, Bundle arguments,
15733            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15734            int userId, String abiOverride) {
15735        enforceNotIsolatedCaller("startInstrumentation");
15736        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15737                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15738        // Refuse possible leaked file descriptors
15739        if (arguments != null && arguments.hasFileDescriptors()) {
15740            throw new IllegalArgumentException("File descriptors passed in Bundle");
15741        }
15742
15743        synchronized(this) {
15744            InstrumentationInfo ii = null;
15745            ApplicationInfo ai = null;
15746            try {
15747                ii = mContext.getPackageManager().getInstrumentationInfo(
15748                    className, STOCK_PM_FLAGS);
15749                ai = AppGlobals.getPackageManager().getApplicationInfo(
15750                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15751            } catch (PackageManager.NameNotFoundException e) {
15752            } catch (RemoteException e) {
15753            }
15754            if (ii == null) {
15755                reportStartInstrumentationFailure(watcher, className,
15756                        "Unable to find instrumentation info for: " + className);
15757                return false;
15758            }
15759            if (ai == null) {
15760                reportStartInstrumentationFailure(watcher, className,
15761                        "Unable to find instrumentation target package: " + ii.targetPackage);
15762                return false;
15763            }
15764
15765            int match = mContext.getPackageManager().checkSignatures(
15766                    ii.targetPackage, ii.packageName);
15767            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15768                String msg = "Permission Denial: starting instrumentation "
15769                        + className + " from pid="
15770                        + Binder.getCallingPid()
15771                        + ", uid=" + Binder.getCallingPid()
15772                        + " not allowed because package " + ii.packageName
15773                        + " does not have a signature matching the target "
15774                        + ii.targetPackage;
15775                reportStartInstrumentationFailure(watcher, className, msg);
15776                throw new SecurityException(msg);
15777            }
15778
15779            final long origId = Binder.clearCallingIdentity();
15780            // Instrumentation can kill and relaunch even persistent processes
15781            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15782                    "start instr");
15783            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15784            app.instrumentationClass = className;
15785            app.instrumentationInfo = ai;
15786            app.instrumentationProfileFile = profileFile;
15787            app.instrumentationArguments = arguments;
15788            app.instrumentationWatcher = watcher;
15789            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15790            app.instrumentationResultClass = className;
15791            Binder.restoreCallingIdentity(origId);
15792        }
15793
15794        return true;
15795    }
15796
15797    /**
15798     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15799     * error to the logs, but if somebody is watching, send the report there too.  This enables
15800     * the "am" command to report errors with more information.
15801     *
15802     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15803     * @param cn The component name of the instrumentation.
15804     * @param report The error report.
15805     */
15806    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15807            ComponentName cn, String report) {
15808        Slog.w(TAG, report);
15809        try {
15810            if (watcher != null) {
15811                Bundle results = new Bundle();
15812                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15813                results.putString("Error", report);
15814                watcher.instrumentationStatus(cn, -1, results);
15815            }
15816        } catch (RemoteException e) {
15817            Slog.w(TAG, e);
15818        }
15819    }
15820
15821    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15822        if (app.instrumentationWatcher != null) {
15823            try {
15824                // NOTE:  IInstrumentationWatcher *must* be oneway here
15825                app.instrumentationWatcher.instrumentationFinished(
15826                    app.instrumentationClass,
15827                    resultCode,
15828                    results);
15829            } catch (RemoteException e) {
15830            }
15831        }
15832        if (app.instrumentationUiAutomationConnection != null) {
15833            try {
15834                app.instrumentationUiAutomationConnection.shutdown();
15835            } catch (RemoteException re) {
15836                /* ignore */
15837            }
15838            // Only a UiAutomation can set this flag and now that
15839            // it is finished we make sure it is reset to its default.
15840            mUserIsMonkey = false;
15841        }
15842        app.instrumentationWatcher = null;
15843        app.instrumentationUiAutomationConnection = null;
15844        app.instrumentationClass = null;
15845        app.instrumentationInfo = null;
15846        app.instrumentationProfileFile = null;
15847        app.instrumentationArguments = null;
15848
15849        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15850                "finished inst");
15851    }
15852
15853    public void finishInstrumentation(IApplicationThread target,
15854            int resultCode, Bundle results) {
15855        int userId = UserHandle.getCallingUserId();
15856        // Refuse possible leaked file descriptors
15857        if (results != null && results.hasFileDescriptors()) {
15858            throw new IllegalArgumentException("File descriptors passed in Intent");
15859        }
15860
15861        synchronized(this) {
15862            ProcessRecord app = getRecordForAppLocked(target);
15863            if (app == null) {
15864                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15865                return;
15866            }
15867            final long origId = Binder.clearCallingIdentity();
15868            finishInstrumentationLocked(app, resultCode, results);
15869            Binder.restoreCallingIdentity(origId);
15870        }
15871    }
15872
15873    // =========================================================
15874    // CONFIGURATION
15875    // =========================================================
15876
15877    public ConfigurationInfo getDeviceConfigurationInfo() {
15878        ConfigurationInfo config = new ConfigurationInfo();
15879        synchronized (this) {
15880            config.reqTouchScreen = mConfiguration.touchscreen;
15881            config.reqKeyboardType = mConfiguration.keyboard;
15882            config.reqNavigation = mConfiguration.navigation;
15883            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15884                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15885                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15886            }
15887            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15888                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15889                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15890            }
15891            config.reqGlEsVersion = GL_ES_VERSION;
15892        }
15893        return config;
15894    }
15895
15896    ActivityStack getFocusedStack() {
15897        return mStackSupervisor.getFocusedStack();
15898    }
15899
15900    public Configuration getConfiguration() {
15901        Configuration ci;
15902        synchronized(this) {
15903            ci = new Configuration(mConfiguration);
15904        }
15905        return ci;
15906    }
15907
15908    public void updatePersistentConfiguration(Configuration values) {
15909        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15910                "updateConfiguration()");
15911        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15912                "updateConfiguration()");
15913        if (values == null) {
15914            throw new NullPointerException("Configuration must not be null");
15915        }
15916
15917        synchronized(this) {
15918            final long origId = Binder.clearCallingIdentity();
15919            updateConfigurationLocked(values, null, true, false);
15920            Binder.restoreCallingIdentity(origId);
15921        }
15922    }
15923
15924    public void updateConfiguration(Configuration values) {
15925        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15926                "updateConfiguration()");
15927
15928        synchronized(this) {
15929            if (values == null && mWindowManager != null) {
15930                // sentinel: fetch the current configuration from the window manager
15931                values = mWindowManager.computeNewConfiguration();
15932            }
15933
15934            if (mWindowManager != null) {
15935                mProcessList.applyDisplaySize(mWindowManager);
15936            }
15937
15938            final long origId = Binder.clearCallingIdentity();
15939            if (values != null) {
15940                Settings.System.clearConfiguration(values);
15941            }
15942            updateConfigurationLocked(values, null, false, false);
15943            Binder.restoreCallingIdentity(origId);
15944        }
15945    }
15946
15947    /**
15948     * Do either or both things: (1) change the current configuration, and (2)
15949     * make sure the given activity is running with the (now) current
15950     * configuration.  Returns true if the activity has been left running, or
15951     * false if <var>starting</var> is being destroyed to match the new
15952     * configuration.
15953     * @param persistent TODO
15954     */
15955    boolean updateConfigurationLocked(Configuration values,
15956            ActivityRecord starting, boolean persistent, boolean initLocale) {
15957        int changes = 0;
15958
15959        if (values != null) {
15960            Configuration newConfig = new Configuration(mConfiguration);
15961            changes = newConfig.updateFrom(values);
15962            if (changes != 0) {
15963                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15964                    Slog.i(TAG, "Updating configuration to: " + values);
15965                }
15966
15967                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15968
15969                if (values.locale != null && !initLocale) {
15970                    saveLocaleLocked(values.locale,
15971                                     !values.locale.equals(mConfiguration.locale),
15972                                     values.userSetLocale);
15973                }
15974
15975                mConfigurationSeq++;
15976                if (mConfigurationSeq <= 0) {
15977                    mConfigurationSeq = 1;
15978                }
15979                newConfig.seq = mConfigurationSeq;
15980                mConfiguration = newConfig;
15981                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15982                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15983                //mUsageStatsService.noteStartConfig(newConfig);
15984
15985                final Configuration configCopy = new Configuration(mConfiguration);
15986
15987                // TODO: If our config changes, should we auto dismiss any currently
15988                // showing dialogs?
15989                mShowDialogs = shouldShowDialogs(newConfig);
15990
15991                AttributeCache ac = AttributeCache.instance();
15992                if (ac != null) {
15993                    ac.updateConfiguration(configCopy);
15994                }
15995
15996                // Make sure all resources in our process are updated
15997                // right now, so that anyone who is going to retrieve
15998                // resource values after we return will be sure to get
15999                // the new ones.  This is especially important during
16000                // boot, where the first config change needs to guarantee
16001                // all resources have that config before following boot
16002                // code is executed.
16003                mSystemThread.applyConfigurationToResources(configCopy);
16004
16005                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16006                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16007                    msg.obj = new Configuration(configCopy);
16008                    mHandler.sendMessage(msg);
16009                }
16010
16011                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16012                    ProcessRecord app = mLruProcesses.get(i);
16013                    try {
16014                        if (app.thread != null) {
16015                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16016                                    + app.processName + " new config " + mConfiguration);
16017                            app.thread.scheduleConfigurationChanged(configCopy);
16018                        }
16019                    } catch (Exception e) {
16020                    }
16021                }
16022                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16023                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16024                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16025                        | Intent.FLAG_RECEIVER_FOREGROUND);
16026                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16027                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16028                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16029                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16030                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16031                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16032                    broadcastIntentLocked(null, null, intent,
16033                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16034                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16035                }
16036            }
16037        }
16038
16039        boolean kept = true;
16040        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16041        // mainStack is null during startup.
16042        if (mainStack != null) {
16043            if (changes != 0 && starting == null) {
16044                // If the configuration changed, and the caller is not already
16045                // in the process of starting an activity, then find the top
16046                // activity to check if its configuration needs to change.
16047                starting = mainStack.topRunningActivityLocked(null);
16048            }
16049
16050            if (starting != null) {
16051                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16052                // And we need to make sure at this point that all other activities
16053                // are made visible with the correct configuration.
16054                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16055            }
16056        }
16057
16058        if (values != null && mWindowManager != null) {
16059            mWindowManager.setNewConfiguration(mConfiguration);
16060        }
16061
16062        return kept;
16063    }
16064
16065    /**
16066     * Decide based on the configuration whether we should shouw the ANR,
16067     * crash, etc dialogs.  The idea is that if there is no affordnace to
16068     * press the on-screen buttons, we shouldn't show the dialog.
16069     *
16070     * A thought: SystemUI might also want to get told about this, the Power
16071     * dialog / global actions also might want different behaviors.
16072     */
16073    private static final boolean shouldShowDialogs(Configuration config) {
16074        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16075                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16076    }
16077
16078    /**
16079     * Save the locale.  You must be inside a synchronized (this) block.
16080     */
16081    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16082        if(isDiff) {
16083            SystemProperties.set("user.language", l.getLanguage());
16084            SystemProperties.set("user.region", l.getCountry());
16085        }
16086
16087        if(isPersist) {
16088            SystemProperties.set("persist.sys.language", l.getLanguage());
16089            SystemProperties.set("persist.sys.country", l.getCountry());
16090            SystemProperties.set("persist.sys.localevar", l.getVariant());
16091        }
16092    }
16093
16094    @Override
16095    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16096        synchronized (this) {
16097            ActivityRecord srec = ActivityRecord.forToken(token);
16098            if (srec.task != null && srec.task.stack != null) {
16099                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16100            }
16101        }
16102        return false;
16103    }
16104
16105    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16106            Intent resultData) {
16107
16108        synchronized (this) {
16109            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16110            if (stack != null) {
16111                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16112            }
16113            return false;
16114        }
16115    }
16116
16117    public int getLaunchedFromUid(IBinder activityToken) {
16118        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16119        if (srec == null) {
16120            return -1;
16121        }
16122        return srec.launchedFromUid;
16123    }
16124
16125    public String getLaunchedFromPackage(IBinder activityToken) {
16126        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16127        if (srec == null) {
16128            return null;
16129        }
16130        return srec.launchedFromPackage;
16131    }
16132
16133    // =========================================================
16134    // LIFETIME MANAGEMENT
16135    // =========================================================
16136
16137    // Returns which broadcast queue the app is the current [or imminent] receiver
16138    // on, or 'null' if the app is not an active broadcast recipient.
16139    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16140        BroadcastRecord r = app.curReceiver;
16141        if (r != null) {
16142            return r.queue;
16143        }
16144
16145        // It's not the current receiver, but it might be starting up to become one
16146        synchronized (this) {
16147            for (BroadcastQueue queue : mBroadcastQueues) {
16148                r = queue.mPendingBroadcast;
16149                if (r != null && r.curApp == app) {
16150                    // found it; report which queue it's in
16151                    return queue;
16152                }
16153            }
16154        }
16155
16156        return null;
16157    }
16158
16159    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16160            boolean doingAll, long now) {
16161        if (mAdjSeq == app.adjSeq) {
16162            // This adjustment has already been computed.
16163            return app.curRawAdj;
16164        }
16165
16166        if (app.thread == null) {
16167            app.adjSeq = mAdjSeq;
16168            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16169            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16170            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16171        }
16172
16173        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16174        app.adjSource = null;
16175        app.adjTarget = null;
16176        app.empty = false;
16177        app.cached = false;
16178
16179        final int activitiesSize = app.activities.size();
16180
16181        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16182            // The max adjustment doesn't allow this app to be anything
16183            // below foreground, so it is not worth doing work for it.
16184            app.adjType = "fixed";
16185            app.adjSeq = mAdjSeq;
16186            app.curRawAdj = app.maxAdj;
16187            app.foregroundActivities = false;
16188            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16189            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16190            // System processes can do UI, and when they do we want to have
16191            // them trim their memory after the user leaves the UI.  To
16192            // facilitate this, here we need to determine whether or not it
16193            // is currently showing UI.
16194            app.systemNoUi = true;
16195            if (app == TOP_APP) {
16196                app.systemNoUi = false;
16197            } else if (activitiesSize > 0) {
16198                for (int j = 0; j < activitiesSize; j++) {
16199                    final ActivityRecord r = app.activities.get(j);
16200                    if (r.visible) {
16201                        app.systemNoUi = false;
16202                    }
16203                }
16204            }
16205            if (!app.systemNoUi) {
16206                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16207            }
16208            return (app.curAdj=app.maxAdj);
16209        }
16210
16211        app.systemNoUi = false;
16212
16213        // Determine the importance of the process, starting with most
16214        // important to least, and assign an appropriate OOM adjustment.
16215        int adj;
16216        int schedGroup;
16217        int procState;
16218        boolean foregroundActivities = false;
16219        BroadcastQueue queue;
16220        if (app == TOP_APP) {
16221            // The last app on the list is the foreground app.
16222            adj = ProcessList.FOREGROUND_APP_ADJ;
16223            schedGroup = Process.THREAD_GROUP_DEFAULT;
16224            app.adjType = "top-activity";
16225            foregroundActivities = true;
16226            procState = ActivityManager.PROCESS_STATE_TOP;
16227        } else if (app.instrumentationClass != null) {
16228            // Don't want to kill running instrumentation.
16229            adj = ProcessList.FOREGROUND_APP_ADJ;
16230            schedGroup = Process.THREAD_GROUP_DEFAULT;
16231            app.adjType = "instrumentation";
16232            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16233        } else if ((queue = isReceivingBroadcast(app)) != null) {
16234            // An app that is currently receiving a broadcast also
16235            // counts as being in the foreground for OOM killer purposes.
16236            // It's placed in a sched group based on the nature of the
16237            // broadcast as reflected by which queue it's active in.
16238            adj = ProcessList.FOREGROUND_APP_ADJ;
16239            schedGroup = (queue == mFgBroadcastQueue)
16240                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16241            app.adjType = "broadcast";
16242            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16243        } else if (app.executingServices.size() > 0) {
16244            // An app that is currently executing a service callback also
16245            // counts as being in the foreground.
16246            adj = ProcessList.FOREGROUND_APP_ADJ;
16247            schedGroup = app.execServicesFg ?
16248                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16249            app.adjType = "exec-service";
16250            procState = ActivityManager.PROCESS_STATE_SERVICE;
16251            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16252        } else {
16253            // As far as we know the process is empty.  We may change our mind later.
16254            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16255            // At this point we don't actually know the adjustment.  Use the cached adj
16256            // value that the caller wants us to.
16257            adj = cachedAdj;
16258            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16259            app.cached = true;
16260            app.empty = true;
16261            app.adjType = "cch-empty";
16262        }
16263
16264        // Examine all activities if not already foreground.
16265        if (!foregroundActivities && activitiesSize > 0) {
16266            for (int j = 0; j < activitiesSize; j++) {
16267                final ActivityRecord r = app.activities.get(j);
16268                if (r.app != app) {
16269                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16270                            + app + "?!?");
16271                    continue;
16272                }
16273                if (r.visible) {
16274                    // App has a visible activity; only upgrade adjustment.
16275                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16276                        adj = ProcessList.VISIBLE_APP_ADJ;
16277                        app.adjType = "visible";
16278                    }
16279                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16280                        procState = ActivityManager.PROCESS_STATE_TOP;
16281                    }
16282                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16283                    app.cached = false;
16284                    app.empty = false;
16285                    foregroundActivities = true;
16286                    break;
16287                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16288                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16289                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16290                        app.adjType = "pausing";
16291                    }
16292                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16293                        procState = ActivityManager.PROCESS_STATE_TOP;
16294                    }
16295                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16296                    app.cached = false;
16297                    app.empty = false;
16298                    foregroundActivities = true;
16299                } else if (r.state == ActivityState.STOPPING) {
16300                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16301                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16302                        app.adjType = "stopping";
16303                    }
16304                    // For the process state, we will at this point consider the
16305                    // process to be cached.  It will be cached either as an activity
16306                    // or empty depending on whether the activity is finishing.  We do
16307                    // this so that we can treat the process as cached for purposes of
16308                    // memory trimming (determing current memory level, trim command to
16309                    // send to process) since there can be an arbitrary number of stopping
16310                    // processes and they should soon all go into the cached state.
16311                    if (!r.finishing) {
16312                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16313                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16314                        }
16315                    }
16316                    app.cached = false;
16317                    app.empty = false;
16318                    foregroundActivities = true;
16319                } else {
16320                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16321                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16322                        app.adjType = "cch-act";
16323                    }
16324                }
16325            }
16326        }
16327
16328        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16329            if (app.foregroundServices) {
16330                // The user is aware of this app, so make it visible.
16331                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16332                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16333                app.cached = false;
16334                app.adjType = "fg-service";
16335                schedGroup = Process.THREAD_GROUP_DEFAULT;
16336            } else if (app.forcingToForeground != null) {
16337                // The user is aware of this app, so make it visible.
16338                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16339                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16340                app.cached = false;
16341                app.adjType = "force-fg";
16342                app.adjSource = app.forcingToForeground;
16343                schedGroup = Process.THREAD_GROUP_DEFAULT;
16344            }
16345        }
16346
16347        if (app == mHeavyWeightProcess) {
16348            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16349                // We don't want to kill the current heavy-weight process.
16350                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16351                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16352                app.cached = false;
16353                app.adjType = "heavy";
16354            }
16355            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16356                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16357            }
16358        }
16359
16360        if (app == mHomeProcess) {
16361            if (adj > ProcessList.HOME_APP_ADJ) {
16362                // This process is hosting what we currently consider to be the
16363                // home app, so we don't want to let it go into the background.
16364                adj = ProcessList.HOME_APP_ADJ;
16365                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16366                app.cached = false;
16367                app.adjType = "home";
16368            }
16369            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16370                procState = ActivityManager.PROCESS_STATE_HOME;
16371            }
16372        }
16373
16374        if (app == mPreviousProcess && app.activities.size() > 0) {
16375            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16376                // This was the previous process that showed UI to the user.
16377                // We want to try to keep it around more aggressively, to give
16378                // a good experience around switching between two apps.
16379                adj = ProcessList.PREVIOUS_APP_ADJ;
16380                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16381                app.cached = false;
16382                app.adjType = "previous";
16383            }
16384            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16385                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16386            }
16387        }
16388
16389        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16390                + " reason=" + app.adjType);
16391
16392        // By default, we use the computed adjustment.  It may be changed if
16393        // there are applications dependent on our services or providers, but
16394        // this gives us a baseline and makes sure we don't get into an
16395        // infinite recursion.
16396        app.adjSeq = mAdjSeq;
16397        app.curRawAdj = adj;
16398        app.hasStartedServices = false;
16399
16400        if (mBackupTarget != null && app == mBackupTarget.app) {
16401            // If possible we want to avoid killing apps while they're being backed up
16402            if (adj > ProcessList.BACKUP_APP_ADJ) {
16403                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16404                adj = ProcessList.BACKUP_APP_ADJ;
16405                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16406                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16407                }
16408                app.adjType = "backup";
16409                app.cached = false;
16410            }
16411            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16412                procState = ActivityManager.PROCESS_STATE_BACKUP;
16413            }
16414        }
16415
16416        boolean mayBeTop = false;
16417
16418        for (int is = app.services.size()-1;
16419                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16420                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16421                        || procState > ActivityManager.PROCESS_STATE_TOP);
16422                is--) {
16423            ServiceRecord s = app.services.valueAt(is);
16424            if (s.startRequested) {
16425                app.hasStartedServices = true;
16426                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16427                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16428                }
16429                if (app.hasShownUi && app != mHomeProcess) {
16430                    // If this process has shown some UI, let it immediately
16431                    // go to the LRU list because it may be pretty heavy with
16432                    // UI stuff.  We'll tag it with a label just to help
16433                    // debug and understand what is going on.
16434                    if (adj > ProcessList.SERVICE_ADJ) {
16435                        app.adjType = "cch-started-ui-services";
16436                    }
16437                } else {
16438                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16439                        // This service has seen some activity within
16440                        // recent memory, so we will keep its process ahead
16441                        // of the background processes.
16442                        if (adj > ProcessList.SERVICE_ADJ) {
16443                            adj = ProcessList.SERVICE_ADJ;
16444                            app.adjType = "started-services";
16445                            app.cached = false;
16446                        }
16447                    }
16448                    // If we have let the service slide into the background
16449                    // state, still have some text describing what it is doing
16450                    // even though the service no longer has an impact.
16451                    if (adj > ProcessList.SERVICE_ADJ) {
16452                        app.adjType = "cch-started-services";
16453                    }
16454                }
16455            }
16456            for (int conni = s.connections.size()-1;
16457                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16458                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16459                            || procState > ActivityManager.PROCESS_STATE_TOP);
16460                    conni--) {
16461                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16462                for (int i = 0;
16463                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16464                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16465                                || procState > ActivityManager.PROCESS_STATE_TOP);
16466                        i++) {
16467                    // XXX should compute this based on the max of
16468                    // all connected clients.
16469                    ConnectionRecord cr = clist.get(i);
16470                    if (cr.binding.client == app) {
16471                        // Binding to ourself is not interesting.
16472                        continue;
16473                    }
16474                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16475                        ProcessRecord client = cr.binding.client;
16476                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16477                                TOP_APP, doingAll, now);
16478                        int clientProcState = client.curProcState;
16479                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16480                            // If the other app is cached for any reason, for purposes here
16481                            // we are going to consider it empty.  The specific cached state
16482                            // doesn't propagate except under certain conditions.
16483                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16484                        }
16485                        String adjType = null;
16486                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16487                            // Not doing bind OOM management, so treat
16488                            // this guy more like a started service.
16489                            if (app.hasShownUi && app != mHomeProcess) {
16490                                // If this process has shown some UI, let it immediately
16491                                // go to the LRU list because it may be pretty heavy with
16492                                // UI stuff.  We'll tag it with a label just to help
16493                                // debug and understand what is going on.
16494                                if (adj > clientAdj) {
16495                                    adjType = "cch-bound-ui-services";
16496                                }
16497                                app.cached = false;
16498                                clientAdj = adj;
16499                                clientProcState = procState;
16500                            } else {
16501                                if (now >= (s.lastActivity
16502                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16503                                    // This service has not seen activity within
16504                                    // recent memory, so allow it to drop to the
16505                                    // LRU list if there is no other reason to keep
16506                                    // it around.  We'll also tag it with a label just
16507                                    // to help debug and undertand what is going on.
16508                                    if (adj > clientAdj) {
16509                                        adjType = "cch-bound-services";
16510                                    }
16511                                    clientAdj = adj;
16512                                }
16513                            }
16514                        }
16515                        if (adj > clientAdj) {
16516                            // If this process has recently shown UI, and
16517                            // the process that is binding to it is less
16518                            // important than being visible, then we don't
16519                            // care about the binding as much as we care
16520                            // about letting this process get into the LRU
16521                            // list to be killed and restarted if needed for
16522                            // memory.
16523                            if (app.hasShownUi && app != mHomeProcess
16524                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16525                                adjType = "cch-bound-ui-services";
16526                            } else {
16527                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16528                                        |Context.BIND_IMPORTANT)) != 0) {
16529                                    adj = clientAdj;
16530                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16531                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16532                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16533                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16534                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16535                                    adj = clientAdj;
16536                                } else {
16537                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16538                                        adj = ProcessList.VISIBLE_APP_ADJ;
16539                                    }
16540                                }
16541                                if (!client.cached) {
16542                                    app.cached = false;
16543                                }
16544                                adjType = "service";
16545                            }
16546                        }
16547                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16548                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16549                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16550                            }
16551                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16552                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16553                                    // Special handling of clients who are in the top state.
16554                                    // We *may* want to consider this process to be in the
16555                                    // top state as well, but only if there is not another
16556                                    // reason for it to be running.  Being on the top is a
16557                                    // special state, meaning you are specifically running
16558                                    // for the current top app.  If the process is already
16559                                    // running in the background for some other reason, it
16560                                    // is more important to continue considering it to be
16561                                    // in the background state.
16562                                    mayBeTop = true;
16563                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16564                                } else {
16565                                    // Special handling for above-top states (persistent
16566                                    // processes).  These should not bring the current process
16567                                    // into the top state, since they are not on top.  Instead
16568                                    // give them the best state after that.
16569                                    clientProcState =
16570                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16571                                }
16572                            }
16573                        } else {
16574                            if (clientProcState <
16575                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16576                                clientProcState =
16577                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16578                            }
16579                        }
16580                        if (procState > clientProcState) {
16581                            procState = clientProcState;
16582                        }
16583                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16584                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16585                            app.pendingUiClean = true;
16586                        }
16587                        if (adjType != null) {
16588                            app.adjType = adjType;
16589                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16590                                    .REASON_SERVICE_IN_USE;
16591                            app.adjSource = cr.binding.client;
16592                            app.adjSourceProcState = clientProcState;
16593                            app.adjTarget = s.name;
16594                        }
16595                    }
16596                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16597                        app.treatLikeActivity = true;
16598                    }
16599                    final ActivityRecord a = cr.activity;
16600                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16601                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16602                                (a.visible || a.state == ActivityState.RESUMED
16603                                 || a.state == ActivityState.PAUSING)) {
16604                            adj = ProcessList.FOREGROUND_APP_ADJ;
16605                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16606                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16607                            }
16608                            app.cached = false;
16609                            app.adjType = "service";
16610                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16611                                    .REASON_SERVICE_IN_USE;
16612                            app.adjSource = a;
16613                            app.adjSourceProcState = procState;
16614                            app.adjTarget = s.name;
16615                        }
16616                    }
16617                }
16618            }
16619        }
16620
16621        for (int provi = app.pubProviders.size()-1;
16622                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16623                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16624                        || procState > ActivityManager.PROCESS_STATE_TOP);
16625                provi--) {
16626            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16627            for (int i = cpr.connections.size()-1;
16628                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16629                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16630                            || procState > ActivityManager.PROCESS_STATE_TOP);
16631                    i--) {
16632                ContentProviderConnection conn = cpr.connections.get(i);
16633                ProcessRecord client = conn.client;
16634                if (client == app) {
16635                    // Being our own client is not interesting.
16636                    continue;
16637                }
16638                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16639                int clientProcState = client.curProcState;
16640                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16641                    // If the other app is cached for any reason, for purposes here
16642                    // we are going to consider it empty.
16643                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16644                }
16645                if (adj > clientAdj) {
16646                    if (app.hasShownUi && app != mHomeProcess
16647                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16648                        app.adjType = "cch-ui-provider";
16649                    } else {
16650                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16651                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16652                        app.adjType = "provider";
16653                    }
16654                    app.cached &= client.cached;
16655                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16656                            .REASON_PROVIDER_IN_USE;
16657                    app.adjSource = client;
16658                    app.adjSourceProcState = clientProcState;
16659                    app.adjTarget = cpr.name;
16660                }
16661                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16662                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16663                        // Special handling of clients who are in the top state.
16664                        // We *may* want to consider this process to be in the
16665                        // top state as well, but only if there is not another
16666                        // reason for it to be running.  Being on the top is a
16667                        // special state, meaning you are specifically running
16668                        // for the current top app.  If the process is already
16669                        // running in the background for some other reason, it
16670                        // is more important to continue considering it to be
16671                        // in the background state.
16672                        mayBeTop = true;
16673                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16674                    } else {
16675                        // Special handling for above-top states (persistent
16676                        // processes).  These should not bring the current process
16677                        // into the top state, since they are not on top.  Instead
16678                        // give them the best state after that.
16679                        clientProcState =
16680                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16681                    }
16682                }
16683                if (procState > clientProcState) {
16684                    procState = clientProcState;
16685                }
16686                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16687                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16688                }
16689            }
16690            // If the provider has external (non-framework) process
16691            // dependencies, ensure that its adjustment is at least
16692            // FOREGROUND_APP_ADJ.
16693            if (cpr.hasExternalProcessHandles()) {
16694                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16695                    adj = ProcessList.FOREGROUND_APP_ADJ;
16696                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16697                    app.cached = false;
16698                    app.adjType = "provider";
16699                    app.adjTarget = cpr.name;
16700                }
16701                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16702                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16703                }
16704            }
16705        }
16706
16707        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16708            // A client of one of our services or providers is in the top state.  We
16709            // *may* want to be in the top state, but not if we are already running in
16710            // the background for some other reason.  For the decision here, we are going
16711            // to pick out a few specific states that we want to remain in when a client
16712            // is top (states that tend to be longer-term) and otherwise allow it to go
16713            // to the top state.
16714            switch (procState) {
16715                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16716                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16717                case ActivityManager.PROCESS_STATE_SERVICE:
16718                    // These all are longer-term states, so pull them up to the top
16719                    // of the background states, but not all the way to the top state.
16720                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16721                    break;
16722                default:
16723                    // Otherwise, top is a better choice, so take it.
16724                    procState = ActivityManager.PROCESS_STATE_TOP;
16725                    break;
16726            }
16727        }
16728
16729        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16730            if (app.hasClientActivities) {
16731                // This is a cached process, but with client activities.  Mark it so.
16732                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16733                app.adjType = "cch-client-act";
16734            } else if (app.treatLikeActivity) {
16735                // This is a cached process, but somebody wants us to treat it like it has
16736                // an activity, okay!
16737                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16738                app.adjType = "cch-as-act";
16739            }
16740        }
16741
16742        if (adj == ProcessList.SERVICE_ADJ) {
16743            if (doingAll) {
16744                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16745                mNewNumServiceProcs++;
16746                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16747                if (!app.serviceb) {
16748                    // This service isn't far enough down on the LRU list to
16749                    // normally be a B service, but if we are low on RAM and it
16750                    // is large we want to force it down since we would prefer to
16751                    // keep launcher over it.
16752                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16753                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16754                        app.serviceHighRam = true;
16755                        app.serviceb = true;
16756                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16757                    } else {
16758                        mNewNumAServiceProcs++;
16759                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16760                    }
16761                } else {
16762                    app.serviceHighRam = false;
16763                }
16764            }
16765            if (app.serviceb) {
16766                adj = ProcessList.SERVICE_B_ADJ;
16767            }
16768        }
16769
16770        app.curRawAdj = adj;
16771
16772        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16773        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16774        if (adj > app.maxAdj) {
16775            adj = app.maxAdj;
16776            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16777                schedGroup = Process.THREAD_GROUP_DEFAULT;
16778            }
16779        }
16780
16781        // Do final modification to adj.  Everything we do between here and applying
16782        // the final setAdj must be done in this function, because we will also use
16783        // it when computing the final cached adj later.  Note that we don't need to
16784        // worry about this for max adj above, since max adj will always be used to
16785        // keep it out of the cached vaues.
16786        app.curAdj = app.modifyRawOomAdj(adj);
16787        app.curSchedGroup = schedGroup;
16788        app.curProcState = procState;
16789        app.foregroundActivities = foregroundActivities;
16790
16791        return app.curRawAdj;
16792    }
16793
16794    /**
16795     * Schedule PSS collection of a process.
16796     */
16797    void requestPssLocked(ProcessRecord proc, int procState) {
16798        if (mPendingPssProcesses.contains(proc)) {
16799            return;
16800        }
16801        if (mPendingPssProcesses.size() == 0) {
16802            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16803        }
16804        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16805        proc.pssProcState = procState;
16806        mPendingPssProcesses.add(proc);
16807    }
16808
16809    /**
16810     * Schedule PSS collection of all processes.
16811     */
16812    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16813        if (!always) {
16814            if (now < (mLastFullPssTime +
16815                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16816                return;
16817            }
16818        }
16819        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16820        mLastFullPssTime = now;
16821        mFullPssPending = true;
16822        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16823        mPendingPssProcesses.clear();
16824        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16825            ProcessRecord app = mLruProcesses.get(i);
16826            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16827                app.pssProcState = app.setProcState;
16828                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16829                        isSleeping(), now);
16830                mPendingPssProcesses.add(app);
16831            }
16832        }
16833        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16834    }
16835
16836    /**
16837     * Ask a given process to GC right now.
16838     */
16839    final void performAppGcLocked(ProcessRecord app) {
16840        try {
16841            app.lastRequestedGc = SystemClock.uptimeMillis();
16842            if (app.thread != null) {
16843                if (app.reportLowMemory) {
16844                    app.reportLowMemory = false;
16845                    app.thread.scheduleLowMemory();
16846                } else {
16847                    app.thread.processInBackground();
16848                }
16849            }
16850        } catch (Exception e) {
16851            // whatever.
16852        }
16853    }
16854
16855    /**
16856     * Returns true if things are idle enough to perform GCs.
16857     */
16858    private final boolean canGcNowLocked() {
16859        boolean processingBroadcasts = false;
16860        for (BroadcastQueue q : mBroadcastQueues) {
16861            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16862                processingBroadcasts = true;
16863            }
16864        }
16865        return !processingBroadcasts
16866                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16867    }
16868
16869    /**
16870     * Perform GCs on all processes that are waiting for it, but only
16871     * if things are idle.
16872     */
16873    final void performAppGcsLocked() {
16874        final int N = mProcessesToGc.size();
16875        if (N <= 0) {
16876            return;
16877        }
16878        if (canGcNowLocked()) {
16879            while (mProcessesToGc.size() > 0) {
16880                ProcessRecord proc = mProcessesToGc.remove(0);
16881                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16882                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16883                            <= SystemClock.uptimeMillis()) {
16884                        // To avoid spamming the system, we will GC processes one
16885                        // at a time, waiting a few seconds between each.
16886                        performAppGcLocked(proc);
16887                        scheduleAppGcsLocked();
16888                        return;
16889                    } else {
16890                        // It hasn't been long enough since we last GCed this
16891                        // process...  put it in the list to wait for its time.
16892                        addProcessToGcListLocked(proc);
16893                        break;
16894                    }
16895                }
16896            }
16897
16898            scheduleAppGcsLocked();
16899        }
16900    }
16901
16902    /**
16903     * If all looks good, perform GCs on all processes waiting for them.
16904     */
16905    final void performAppGcsIfAppropriateLocked() {
16906        if (canGcNowLocked()) {
16907            performAppGcsLocked();
16908            return;
16909        }
16910        // Still not idle, wait some more.
16911        scheduleAppGcsLocked();
16912    }
16913
16914    /**
16915     * Schedule the execution of all pending app GCs.
16916     */
16917    final void scheduleAppGcsLocked() {
16918        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16919
16920        if (mProcessesToGc.size() > 0) {
16921            // Schedule a GC for the time to the next process.
16922            ProcessRecord proc = mProcessesToGc.get(0);
16923            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16924
16925            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16926            long now = SystemClock.uptimeMillis();
16927            if (when < (now+GC_TIMEOUT)) {
16928                when = now + GC_TIMEOUT;
16929            }
16930            mHandler.sendMessageAtTime(msg, when);
16931        }
16932    }
16933
16934    /**
16935     * Add a process to the array of processes waiting to be GCed.  Keeps the
16936     * list in sorted order by the last GC time.  The process can't already be
16937     * on the list.
16938     */
16939    final void addProcessToGcListLocked(ProcessRecord proc) {
16940        boolean added = false;
16941        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16942            if (mProcessesToGc.get(i).lastRequestedGc <
16943                    proc.lastRequestedGc) {
16944                added = true;
16945                mProcessesToGc.add(i+1, proc);
16946                break;
16947            }
16948        }
16949        if (!added) {
16950            mProcessesToGc.add(0, proc);
16951        }
16952    }
16953
16954    /**
16955     * Set up to ask a process to GC itself.  This will either do it
16956     * immediately, or put it on the list of processes to gc the next
16957     * time things are idle.
16958     */
16959    final void scheduleAppGcLocked(ProcessRecord app) {
16960        long now = SystemClock.uptimeMillis();
16961        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16962            return;
16963        }
16964        if (!mProcessesToGc.contains(app)) {
16965            addProcessToGcListLocked(app);
16966            scheduleAppGcsLocked();
16967        }
16968    }
16969
16970    final void checkExcessivePowerUsageLocked(boolean doKills) {
16971        updateCpuStatsNow();
16972
16973        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16974        boolean doWakeKills = doKills;
16975        boolean doCpuKills = doKills;
16976        if (mLastPowerCheckRealtime == 0) {
16977            doWakeKills = false;
16978        }
16979        if (mLastPowerCheckUptime == 0) {
16980            doCpuKills = false;
16981        }
16982        if (stats.isScreenOn()) {
16983            doWakeKills = false;
16984        }
16985        final long curRealtime = SystemClock.elapsedRealtime();
16986        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16987        final long curUptime = SystemClock.uptimeMillis();
16988        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16989        mLastPowerCheckRealtime = curRealtime;
16990        mLastPowerCheckUptime = curUptime;
16991        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16992            doWakeKills = false;
16993        }
16994        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16995            doCpuKills = false;
16996        }
16997        int i = mLruProcesses.size();
16998        while (i > 0) {
16999            i--;
17000            ProcessRecord app = mLruProcesses.get(i);
17001            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17002                long wtime;
17003                synchronized (stats) {
17004                    wtime = stats.getProcessWakeTime(app.info.uid,
17005                            app.pid, curRealtime);
17006                }
17007                long wtimeUsed = wtime - app.lastWakeTime;
17008                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17009                if (DEBUG_POWER) {
17010                    StringBuilder sb = new StringBuilder(128);
17011                    sb.append("Wake for ");
17012                    app.toShortString(sb);
17013                    sb.append(": over ");
17014                    TimeUtils.formatDuration(realtimeSince, sb);
17015                    sb.append(" used ");
17016                    TimeUtils.formatDuration(wtimeUsed, sb);
17017                    sb.append(" (");
17018                    sb.append((wtimeUsed*100)/realtimeSince);
17019                    sb.append("%)");
17020                    Slog.i(TAG, sb.toString());
17021                    sb.setLength(0);
17022                    sb.append("CPU for ");
17023                    app.toShortString(sb);
17024                    sb.append(": over ");
17025                    TimeUtils.formatDuration(uptimeSince, sb);
17026                    sb.append(" used ");
17027                    TimeUtils.formatDuration(cputimeUsed, sb);
17028                    sb.append(" (");
17029                    sb.append((cputimeUsed*100)/uptimeSince);
17030                    sb.append("%)");
17031                    Slog.i(TAG, sb.toString());
17032                }
17033                // If a process has held a wake lock for more
17034                // than 50% of the time during this period,
17035                // that sounds bad.  Kill!
17036                if (doWakeKills && realtimeSince > 0
17037                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17038                    synchronized (stats) {
17039                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17040                                realtimeSince, wtimeUsed);
17041                    }
17042                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17043                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17044                } else if (doCpuKills && uptimeSince > 0
17045                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17046                    synchronized (stats) {
17047                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17048                                uptimeSince, cputimeUsed);
17049                    }
17050                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17051                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17052                } else {
17053                    app.lastWakeTime = wtime;
17054                    app.lastCpuTime = app.curCpuTime;
17055                }
17056            }
17057        }
17058    }
17059
17060    private final boolean applyOomAdjLocked(ProcessRecord app,
17061            ProcessRecord TOP_APP, boolean doingAll, long now) {
17062        boolean success = true;
17063
17064        if (app.curRawAdj != app.setRawAdj) {
17065            app.setRawAdj = app.curRawAdj;
17066        }
17067
17068        int changes = 0;
17069
17070        if (app.curAdj != app.setAdj) {
17071            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17072            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17073                TAG, "Set " + app.pid + " " + app.processName +
17074                " adj " + app.curAdj + ": " + app.adjType);
17075            app.setAdj = app.curAdj;
17076        }
17077
17078        if (app.setSchedGroup != app.curSchedGroup) {
17079            app.setSchedGroup = app.curSchedGroup;
17080            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17081                    "Setting process group of " + app.processName
17082                    + " to " + app.curSchedGroup);
17083            if (app.waitingToKill != null &&
17084                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17085                app.kill(app.waitingToKill, true);
17086                success = false;
17087            } else {
17088                if (true) {
17089                    long oldId = Binder.clearCallingIdentity();
17090                    try {
17091                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17092                    } catch (Exception e) {
17093                        Slog.w(TAG, "Failed setting process group of " + app.pid
17094                                + " to " + app.curSchedGroup);
17095                        e.printStackTrace();
17096                    } finally {
17097                        Binder.restoreCallingIdentity(oldId);
17098                    }
17099                } else {
17100                    if (app.thread != null) {
17101                        try {
17102                            app.thread.setSchedulingGroup(app.curSchedGroup);
17103                        } catch (RemoteException e) {
17104                        }
17105                    }
17106                }
17107                Process.setSwappiness(app.pid,
17108                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17109            }
17110        }
17111        if (app.repForegroundActivities != app.foregroundActivities) {
17112            app.repForegroundActivities = app.foregroundActivities;
17113            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17114        }
17115        if (app.repProcState != app.curProcState) {
17116            app.repProcState = app.curProcState;
17117            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17118            if (app.thread != null) {
17119                try {
17120                    if (false) {
17121                        //RuntimeException h = new RuntimeException("here");
17122                        Slog.i(TAG, "Sending new process state " + app.repProcState
17123                                + " to " + app /*, h*/);
17124                    }
17125                    app.thread.setProcessState(app.repProcState);
17126                } catch (RemoteException e) {
17127                }
17128            }
17129        }
17130        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17131                app.setProcState)) {
17132            app.lastStateTime = now;
17133            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17134                    isSleeping(), now);
17135            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17136                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17137                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17138                    + (app.nextPssTime-now) + ": " + app);
17139        } else {
17140            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17141                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17142                requestPssLocked(app, app.setProcState);
17143                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17144                        isSleeping(), now);
17145            } else if (false && DEBUG_PSS) {
17146                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17147            }
17148        }
17149        if (app.setProcState != app.curProcState) {
17150            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17151                    "Proc state change of " + app.processName
17152                    + " to " + app.curProcState);
17153            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17154            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17155            if (setImportant && !curImportant) {
17156                // This app is no longer something we consider important enough to allow to
17157                // use arbitrary amounts of battery power.  Note
17158                // its current wake lock time to later know to kill it if
17159                // it is not behaving well.
17160                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17161                synchronized (stats) {
17162                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17163                            app.pid, SystemClock.elapsedRealtime());
17164                }
17165                app.lastCpuTime = app.curCpuTime;
17166
17167            }
17168            app.setProcState = app.curProcState;
17169            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17170                app.notCachedSinceIdle = false;
17171            }
17172            if (!doingAll) {
17173                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17174            } else {
17175                app.procStateChanged = true;
17176            }
17177        }
17178
17179        if (changes != 0) {
17180            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17181            int i = mPendingProcessChanges.size()-1;
17182            ProcessChangeItem item = null;
17183            while (i >= 0) {
17184                item = mPendingProcessChanges.get(i);
17185                if (item.pid == app.pid) {
17186                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17187                    break;
17188                }
17189                i--;
17190            }
17191            if (i < 0) {
17192                // No existing item in pending changes; need a new one.
17193                final int NA = mAvailProcessChanges.size();
17194                if (NA > 0) {
17195                    item = mAvailProcessChanges.remove(NA-1);
17196                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17197                } else {
17198                    item = new ProcessChangeItem();
17199                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17200                }
17201                item.changes = 0;
17202                item.pid = app.pid;
17203                item.uid = app.info.uid;
17204                if (mPendingProcessChanges.size() == 0) {
17205                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17206                            "*** Enqueueing dispatch processes changed!");
17207                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17208                }
17209                mPendingProcessChanges.add(item);
17210            }
17211            item.changes |= changes;
17212            item.processState = app.repProcState;
17213            item.foregroundActivities = app.repForegroundActivities;
17214            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17215                    + Integer.toHexString(System.identityHashCode(item))
17216                    + " " + app.toShortString() + ": changes=" + item.changes
17217                    + " procState=" + item.processState
17218                    + " foreground=" + item.foregroundActivities
17219                    + " type=" + app.adjType + " source=" + app.adjSource
17220                    + " target=" + app.adjTarget);
17221        }
17222
17223        return success;
17224    }
17225
17226    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17227        if (proc.thread != null) {
17228            if (proc.baseProcessTracker != null) {
17229                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17230            }
17231            if (proc.repProcState >= 0) {
17232                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17233                        proc.repProcState);
17234            }
17235        }
17236    }
17237
17238    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17239            ProcessRecord TOP_APP, boolean doingAll, long now) {
17240        if (app.thread == null) {
17241            return false;
17242        }
17243
17244        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17245
17246        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17247    }
17248
17249    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17250            boolean oomAdj) {
17251        if (isForeground != proc.foregroundServices) {
17252            proc.foregroundServices = isForeground;
17253            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17254                    proc.info.uid);
17255            if (isForeground) {
17256                if (curProcs == null) {
17257                    curProcs = new ArrayList<ProcessRecord>();
17258                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17259                }
17260                if (!curProcs.contains(proc)) {
17261                    curProcs.add(proc);
17262                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17263                            proc.info.packageName, proc.info.uid);
17264                }
17265            } else {
17266                if (curProcs != null) {
17267                    if (curProcs.remove(proc)) {
17268                        mBatteryStatsService.noteEvent(
17269                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17270                                proc.info.packageName, proc.info.uid);
17271                        if (curProcs.size() <= 0) {
17272                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17273                        }
17274                    }
17275                }
17276            }
17277            if (oomAdj) {
17278                updateOomAdjLocked();
17279            }
17280        }
17281    }
17282
17283    private final ActivityRecord resumedAppLocked() {
17284        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17285        String pkg;
17286        int uid;
17287        if (act != null) {
17288            pkg = act.packageName;
17289            uid = act.info.applicationInfo.uid;
17290        } else {
17291            pkg = null;
17292            uid = -1;
17293        }
17294        // Has the UID or resumed package name changed?
17295        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17296                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17297            if (mCurResumedPackage != null) {
17298                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17299                        mCurResumedPackage, mCurResumedUid);
17300            }
17301            mCurResumedPackage = pkg;
17302            mCurResumedUid = uid;
17303            if (mCurResumedPackage != null) {
17304                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17305                        mCurResumedPackage, mCurResumedUid);
17306            }
17307        }
17308        return act;
17309    }
17310
17311    final boolean updateOomAdjLocked(ProcessRecord app) {
17312        final ActivityRecord TOP_ACT = resumedAppLocked();
17313        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17314        final boolean wasCached = app.cached;
17315
17316        mAdjSeq++;
17317
17318        // This is the desired cached adjusment we want to tell it to use.
17319        // If our app is currently cached, we know it, and that is it.  Otherwise,
17320        // we don't know it yet, and it needs to now be cached we will then
17321        // need to do a complete oom adj.
17322        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17323                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17324        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17325                SystemClock.uptimeMillis());
17326        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17327            // Changed to/from cached state, so apps after it in the LRU
17328            // list may also be changed.
17329            updateOomAdjLocked();
17330        }
17331        return success;
17332    }
17333
17334    final void updateOomAdjLocked() {
17335        final ActivityRecord TOP_ACT = resumedAppLocked();
17336        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17337        final long now = SystemClock.uptimeMillis();
17338        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17339        final int N = mLruProcesses.size();
17340
17341        if (false) {
17342            RuntimeException e = new RuntimeException();
17343            e.fillInStackTrace();
17344            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17345        }
17346
17347        mAdjSeq++;
17348        mNewNumServiceProcs = 0;
17349        mNewNumAServiceProcs = 0;
17350
17351        final int emptyProcessLimit;
17352        final int cachedProcessLimit;
17353        if (mProcessLimit <= 0) {
17354            emptyProcessLimit = cachedProcessLimit = 0;
17355        } else if (mProcessLimit == 1) {
17356            emptyProcessLimit = 1;
17357            cachedProcessLimit = 0;
17358        } else {
17359            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17360            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17361        }
17362
17363        // Let's determine how many processes we have running vs.
17364        // how many slots we have for background processes; we may want
17365        // to put multiple processes in a slot of there are enough of
17366        // them.
17367        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17368                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17369        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17370        if (numEmptyProcs > cachedProcessLimit) {
17371            // If there are more empty processes than our limit on cached
17372            // processes, then use the cached process limit for the factor.
17373            // This ensures that the really old empty processes get pushed
17374            // down to the bottom, so if we are running low on memory we will
17375            // have a better chance at keeping around more cached processes
17376            // instead of a gazillion empty processes.
17377            numEmptyProcs = cachedProcessLimit;
17378        }
17379        int emptyFactor = numEmptyProcs/numSlots;
17380        if (emptyFactor < 1) emptyFactor = 1;
17381        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17382        if (cachedFactor < 1) cachedFactor = 1;
17383        int stepCached = 0;
17384        int stepEmpty = 0;
17385        int numCached = 0;
17386        int numEmpty = 0;
17387        int numTrimming = 0;
17388
17389        mNumNonCachedProcs = 0;
17390        mNumCachedHiddenProcs = 0;
17391
17392        // First update the OOM adjustment for each of the
17393        // application processes based on their current state.
17394        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17395        int nextCachedAdj = curCachedAdj+1;
17396        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17397        int nextEmptyAdj = curEmptyAdj+2;
17398        for (int i=N-1; i>=0; i--) {
17399            ProcessRecord app = mLruProcesses.get(i);
17400            if (!app.killedByAm && app.thread != null) {
17401                app.procStateChanged = false;
17402                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17403
17404                // If we haven't yet assigned the final cached adj
17405                // to the process, do that now.
17406                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17407                    switch (app.curProcState) {
17408                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17409                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17410                            // This process is a cached process holding activities...
17411                            // assign it the next cached value for that type, and then
17412                            // step that cached level.
17413                            app.curRawAdj = curCachedAdj;
17414                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17415                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17416                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17417                                    + ")");
17418                            if (curCachedAdj != nextCachedAdj) {
17419                                stepCached++;
17420                                if (stepCached >= cachedFactor) {
17421                                    stepCached = 0;
17422                                    curCachedAdj = nextCachedAdj;
17423                                    nextCachedAdj += 2;
17424                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17425                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17426                                    }
17427                                }
17428                            }
17429                            break;
17430                        default:
17431                            // For everything else, assign next empty cached process
17432                            // level and bump that up.  Note that this means that
17433                            // long-running services that have dropped down to the
17434                            // cached level will be treated as empty (since their process
17435                            // state is still as a service), which is what we want.
17436                            app.curRawAdj = curEmptyAdj;
17437                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17438                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17439                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17440                                    + ")");
17441                            if (curEmptyAdj != nextEmptyAdj) {
17442                                stepEmpty++;
17443                                if (stepEmpty >= emptyFactor) {
17444                                    stepEmpty = 0;
17445                                    curEmptyAdj = nextEmptyAdj;
17446                                    nextEmptyAdj += 2;
17447                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17448                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17449                                    }
17450                                }
17451                            }
17452                            break;
17453                    }
17454                }
17455
17456                applyOomAdjLocked(app, TOP_APP, true, now);
17457
17458                // Count the number of process types.
17459                switch (app.curProcState) {
17460                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17461                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17462                        mNumCachedHiddenProcs++;
17463                        numCached++;
17464                        if (numCached > cachedProcessLimit) {
17465                            app.kill("cached #" + numCached, true);
17466                        }
17467                        break;
17468                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17469                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17470                                && app.lastActivityTime < oldTime) {
17471                            app.kill("empty for "
17472                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17473                                    / 1000) + "s", true);
17474                        } else {
17475                            numEmpty++;
17476                            if (numEmpty > emptyProcessLimit) {
17477                                app.kill("empty #" + numEmpty, true);
17478                            }
17479                        }
17480                        break;
17481                    default:
17482                        mNumNonCachedProcs++;
17483                        break;
17484                }
17485
17486                if (app.isolated && app.services.size() <= 0) {
17487                    // If this is an isolated process, and there are no
17488                    // services running in it, then the process is no longer
17489                    // needed.  We agressively kill these because we can by
17490                    // definition not re-use the same process again, and it is
17491                    // good to avoid having whatever code was running in them
17492                    // left sitting around after no longer needed.
17493                    app.kill("isolated not needed", true);
17494                }
17495
17496                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17497                        && !app.killedByAm) {
17498                    numTrimming++;
17499                }
17500            }
17501        }
17502
17503        mNumServiceProcs = mNewNumServiceProcs;
17504
17505        // Now determine the memory trimming level of background processes.
17506        // Unfortunately we need to start at the back of the list to do this
17507        // properly.  We only do this if the number of background apps we
17508        // are managing to keep around is less than half the maximum we desire;
17509        // if we are keeping a good number around, we'll let them use whatever
17510        // memory they want.
17511        final int numCachedAndEmpty = numCached + numEmpty;
17512        int memFactor;
17513        if (numCached <= ProcessList.TRIM_CACHED_APPS
17514                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17515            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17516                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17517            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17518                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17519            } else {
17520                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17521            }
17522        } else {
17523            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17524        }
17525        // We always allow the memory level to go up (better).  We only allow it to go
17526        // down if we are in a state where that is allowed, *and* the total number of processes
17527        // has gone down since last time.
17528        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17529                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17530                + " last=" + mLastNumProcesses);
17531        if (memFactor > mLastMemoryLevel) {
17532            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17533                memFactor = mLastMemoryLevel;
17534                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17535            }
17536        }
17537        mLastMemoryLevel = memFactor;
17538        mLastNumProcesses = mLruProcesses.size();
17539        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17540        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17541        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17542            if (mLowRamStartTime == 0) {
17543                mLowRamStartTime = now;
17544            }
17545            int step = 0;
17546            int fgTrimLevel;
17547            switch (memFactor) {
17548                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17549                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17550                    break;
17551                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17552                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17553                    break;
17554                default:
17555                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17556                    break;
17557            }
17558            int factor = numTrimming/3;
17559            int minFactor = 2;
17560            if (mHomeProcess != null) minFactor++;
17561            if (mPreviousProcess != null) minFactor++;
17562            if (factor < minFactor) factor = minFactor;
17563            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17564            for (int i=N-1; i>=0; i--) {
17565                ProcessRecord app = mLruProcesses.get(i);
17566                if (allChanged || app.procStateChanged) {
17567                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17568                    app.procStateChanged = false;
17569                }
17570                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17571                        && !app.killedByAm) {
17572                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17573                        try {
17574                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17575                                    "Trimming memory of " + app.processName
17576                                    + " to " + curLevel);
17577                            app.thread.scheduleTrimMemory(curLevel);
17578                        } catch (RemoteException e) {
17579                        }
17580                        if (false) {
17581                            // For now we won't do this; our memory trimming seems
17582                            // to be good enough at this point that destroying
17583                            // activities causes more harm than good.
17584                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17585                                    && app != mHomeProcess && app != mPreviousProcess) {
17586                                // Need to do this on its own message because the stack may not
17587                                // be in a consistent state at this point.
17588                                // For these apps we will also finish their activities
17589                                // to help them free memory.
17590                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17591                            }
17592                        }
17593                    }
17594                    app.trimMemoryLevel = curLevel;
17595                    step++;
17596                    if (step >= factor) {
17597                        step = 0;
17598                        switch (curLevel) {
17599                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17600                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17601                                break;
17602                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17603                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17604                                break;
17605                        }
17606                    }
17607                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17608                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17609                            && app.thread != null) {
17610                        try {
17611                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17612                                    "Trimming memory of heavy-weight " + app.processName
17613                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17614                            app.thread.scheduleTrimMemory(
17615                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17616                        } catch (RemoteException e) {
17617                        }
17618                    }
17619                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17620                } else {
17621                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17622                            || app.systemNoUi) && app.pendingUiClean) {
17623                        // If this application is now in the background and it
17624                        // had done UI, then give it the special trim level to
17625                        // have it free UI resources.
17626                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17627                        if (app.trimMemoryLevel < level && app.thread != null) {
17628                            try {
17629                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17630                                        "Trimming memory of bg-ui " + app.processName
17631                                        + " to " + level);
17632                                app.thread.scheduleTrimMemory(level);
17633                            } catch (RemoteException e) {
17634                            }
17635                        }
17636                        app.pendingUiClean = false;
17637                    }
17638                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17639                        try {
17640                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17641                                    "Trimming memory of fg " + app.processName
17642                                    + " to " + fgTrimLevel);
17643                            app.thread.scheduleTrimMemory(fgTrimLevel);
17644                        } catch (RemoteException e) {
17645                        }
17646                    }
17647                    app.trimMemoryLevel = fgTrimLevel;
17648                }
17649            }
17650        } else {
17651            if (mLowRamStartTime != 0) {
17652                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17653                mLowRamStartTime = 0;
17654            }
17655            for (int i=N-1; i>=0; i--) {
17656                ProcessRecord app = mLruProcesses.get(i);
17657                if (allChanged || app.procStateChanged) {
17658                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17659                    app.procStateChanged = false;
17660                }
17661                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17662                        || app.systemNoUi) && app.pendingUiClean) {
17663                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17664                            && app.thread != null) {
17665                        try {
17666                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17667                                    "Trimming memory of ui hidden " + app.processName
17668                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17669                            app.thread.scheduleTrimMemory(
17670                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17671                        } catch (RemoteException e) {
17672                        }
17673                    }
17674                    app.pendingUiClean = false;
17675                }
17676                app.trimMemoryLevel = 0;
17677            }
17678        }
17679
17680        if (mAlwaysFinishActivities) {
17681            // Need to do this on its own message because the stack may not
17682            // be in a consistent state at this point.
17683            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17684        }
17685
17686        if (allChanged) {
17687            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17688        }
17689
17690        if (mProcessStats.shouldWriteNowLocked(now)) {
17691            mHandler.post(new Runnable() {
17692                @Override public void run() {
17693                    synchronized (ActivityManagerService.this) {
17694                        mProcessStats.writeStateAsyncLocked();
17695                    }
17696                }
17697            });
17698        }
17699
17700        if (DEBUG_OOM_ADJ) {
17701            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17702        }
17703    }
17704
17705    final void trimApplications() {
17706        synchronized (this) {
17707            int i;
17708
17709            // First remove any unused application processes whose package
17710            // has been removed.
17711            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17712                final ProcessRecord app = mRemovedProcesses.get(i);
17713                if (app.activities.size() == 0
17714                        && app.curReceiver == null && app.services.size() == 0) {
17715                    Slog.i(
17716                        TAG, "Exiting empty application process "
17717                        + app.processName + " ("
17718                        + (app.thread != null ? app.thread.asBinder() : null)
17719                        + ")\n");
17720                    if (app.pid > 0 && app.pid != MY_PID) {
17721                        app.kill("empty", false);
17722                    } else {
17723                        try {
17724                            app.thread.scheduleExit();
17725                        } catch (Exception e) {
17726                            // Ignore exceptions.
17727                        }
17728                    }
17729                    cleanUpApplicationRecordLocked(app, false, true, -1);
17730                    mRemovedProcesses.remove(i);
17731
17732                    if (app.persistent) {
17733                        addAppLocked(app.info, false, null /* ABI override */);
17734                    }
17735                }
17736            }
17737
17738            // Now update the oom adj for all processes.
17739            updateOomAdjLocked();
17740        }
17741    }
17742
17743    /** This method sends the specified signal to each of the persistent apps */
17744    public void signalPersistentProcesses(int sig) throws RemoteException {
17745        if (sig != Process.SIGNAL_USR1) {
17746            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17747        }
17748
17749        synchronized (this) {
17750            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17751                    != PackageManager.PERMISSION_GRANTED) {
17752                throw new SecurityException("Requires permission "
17753                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17754            }
17755
17756            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17757                ProcessRecord r = mLruProcesses.get(i);
17758                if (r.thread != null && r.persistent) {
17759                    Process.sendSignal(r.pid, sig);
17760                }
17761            }
17762        }
17763    }
17764
17765    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17766        if (proc == null || proc == mProfileProc) {
17767            proc = mProfileProc;
17768            profileType = mProfileType;
17769            clearProfilerLocked();
17770        }
17771        if (proc == null) {
17772            return;
17773        }
17774        try {
17775            proc.thread.profilerControl(false, null, profileType);
17776        } catch (RemoteException e) {
17777            throw new IllegalStateException("Process disappeared");
17778        }
17779    }
17780
17781    private void clearProfilerLocked() {
17782        if (mProfileFd != null) {
17783            try {
17784                mProfileFd.close();
17785            } catch (IOException e) {
17786            }
17787        }
17788        mProfileApp = null;
17789        mProfileProc = null;
17790        mProfileFile = null;
17791        mProfileType = 0;
17792        mAutoStopProfiler = false;
17793        mSamplingInterval = 0;
17794    }
17795
17796    public boolean profileControl(String process, int userId, boolean start,
17797            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17798
17799        try {
17800            synchronized (this) {
17801                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17802                // its own permission.
17803                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17804                        != PackageManager.PERMISSION_GRANTED) {
17805                    throw new SecurityException("Requires permission "
17806                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17807                }
17808
17809                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17810                    throw new IllegalArgumentException("null profile info or fd");
17811                }
17812
17813                ProcessRecord proc = null;
17814                if (process != null) {
17815                    proc = findProcessLocked(process, userId, "profileControl");
17816                }
17817
17818                if (start && (proc == null || proc.thread == null)) {
17819                    throw new IllegalArgumentException("Unknown process: " + process);
17820                }
17821
17822                if (start) {
17823                    stopProfilerLocked(null, 0);
17824                    setProfileApp(proc.info, proc.processName, profilerInfo);
17825                    mProfileProc = proc;
17826                    mProfileType = profileType;
17827                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17828                    try {
17829                        fd = fd.dup();
17830                    } catch (IOException e) {
17831                        fd = null;
17832                    }
17833                    profilerInfo.profileFd = fd;
17834                    proc.thread.profilerControl(start, profilerInfo, profileType);
17835                    fd = null;
17836                    mProfileFd = null;
17837                } else {
17838                    stopProfilerLocked(proc, profileType);
17839                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17840                        try {
17841                            profilerInfo.profileFd.close();
17842                        } catch (IOException e) {
17843                        }
17844                    }
17845                }
17846
17847                return true;
17848            }
17849        } catch (RemoteException e) {
17850            throw new IllegalStateException("Process disappeared");
17851        } finally {
17852            if (profilerInfo != null && profilerInfo.profileFd != null) {
17853                try {
17854                    profilerInfo.profileFd.close();
17855                } catch (IOException e) {
17856                }
17857            }
17858        }
17859    }
17860
17861    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17862        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17863                userId, true, ALLOW_FULL_ONLY, callName, null);
17864        ProcessRecord proc = null;
17865        try {
17866            int pid = Integer.parseInt(process);
17867            synchronized (mPidsSelfLocked) {
17868                proc = mPidsSelfLocked.get(pid);
17869            }
17870        } catch (NumberFormatException e) {
17871        }
17872
17873        if (proc == null) {
17874            ArrayMap<String, SparseArray<ProcessRecord>> all
17875                    = mProcessNames.getMap();
17876            SparseArray<ProcessRecord> procs = all.get(process);
17877            if (procs != null && procs.size() > 0) {
17878                proc = procs.valueAt(0);
17879                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17880                    for (int i=1; i<procs.size(); i++) {
17881                        ProcessRecord thisProc = procs.valueAt(i);
17882                        if (thisProc.userId == userId) {
17883                            proc = thisProc;
17884                            break;
17885                        }
17886                    }
17887                }
17888            }
17889        }
17890
17891        return proc;
17892    }
17893
17894    public boolean dumpHeap(String process, int userId, boolean managed,
17895            String path, ParcelFileDescriptor fd) throws RemoteException {
17896
17897        try {
17898            synchronized (this) {
17899                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17900                // its own permission (same as profileControl).
17901                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17902                        != PackageManager.PERMISSION_GRANTED) {
17903                    throw new SecurityException("Requires permission "
17904                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17905                }
17906
17907                if (fd == null) {
17908                    throw new IllegalArgumentException("null fd");
17909                }
17910
17911                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17912                if (proc == null || proc.thread == null) {
17913                    throw new IllegalArgumentException("Unknown process: " + process);
17914                }
17915
17916                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17917                if (!isDebuggable) {
17918                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17919                        throw new SecurityException("Process not debuggable: " + proc);
17920                    }
17921                }
17922
17923                proc.thread.dumpHeap(managed, path, fd);
17924                fd = null;
17925                return true;
17926            }
17927        } catch (RemoteException e) {
17928            throw new IllegalStateException("Process disappeared");
17929        } finally {
17930            if (fd != null) {
17931                try {
17932                    fd.close();
17933                } catch (IOException e) {
17934                }
17935            }
17936        }
17937    }
17938
17939    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17940    public void monitor() {
17941        synchronized (this) { }
17942    }
17943
17944    void onCoreSettingsChange(Bundle settings) {
17945        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17946            ProcessRecord processRecord = mLruProcesses.get(i);
17947            try {
17948                if (processRecord.thread != null) {
17949                    processRecord.thread.setCoreSettings(settings);
17950                }
17951            } catch (RemoteException re) {
17952                /* ignore */
17953            }
17954        }
17955    }
17956
17957    // Multi-user methods
17958
17959    /**
17960     * Start user, if its not already running, but don't bring it to foreground.
17961     */
17962    @Override
17963    public boolean startUserInBackground(final int userId) {
17964        return startUser(userId, /* foreground */ false);
17965    }
17966
17967    /**
17968     * Start user, if its not already running, and bring it to foreground.
17969     */
17970    boolean startUserInForeground(final int userId, Dialog dlg) {
17971        boolean result = startUser(userId, /* foreground */ true);
17972        dlg.dismiss();
17973        return result;
17974    }
17975
17976    /**
17977     * Refreshes the list of users related to the current user when either a
17978     * user switch happens or when a new related user is started in the
17979     * background.
17980     */
17981    private void updateCurrentProfileIdsLocked() {
17982        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17983                mCurrentUserId, false /* enabledOnly */);
17984        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17985        for (int i = 0; i < currentProfileIds.length; i++) {
17986            currentProfileIds[i] = profiles.get(i).id;
17987        }
17988        mCurrentProfileIds = currentProfileIds;
17989
17990        synchronized (mUserProfileGroupIdsSelfLocked) {
17991            mUserProfileGroupIdsSelfLocked.clear();
17992            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17993            for (int i = 0; i < users.size(); i++) {
17994                UserInfo user = users.get(i);
17995                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17996                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17997                }
17998            }
17999        }
18000    }
18001
18002    private Set getProfileIdsLocked(int userId) {
18003        Set userIds = new HashSet<Integer>();
18004        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18005                userId, false /* enabledOnly */);
18006        for (UserInfo user : profiles) {
18007            userIds.add(Integer.valueOf(user.id));
18008        }
18009        return userIds;
18010    }
18011
18012    @Override
18013    public boolean switchUser(final int userId) {
18014        String userName;
18015        synchronized (this) {
18016            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18017            if (userInfo == null) {
18018                Slog.w(TAG, "No user info for user #" + userId);
18019                return false;
18020            }
18021            if (userInfo.isManagedProfile()) {
18022                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18023                return false;
18024            }
18025            userName = userInfo.name;
18026            mTargetUserId = userId;
18027        }
18028        mHandler.removeMessages(START_USER_SWITCH_MSG);
18029        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18030        return true;
18031    }
18032
18033    private void showUserSwitchDialog(int userId, String userName) {
18034        // The dialog will show and then initiate the user switch by calling startUserInForeground
18035        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18036                true /* above system */);
18037        d.show();
18038    }
18039
18040    private boolean startUser(final int userId, final boolean foreground) {
18041        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18042                != PackageManager.PERMISSION_GRANTED) {
18043            String msg = "Permission Denial: switchUser() from pid="
18044                    + Binder.getCallingPid()
18045                    + ", uid=" + Binder.getCallingUid()
18046                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18047            Slog.w(TAG, msg);
18048            throw new SecurityException(msg);
18049        }
18050
18051        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18052
18053        final long ident = Binder.clearCallingIdentity();
18054        try {
18055            synchronized (this) {
18056                final int oldUserId = mCurrentUserId;
18057                if (oldUserId == userId) {
18058                    return true;
18059                }
18060
18061                mStackSupervisor.setLockTaskModeLocked(null, false);
18062
18063                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18064                if (userInfo == null) {
18065                    Slog.w(TAG, "No user info for user #" + userId);
18066                    return false;
18067                }
18068                if (foreground && userInfo.isManagedProfile()) {
18069                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18070                    return false;
18071                }
18072
18073                if (foreground) {
18074                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18075                            R.anim.screen_user_enter);
18076                }
18077
18078                boolean needStart = false;
18079
18080                // If the user we are switching to is not currently started, then
18081                // we need to start it now.
18082                if (mStartedUsers.get(userId) == null) {
18083                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18084                    updateStartedUserArrayLocked();
18085                    needStart = true;
18086                }
18087
18088                final Integer userIdInt = Integer.valueOf(userId);
18089                mUserLru.remove(userIdInt);
18090                mUserLru.add(userIdInt);
18091
18092                if (foreground) {
18093                    mCurrentUserId = userId;
18094                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18095                    updateCurrentProfileIdsLocked();
18096                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18097                    // Once the internal notion of the active user has switched, we lock the device
18098                    // with the option to show the user switcher on the keyguard.
18099                    mWindowManager.lockNow(null);
18100                } else {
18101                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18102                    updateCurrentProfileIdsLocked();
18103                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18104                    mUserLru.remove(currentUserIdInt);
18105                    mUserLru.add(currentUserIdInt);
18106                }
18107
18108                final UserStartedState uss = mStartedUsers.get(userId);
18109
18110                // Make sure user is in the started state.  If it is currently
18111                // stopping, we need to knock that off.
18112                if (uss.mState == UserStartedState.STATE_STOPPING) {
18113                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18114                    // so we can just fairly silently bring the user back from
18115                    // the almost-dead.
18116                    uss.mState = UserStartedState.STATE_RUNNING;
18117                    updateStartedUserArrayLocked();
18118                    needStart = true;
18119                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18120                    // This means ACTION_SHUTDOWN has been sent, so we will
18121                    // need to treat this as a new boot of the user.
18122                    uss.mState = UserStartedState.STATE_BOOTING;
18123                    updateStartedUserArrayLocked();
18124                    needStart = true;
18125                }
18126
18127                if (uss.mState == UserStartedState.STATE_BOOTING) {
18128                    // Booting up a new user, need to tell system services about it.
18129                    // Note that this is on the same handler as scheduling of broadcasts,
18130                    // which is important because it needs to go first.
18131                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18132                }
18133
18134                if (foreground) {
18135                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18136                            oldUserId));
18137                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18138                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18139                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18140                            oldUserId, userId, uss));
18141                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18142                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18143                }
18144
18145                if (needStart) {
18146                    // Send USER_STARTED broadcast
18147                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18148                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18149                            | Intent.FLAG_RECEIVER_FOREGROUND);
18150                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18151                    broadcastIntentLocked(null, null, intent,
18152                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18153                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18154                }
18155
18156                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18157                    if (userId != UserHandle.USER_OWNER) {
18158                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18159                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18160                        broadcastIntentLocked(null, null, intent, null,
18161                                new IIntentReceiver.Stub() {
18162                                    public void performReceive(Intent intent, int resultCode,
18163                                            String data, Bundle extras, boolean ordered,
18164                                            boolean sticky, int sendingUser) {
18165                                        onUserInitialized(uss, foreground, oldUserId, userId);
18166                                    }
18167                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18168                                true, false, MY_PID, Process.SYSTEM_UID,
18169                                userId);
18170                        uss.initializing = true;
18171                    } else {
18172                        getUserManagerLocked().makeInitialized(userInfo.id);
18173                    }
18174                }
18175
18176                if (foreground) {
18177                    if (!uss.initializing) {
18178                        moveUserToForeground(uss, oldUserId, userId);
18179                    }
18180                } else {
18181                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18182                }
18183
18184                if (needStart) {
18185                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18186                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18187                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18188                    broadcastIntentLocked(null, null, intent,
18189                            null, new IIntentReceiver.Stub() {
18190                                @Override
18191                                public void performReceive(Intent intent, int resultCode, String data,
18192                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18193                                        throws RemoteException {
18194                                }
18195                            }, 0, null, null,
18196                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18197                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18198                }
18199            }
18200        } finally {
18201            Binder.restoreCallingIdentity(ident);
18202        }
18203
18204        return true;
18205    }
18206
18207    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18208        long ident = Binder.clearCallingIdentity();
18209        try {
18210            Intent intent;
18211            if (oldUserId >= 0) {
18212                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18213                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18214                int count = profiles.size();
18215                for (int i = 0; i < count; i++) {
18216                    int profileUserId = profiles.get(i).id;
18217                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18218                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18219                            | Intent.FLAG_RECEIVER_FOREGROUND);
18220                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18221                    broadcastIntentLocked(null, null, intent,
18222                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18223                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18224                }
18225            }
18226            if (newUserId >= 0) {
18227                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18228                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18229                int count = profiles.size();
18230                for (int i = 0; i < count; i++) {
18231                    int profileUserId = profiles.get(i).id;
18232                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18233                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18234                            | Intent.FLAG_RECEIVER_FOREGROUND);
18235                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18236                    broadcastIntentLocked(null, null, intent,
18237                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18238                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18239                }
18240                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18241                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18242                        | Intent.FLAG_RECEIVER_FOREGROUND);
18243                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18244                broadcastIntentLocked(null, null, intent,
18245                        null, null, 0, null, null,
18246                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18247                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18248            }
18249        } finally {
18250            Binder.restoreCallingIdentity(ident);
18251        }
18252    }
18253
18254    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18255            final int newUserId) {
18256        final int N = mUserSwitchObservers.beginBroadcast();
18257        if (N > 0) {
18258            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18259                int mCount = 0;
18260                @Override
18261                public void sendResult(Bundle data) throws RemoteException {
18262                    synchronized (ActivityManagerService.this) {
18263                        if (mCurUserSwitchCallback == this) {
18264                            mCount++;
18265                            if (mCount == N) {
18266                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18267                            }
18268                        }
18269                    }
18270                }
18271            };
18272            synchronized (this) {
18273                uss.switching = true;
18274                mCurUserSwitchCallback = callback;
18275            }
18276            for (int i=0; i<N; i++) {
18277                try {
18278                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18279                            newUserId, callback);
18280                } catch (RemoteException e) {
18281                }
18282            }
18283        } else {
18284            synchronized (this) {
18285                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18286            }
18287        }
18288        mUserSwitchObservers.finishBroadcast();
18289    }
18290
18291    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18292        synchronized (this) {
18293            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18294            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18295        }
18296    }
18297
18298    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18299        mCurUserSwitchCallback = null;
18300        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18301        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18302                oldUserId, newUserId, uss));
18303    }
18304
18305    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18306        synchronized (this) {
18307            if (foreground) {
18308                moveUserToForeground(uss, oldUserId, newUserId);
18309            }
18310        }
18311
18312        completeSwitchAndInitalize(uss, newUserId, true, false);
18313    }
18314
18315    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18316        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18317        if (homeInFront) {
18318            startHomeActivityLocked(newUserId);
18319        } else {
18320            mStackSupervisor.resumeTopActivitiesLocked();
18321        }
18322        EventLogTags.writeAmSwitchUser(newUserId);
18323        getUserManagerLocked().userForeground(newUserId);
18324        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18325    }
18326
18327    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18328        completeSwitchAndInitalize(uss, newUserId, false, true);
18329    }
18330
18331    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18332            boolean clearInitializing, boolean clearSwitching) {
18333        boolean unfrozen = false;
18334        synchronized (this) {
18335            if (clearInitializing) {
18336                uss.initializing = false;
18337                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18338            }
18339            if (clearSwitching) {
18340                uss.switching = false;
18341            }
18342            if (!uss.switching && !uss.initializing) {
18343                mWindowManager.stopFreezingScreen();
18344                unfrozen = true;
18345            }
18346        }
18347        if (unfrozen) {
18348            final int N = mUserSwitchObservers.beginBroadcast();
18349            for (int i=0; i<N; i++) {
18350                try {
18351                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18352                } catch (RemoteException e) {
18353                }
18354            }
18355            mUserSwitchObservers.finishBroadcast();
18356        }
18357    }
18358
18359    void scheduleStartProfilesLocked() {
18360        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18361            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18362                    DateUtils.SECOND_IN_MILLIS);
18363        }
18364    }
18365
18366    void startProfilesLocked() {
18367        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18368        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18369                mCurrentUserId, false /* enabledOnly */);
18370        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18371        for (UserInfo user : profiles) {
18372            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18373                    && user.id != mCurrentUserId) {
18374                toStart.add(user);
18375            }
18376        }
18377        final int n = toStart.size();
18378        int i = 0;
18379        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18380            startUserInBackground(toStart.get(i).id);
18381        }
18382        if (i < n) {
18383            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18384        }
18385    }
18386
18387    void finishUserBoot(UserStartedState uss) {
18388        synchronized (this) {
18389            if (uss.mState == UserStartedState.STATE_BOOTING
18390                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18391                uss.mState = UserStartedState.STATE_RUNNING;
18392                final int userId = uss.mHandle.getIdentifier();
18393                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18394                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18395                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18396                broadcastIntentLocked(null, null, intent,
18397                        null, null, 0, null, null,
18398                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18399                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18400            }
18401        }
18402    }
18403
18404    void finishUserSwitch(UserStartedState uss) {
18405        synchronized (this) {
18406            finishUserBoot(uss);
18407
18408            startProfilesLocked();
18409
18410            int num = mUserLru.size();
18411            int i = 0;
18412            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18413                Integer oldUserId = mUserLru.get(i);
18414                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18415                if (oldUss == null) {
18416                    // Shouldn't happen, but be sane if it does.
18417                    mUserLru.remove(i);
18418                    num--;
18419                    continue;
18420                }
18421                if (oldUss.mState == UserStartedState.STATE_STOPPING
18422                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18423                    // This user is already stopping, doesn't count.
18424                    num--;
18425                    i++;
18426                    continue;
18427                }
18428                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18429                    // Owner and current can't be stopped, but count as running.
18430                    i++;
18431                    continue;
18432                }
18433                // This is a user to be stopped.
18434                stopUserLocked(oldUserId, null);
18435                num--;
18436                i++;
18437            }
18438        }
18439    }
18440
18441    @Override
18442    public int stopUser(final int userId, final IStopUserCallback callback) {
18443        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18444                != PackageManager.PERMISSION_GRANTED) {
18445            String msg = "Permission Denial: switchUser() from pid="
18446                    + Binder.getCallingPid()
18447                    + ", uid=" + Binder.getCallingUid()
18448                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18449            Slog.w(TAG, msg);
18450            throw new SecurityException(msg);
18451        }
18452        if (userId <= 0) {
18453            throw new IllegalArgumentException("Can't stop primary user " + userId);
18454        }
18455        synchronized (this) {
18456            return stopUserLocked(userId, callback);
18457        }
18458    }
18459
18460    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18461        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18462        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18463            return ActivityManager.USER_OP_IS_CURRENT;
18464        }
18465
18466        final UserStartedState uss = mStartedUsers.get(userId);
18467        if (uss == null) {
18468            // User is not started, nothing to do...  but we do need to
18469            // callback if requested.
18470            if (callback != null) {
18471                mHandler.post(new Runnable() {
18472                    @Override
18473                    public void run() {
18474                        try {
18475                            callback.userStopped(userId);
18476                        } catch (RemoteException e) {
18477                        }
18478                    }
18479                });
18480            }
18481            return ActivityManager.USER_OP_SUCCESS;
18482        }
18483
18484        if (callback != null) {
18485            uss.mStopCallbacks.add(callback);
18486        }
18487
18488        if (uss.mState != UserStartedState.STATE_STOPPING
18489                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18490            uss.mState = UserStartedState.STATE_STOPPING;
18491            updateStartedUserArrayLocked();
18492
18493            long ident = Binder.clearCallingIdentity();
18494            try {
18495                // We are going to broadcast ACTION_USER_STOPPING and then
18496                // once that is done send a final ACTION_SHUTDOWN and then
18497                // stop the user.
18498                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18499                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18500                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18501                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18502                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18503                // This is the result receiver for the final shutdown broadcast.
18504                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18505                    @Override
18506                    public void performReceive(Intent intent, int resultCode, String data,
18507                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18508                        finishUserStop(uss);
18509                    }
18510                };
18511                // This is the result receiver for the initial stopping broadcast.
18512                final IIntentReceiver stoppingReceiver = 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                        // On to the next.
18517                        synchronized (ActivityManagerService.this) {
18518                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18519                                // Whoops, we are being started back up.  Abort, abort!
18520                                return;
18521                            }
18522                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18523                        }
18524                        mBatteryStatsService.noteEvent(
18525                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18526                                Integer.toString(userId), userId);
18527                        mSystemServiceManager.stopUser(userId);
18528                        broadcastIntentLocked(null, null, shutdownIntent,
18529                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18530                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18531                    }
18532                };
18533                // Kick things off.
18534                broadcastIntentLocked(null, null, stoppingIntent,
18535                        null, stoppingReceiver, 0, null, null,
18536                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18537                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18538            } finally {
18539                Binder.restoreCallingIdentity(ident);
18540            }
18541        }
18542
18543        return ActivityManager.USER_OP_SUCCESS;
18544    }
18545
18546    void finishUserStop(UserStartedState uss) {
18547        final int userId = uss.mHandle.getIdentifier();
18548        boolean stopped;
18549        ArrayList<IStopUserCallback> callbacks;
18550        synchronized (this) {
18551            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18552            if (mStartedUsers.get(userId) != uss) {
18553                stopped = false;
18554            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18555                stopped = false;
18556            } else {
18557                stopped = true;
18558                // User can no longer run.
18559                mStartedUsers.remove(userId);
18560                mUserLru.remove(Integer.valueOf(userId));
18561                updateStartedUserArrayLocked();
18562
18563                // Clean up all state and processes associated with the user.
18564                // Kill all the processes for the user.
18565                forceStopUserLocked(userId, "finish user");
18566            }
18567
18568            // Explicitly remove the old information in mRecentTasks.
18569            removeRecentTasksForUserLocked(userId);
18570        }
18571
18572        for (int i=0; i<callbacks.size(); i++) {
18573            try {
18574                if (stopped) callbacks.get(i).userStopped(userId);
18575                else callbacks.get(i).userStopAborted(userId);
18576            } catch (RemoteException e) {
18577            }
18578        }
18579
18580        if (stopped) {
18581            mSystemServiceManager.cleanupUser(userId);
18582            synchronized (this) {
18583                mStackSupervisor.removeUserLocked(userId);
18584            }
18585        }
18586    }
18587
18588    @Override
18589    public UserInfo getCurrentUser() {
18590        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18591                != PackageManager.PERMISSION_GRANTED) && (
18592                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18593                != PackageManager.PERMISSION_GRANTED)) {
18594            String msg = "Permission Denial: getCurrentUser() from pid="
18595                    + Binder.getCallingPid()
18596                    + ", uid=" + Binder.getCallingUid()
18597                    + " requires " + INTERACT_ACROSS_USERS;
18598            Slog.w(TAG, msg);
18599            throw new SecurityException(msg);
18600        }
18601        synchronized (this) {
18602            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18603            return getUserManagerLocked().getUserInfo(userId);
18604        }
18605    }
18606
18607    int getCurrentUserIdLocked() {
18608        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18609    }
18610
18611    @Override
18612    public boolean isUserRunning(int userId, boolean orStopped) {
18613        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18614                != PackageManager.PERMISSION_GRANTED) {
18615            String msg = "Permission Denial: isUserRunning() from pid="
18616                    + Binder.getCallingPid()
18617                    + ", uid=" + Binder.getCallingUid()
18618                    + " requires " + INTERACT_ACROSS_USERS;
18619            Slog.w(TAG, msg);
18620            throw new SecurityException(msg);
18621        }
18622        synchronized (this) {
18623            return isUserRunningLocked(userId, orStopped);
18624        }
18625    }
18626
18627    boolean isUserRunningLocked(int userId, boolean orStopped) {
18628        UserStartedState state = mStartedUsers.get(userId);
18629        if (state == null) {
18630            return false;
18631        }
18632        if (orStopped) {
18633            return true;
18634        }
18635        return state.mState != UserStartedState.STATE_STOPPING
18636                && state.mState != UserStartedState.STATE_SHUTDOWN;
18637    }
18638
18639    @Override
18640    public int[] getRunningUserIds() {
18641        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18642                != PackageManager.PERMISSION_GRANTED) {
18643            String msg = "Permission Denial: isUserRunning() from pid="
18644                    + Binder.getCallingPid()
18645                    + ", uid=" + Binder.getCallingUid()
18646                    + " requires " + INTERACT_ACROSS_USERS;
18647            Slog.w(TAG, msg);
18648            throw new SecurityException(msg);
18649        }
18650        synchronized (this) {
18651            return mStartedUserArray;
18652        }
18653    }
18654
18655    private void updateStartedUserArrayLocked() {
18656        int num = 0;
18657        for (int i=0; i<mStartedUsers.size();  i++) {
18658            UserStartedState uss = mStartedUsers.valueAt(i);
18659            // This list does not include stopping users.
18660            if (uss.mState != UserStartedState.STATE_STOPPING
18661                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18662                num++;
18663            }
18664        }
18665        mStartedUserArray = new int[num];
18666        num = 0;
18667        for (int i=0; i<mStartedUsers.size();  i++) {
18668            UserStartedState uss = mStartedUsers.valueAt(i);
18669            if (uss.mState != UserStartedState.STATE_STOPPING
18670                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18671                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18672                num++;
18673            }
18674        }
18675    }
18676
18677    @Override
18678    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18679        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18680                != PackageManager.PERMISSION_GRANTED) {
18681            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18682                    + Binder.getCallingPid()
18683                    + ", uid=" + Binder.getCallingUid()
18684                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18685            Slog.w(TAG, msg);
18686            throw new SecurityException(msg);
18687        }
18688
18689        mUserSwitchObservers.register(observer);
18690    }
18691
18692    @Override
18693    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18694        mUserSwitchObservers.unregister(observer);
18695    }
18696
18697    private boolean userExists(int userId) {
18698        if (userId == 0) {
18699            return true;
18700        }
18701        UserManagerService ums = getUserManagerLocked();
18702        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18703    }
18704
18705    int[] getUsersLocked() {
18706        UserManagerService ums = getUserManagerLocked();
18707        return ums != null ? ums.getUserIds() : new int[] { 0 };
18708    }
18709
18710    UserManagerService getUserManagerLocked() {
18711        if (mUserManager == null) {
18712            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18713            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18714        }
18715        return mUserManager;
18716    }
18717
18718    private int applyUserId(int uid, int userId) {
18719        return UserHandle.getUid(userId, uid);
18720    }
18721
18722    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18723        if (info == null) return null;
18724        ApplicationInfo newInfo = new ApplicationInfo(info);
18725        newInfo.uid = applyUserId(info.uid, userId);
18726        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18727                + info.packageName;
18728        return newInfo;
18729    }
18730
18731    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18732        if (aInfo == null
18733                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18734            return aInfo;
18735        }
18736
18737        ActivityInfo info = new ActivityInfo(aInfo);
18738        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18739        return info;
18740    }
18741
18742    private final class LocalService extends ActivityManagerInternal {
18743        @Override
18744        public void goingToSleep() {
18745            ActivityManagerService.this.goingToSleep();
18746        }
18747
18748        @Override
18749        public void wakingUp() {
18750            ActivityManagerService.this.wakingUp();
18751        }
18752
18753        @Override
18754        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18755                String processName, String abiOverride, int uid, Runnable crashHandler) {
18756            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18757                    processName, abiOverride, uid, crashHandler);
18758        }
18759    }
18760
18761    /**
18762     * An implementation of IAppTask, that allows an app to manage its own tasks via
18763     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18764     * only the process that calls getAppTasks() can call the AppTask methods.
18765     */
18766    class AppTaskImpl extends IAppTask.Stub {
18767        private int mTaskId;
18768        private int mCallingUid;
18769
18770        public AppTaskImpl(int taskId, int callingUid) {
18771            mTaskId = taskId;
18772            mCallingUid = callingUid;
18773        }
18774
18775        private void checkCaller() {
18776            if (mCallingUid != Binder.getCallingUid()) {
18777                throw new SecurityException("Caller " + mCallingUid
18778                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18779            }
18780        }
18781
18782        @Override
18783        public void finishAndRemoveTask() {
18784            checkCaller();
18785
18786            synchronized (ActivityManagerService.this) {
18787                long origId = Binder.clearCallingIdentity();
18788                try {
18789                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18790                    if (tr == null) {
18791                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18792                    }
18793                    // Only kill the process if we are not a new document
18794                    int flags = tr.getBaseIntent().getFlags();
18795                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18796                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18797                    removeTaskByIdLocked(mTaskId,
18798                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18799                } finally {
18800                    Binder.restoreCallingIdentity(origId);
18801                }
18802            }
18803        }
18804
18805        @Override
18806        public ActivityManager.RecentTaskInfo getTaskInfo() {
18807            checkCaller();
18808
18809            synchronized (ActivityManagerService.this) {
18810                long origId = Binder.clearCallingIdentity();
18811                try {
18812                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18813                    if (tr == null) {
18814                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18815                    }
18816                    return createRecentTaskInfoFromTaskRecord(tr);
18817                } finally {
18818                    Binder.restoreCallingIdentity(origId);
18819                }
18820            }
18821        }
18822
18823        @Override
18824        public void moveToFront() {
18825            checkCaller();
18826
18827            final TaskRecord tr;
18828            synchronized (ActivityManagerService.this) {
18829                tr = recentTaskForIdLocked(mTaskId);
18830                if (tr == null) {
18831                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18832                }
18833                if (tr.getRootActivity() != null) {
18834                    long origId = Binder.clearCallingIdentity();
18835                    try {
18836                        moveTaskToFrontLocked(tr.taskId, 0, null);
18837                        return;
18838                    } finally {
18839                        Binder.restoreCallingIdentity(origId);
18840                    }
18841                }
18842            }
18843
18844            startActivityFromRecentsInner(tr.taskId, null);
18845        }
18846
18847        @Override
18848        public int startActivity(IBinder whoThread, String callingPackage,
18849                Intent intent, String resolvedType, Bundle options) {
18850            checkCaller();
18851
18852            int callingUser = UserHandle.getCallingUserId();
18853            TaskRecord tr;
18854            IApplicationThread appThread;
18855            synchronized (ActivityManagerService.this) {
18856                tr = recentTaskForIdLocked(mTaskId);
18857                if (tr == null) {
18858                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18859                }
18860                appThread = ApplicationThreadNative.asInterface(whoThread);
18861                if (appThread == null) {
18862                    throw new IllegalArgumentException("Bad app thread " + appThread);
18863                }
18864            }
18865            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18866                    resolvedType, null, null, null, null, 0, 0, null, null,
18867                    null, options, callingUser, null, tr);
18868        }
18869
18870        @Override
18871        public void setExcludeFromRecents(boolean exclude) {
18872            checkCaller();
18873
18874            synchronized (ActivityManagerService.this) {
18875                long origId = Binder.clearCallingIdentity();
18876                try {
18877                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18878                    if (tr == null) {
18879                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18880                    }
18881                    Intent intent = tr.getBaseIntent();
18882                    if (exclude) {
18883                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18884                    } else {
18885                        intent.setFlags(intent.getFlags()
18886                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18887                    }
18888                } finally {
18889                    Binder.restoreCallingIdentity(origId);
18890                }
18891            }
18892        }
18893    }
18894}
18895