ActivityManagerService.java revision c7c04890beaf459808aeecb7418913939abbd169
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    ArraySet<TaskRecord> mTmpRecents = new ArraySet<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    /**
3845     * Update the recent tasks lists: make sure tasks should still be here (their
3846     * applications / activities still exist), update their availability, fixup ordering
3847     * of affiliations.
3848     */
3849    void cleanupRecentTasksLocked(int userId) {
3850        if (mRecentTasks == null) {
3851            // Happens when called from the packagemanager broadcast before boot.
3852            return;
3853        }
3854
3855        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3856        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3857        final IPackageManager pm = AppGlobals.getPackageManager();
3858        final ActivityInfo dummyAct = new ActivityInfo();
3859        final ApplicationInfo dummyApp = new ApplicationInfo();
3860
3861        int N = mRecentTasks.size();
3862
3863        int[] users = userId == UserHandle.USER_ALL
3864                ? getUsersLocked() : new int[] { userId };
3865        for (int user : users) {
3866            for (int i = 0; i < N; i++) {
3867                TaskRecord task = mRecentTasks.get(i);
3868                if (task.userId != user) {
3869                    // Only look at tasks for the user ID of interest.
3870                    continue;
3871                }
3872                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3873                    // This situation is broken, and we should just get rid of it now.
3874                    mRecentTasks.remove(i);
3875                    task.removedFromRecents(mTaskPersister);
3876                    i--;
3877                    N--;
3878                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3879                    continue;
3880                }
3881                // Check whether this activity is currently available.
3882                if (task.realActivity != null) {
3883                    ActivityInfo ai = availActCache.get(task.realActivity);
3884                    if (ai == null) {
3885                        try {
3886                            ai = pm.getActivityInfo(task.realActivity,
3887                                    PackageManager.GET_UNINSTALLED_PACKAGES
3888                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3889                        } catch (RemoteException e) {
3890                            // Will never happen.
3891                            continue;
3892                        }
3893                        if (ai == null) {
3894                            ai = dummyAct;
3895                        }
3896                        availActCache.put(task.realActivity, ai);
3897                    }
3898                    if (ai == dummyAct) {
3899                        // This could be either because the activity no longer exists, or the
3900                        // app is temporarily gone.  For the former we want to remove the recents
3901                        // entry; for the latter we want to mark it as unavailable.
3902                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3903                        if (app == null) {
3904                            try {
3905                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3906                                        PackageManager.GET_UNINSTALLED_PACKAGES
3907                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3908                            } catch (RemoteException e) {
3909                                // Will never happen.
3910                                continue;
3911                            }
3912                            if (app == null) {
3913                                app = dummyApp;
3914                            }
3915                            availAppCache.put(task.realActivity.getPackageName(), app);
3916                        }
3917                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3918                            // Doesn't exist any more!  Good-bye.
3919                            mRecentTasks.remove(i);
3920                            task.removedFromRecents(mTaskPersister);
3921                            i--;
3922                            N--;
3923                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3924                            continue;
3925                        } else {
3926                            // Otherwise just not available for now.
3927                            if (task.isAvailable) {
3928                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3929                                        + task);
3930                            }
3931                            task.isAvailable = false;
3932                        }
3933                    } else {
3934                        if (!ai.enabled || !ai.applicationInfo.enabled
3935                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3936                            if (task.isAvailable) {
3937                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3938                                        + task + " (enabled=" + ai.enabled + "/"
3939                                        + ai.applicationInfo.enabled +  " flags="
3940                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3941                            }
3942                            task.isAvailable = false;
3943                        } else {
3944                            if (!task.isAvailable) {
3945                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3946                                        + task);
3947                            }
3948                            task.isAvailable = true;
3949                        }
3950                    }
3951                }
3952            }
3953        }
3954
3955        // Verify the affiliate chain for each task.
3956        for (int i = 0; i < N; ) {
3957            TaskRecord task = mRecentTasks.remove(i);
3958            if (mTmpRecents.contains(task)) {
3959                continue;
3960            }
3961            int affiliatedTaskId = task.mAffiliatedTaskId;
3962            while (true) {
3963                TaskRecord next = task.mNextAffiliate;
3964                if (next == null) {
3965                    break;
3966                }
3967                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3968                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3969                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3970                    task.setNextAffiliate(null);
3971                    if (next.mPrevAffiliate == task) {
3972                        next.setPrevAffiliate(null);
3973                    }
3974                    break;
3975                }
3976                if (next.mPrevAffiliate != task) {
3977                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3978                            next.mPrevAffiliate + " task=" + task);
3979                    next.setPrevAffiliate(null);
3980                    task.setNextAffiliate(null);
3981                    break;
3982                }
3983                if (!mRecentTasks.contains(next)) {
3984                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3985                    task.setNextAffiliate(null);
3986                    // We know that next.mPrevAffiliate is always task, from above, so clear
3987                    // its previous affiliate.
3988                    next.setPrevAffiliate(null);
3989                    break;
3990                }
3991                task = next;
3992            }
3993            // task is now the end of the list
3994            do {
3995                mRecentTasks.remove(task);
3996                mRecentTasks.add(i++, task);
3997                mTmpRecents.add(task);
3998                task.inRecents = true;
3999            } while ((task = task.mPrevAffiliate) != null);
4000        }
4001        mTmpRecents.clear();
4002        // mRecentTasks is now in sorted, affiliated order.
4003    }
4004
4005    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4006        int N = mRecentTasks.size();
4007        TaskRecord top = task;
4008        int topIndex = taskIndex;
4009        while (top.mNextAffiliate != null && topIndex > 0) {
4010            top = top.mNextAffiliate;
4011            topIndex--;
4012        }
4013        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4014                + topIndex + " from intial " + taskIndex);
4015        // Find the end of the chain, doing a sanity check along the way.
4016        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4017        int endIndex = topIndex;
4018        TaskRecord prev = top;
4019        while (endIndex < N) {
4020            TaskRecord cur = mRecentTasks.get(endIndex);
4021            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4022                    + endIndex + " " + cur);
4023            if (cur == top) {
4024                // Verify start of the chain.
4025                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4026                    Slog.wtf(TAG, "Bad chain @" + endIndex
4027                            + ": first task has next affiliate: " + prev);
4028                    sane = false;
4029                    break;
4030                }
4031            } else {
4032                // Verify middle of the chain's next points back to the one before.
4033                if (cur.mNextAffiliate != prev
4034                        || cur.mNextAffiliateTaskId != prev.taskId) {
4035                    Slog.wtf(TAG, "Bad chain @" + endIndex
4036                            + ": middle task " + cur + " @" + endIndex
4037                            + " has bad next affiliate "
4038                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4039                            + ", expected " + prev);
4040                    sane = false;
4041                    break;
4042                }
4043            }
4044            if (cur.mPrevAffiliateTaskId == -1) {
4045                // Chain ends here.
4046                if (cur.mPrevAffiliate != null) {
4047                    Slog.wtf(TAG, "Bad chain @" + endIndex
4048                            + ": last task " + cur + " has previous affiliate "
4049                            + cur.mPrevAffiliate);
4050                    sane = false;
4051                }
4052                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4053                break;
4054            } else {
4055                // Verify middle of the chain's prev points to a valid item.
4056                if (cur.mPrevAffiliate == null) {
4057                    Slog.wtf(TAG, "Bad chain @" + endIndex
4058                            + ": task " + cur + " has previous affiliate "
4059                            + cur.mPrevAffiliate + " but should be id "
4060                            + cur.mPrevAffiliate);
4061                    sane = false;
4062                    break;
4063                }
4064            }
4065            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4066                Slog.wtf(TAG, "Bad chain @" + endIndex
4067                        + ": task " + cur + " has affiliated id "
4068                        + cur.mAffiliatedTaskId + " but should be "
4069                        + task.mAffiliatedTaskId);
4070                sane = false;
4071                break;
4072            }
4073            prev = cur;
4074            endIndex++;
4075            if (endIndex >= N) {
4076                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4077                        + ": last task " + prev);
4078                sane = false;
4079                break;
4080            }
4081        }
4082        if (sane) {
4083            if (endIndex < taskIndex) {
4084                Slog.wtf(TAG, "Bad chain @" + endIndex
4085                        + ": did not extend to task " + task + " @" + taskIndex);
4086                sane = false;
4087            }
4088        }
4089        if (sane) {
4090            // All looks good, we can just move all of the affiliated tasks
4091            // to the top.
4092            for (int i=topIndex; i<=endIndex; i++) {
4093                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4094                        + " from " + i + " to " + (i-topIndex));
4095                TaskRecord cur = mRecentTasks.remove(i);
4096                mRecentTasks.add(i-topIndex, cur);
4097            }
4098            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4099                    + " to " + endIndex);
4100            return true;
4101        }
4102
4103        // Whoops, couldn't do it.
4104        return false;
4105    }
4106
4107    final void addRecentTaskLocked(TaskRecord task) {
4108        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4109                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4110
4111        int N = mRecentTasks.size();
4112        // Quick case: check if the top-most recent task is the same.
4113        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4114            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4115            return;
4116        }
4117        // Another quick case: check if this is part of a set of affiliated
4118        // tasks that are at the top.
4119        if (isAffiliated && N > 0 && task.inRecents
4120                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4121            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4122                    + " at top when adding " + task);
4123            return;
4124        }
4125        // Another quick case: never add voice sessions.
4126        if (task.voiceSession != null) {
4127            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4128            return;
4129        }
4130
4131        boolean needAffiliationFix = false;
4132
4133        // Slightly less quick case: the task is already in recents, so all we need
4134        // to do is move it.
4135        if (task.inRecents) {
4136            int taskIndex = mRecentTasks.indexOf(task);
4137            if (taskIndex >= 0) {
4138                if (!isAffiliated) {
4139                    // Simple case: this is not an affiliated task, so we just move it to the front.
4140                    mRecentTasks.remove(taskIndex);
4141                    mRecentTasks.add(0, task);
4142                    notifyTaskPersisterLocked(task, false);
4143                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4144                            + " from " + taskIndex);
4145                    return;
4146                } else {
4147                    // More complicated: need to keep all affiliated tasks together.
4148                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4149                        // All went well.
4150                        return;
4151                    }
4152
4153                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4154                    // everything and then go through our general path of adding a new task.
4155                    needAffiliationFix = true;
4156                }
4157            } else {
4158                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4159                needAffiliationFix = true;
4160            }
4161        }
4162
4163        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4164        trimRecentsForTask(task, true);
4165
4166        N = mRecentTasks.size();
4167        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4168            final TaskRecord tr = mRecentTasks.remove(N - 1);
4169            tr.removedFromRecents(mTaskPersister);
4170            N--;
4171        }
4172        task.inRecents = true;
4173        if (!isAffiliated || needAffiliationFix) {
4174            // If this is a simple non-affiliated task, or we had some failure trying to
4175            // handle it as part of an affilated task, then just place it at the top.
4176            mRecentTasks.add(0, task);
4177        } else if (isAffiliated) {
4178            // If this is a new affiliated task, then move all of the affiliated tasks
4179            // to the front and insert this new one.
4180            TaskRecord other = task.mNextAffiliate;
4181            if (other == null) {
4182                other = task.mPrevAffiliate;
4183            }
4184            if (other != null) {
4185                int otherIndex = mRecentTasks.indexOf(other);
4186                if (otherIndex >= 0) {
4187                    // Insert new task at appropriate location.
4188                    int taskIndex;
4189                    if (other == task.mNextAffiliate) {
4190                        // We found the index of our next affiliation, which is who is
4191                        // before us in the list, so add after that point.
4192                        taskIndex = otherIndex+1;
4193                    } else {
4194                        // We found the index of our previous affiliation, which is who is
4195                        // after us in the list, so add at their position.
4196                        taskIndex = otherIndex;
4197                    }
4198                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4199                            + taskIndex + ": " + task);
4200                    mRecentTasks.add(taskIndex, task);
4201
4202                    // Now move everything to the front.
4203                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4204                        // All went well.
4205                        return;
4206                    }
4207
4208                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4209                    // everything and then go through our general path of adding a new task.
4210                    needAffiliationFix = true;
4211                } else {
4212                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4213                            + other);
4214                    needAffiliationFix = true;
4215                }
4216            } else {
4217                if (DEBUG_RECENTS) Slog.d(TAG,
4218                        "addRecent: adding affiliated task without next/prev:" + task);
4219                needAffiliationFix = true;
4220            }
4221        }
4222        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4223
4224        if (needAffiliationFix) {
4225            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4226            cleanupRecentTasksLocked(task.userId);
4227        }
4228    }
4229
4230    /**
4231     * If needed, remove oldest existing entries in recents that are for the same kind
4232     * of task as the given one.
4233     */
4234    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4235        int N = mRecentTasks.size();
4236        final Intent intent = task.intent;
4237        final boolean document = intent != null && intent.isDocument();
4238
4239        int maxRecents = task.maxRecents - 1;
4240        for (int i=0; i<N; i++) {
4241            final TaskRecord tr = mRecentTasks.get(i);
4242            if (task != tr) {
4243                if (task.userId != tr.userId) {
4244                    continue;
4245                }
4246                if (i > MAX_RECENT_BITMAPS) {
4247                    tr.freeLastThumbnail();
4248                }
4249                final Intent trIntent = tr.intent;
4250                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4251                    (intent == null || !intent.filterEquals(trIntent))) {
4252                    continue;
4253                }
4254                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4255                if (document && trIsDocument) {
4256                    // These are the same document activity (not necessarily the same doc).
4257                    if (maxRecents > 0) {
4258                        --maxRecents;
4259                        continue;
4260                    }
4261                    // Hit the maximum number of documents for this task. Fall through
4262                    // and remove this document from recents.
4263                } else if (document || trIsDocument) {
4264                    // Only one of these is a document. Not the droid we're looking for.
4265                    continue;
4266                }
4267            }
4268
4269            if (!doTrim) {
4270                // If the caller is not actually asking for a trim, just tell them we reached
4271                // a point where the trim would happen.
4272                return i;
4273            }
4274
4275            // Either task and tr are the same or, their affinities match or their intents match
4276            // and neither of them is a document, or they are documents using the same activity
4277            // and their maxRecents has been reached.
4278            tr.disposeThumbnail();
4279            mRecentTasks.remove(i);
4280            if (task != tr) {
4281                tr.removedFromRecents(mTaskPersister);
4282            }
4283            i--;
4284            N--;
4285            if (task.intent == null) {
4286                // If the new recent task we are adding is not fully
4287                // specified, then replace it with the existing recent task.
4288                task = tr;
4289            }
4290            notifyTaskPersisterLocked(tr, false);
4291        }
4292
4293        return -1;
4294    }
4295
4296    @Override
4297    public void reportActivityFullyDrawn(IBinder token) {
4298        synchronized (this) {
4299            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4300            if (r == null) {
4301                return;
4302            }
4303            r.reportFullyDrawnLocked();
4304        }
4305    }
4306
4307    @Override
4308    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4309        synchronized (this) {
4310            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4311            if (r == null) {
4312                return;
4313            }
4314            final long origId = Binder.clearCallingIdentity();
4315            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4316            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4317                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4318            if (config != null) {
4319                r.frozenBeforeDestroy = true;
4320                if (!updateConfigurationLocked(config, r, false, false)) {
4321                    mStackSupervisor.resumeTopActivitiesLocked();
4322                }
4323            }
4324            Binder.restoreCallingIdentity(origId);
4325        }
4326    }
4327
4328    @Override
4329    public int getRequestedOrientation(IBinder token) {
4330        synchronized (this) {
4331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4332            if (r == null) {
4333                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4334            }
4335            return mWindowManager.getAppOrientation(r.appToken);
4336        }
4337    }
4338
4339    /**
4340     * This is the internal entry point for handling Activity.finish().
4341     *
4342     * @param token The Binder token referencing the Activity we want to finish.
4343     * @param resultCode Result code, if any, from this Activity.
4344     * @param resultData Result data (Intent), if any, from this Activity.
4345     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4346     *            the root Activity in the task.
4347     *
4348     * @return Returns true if the activity successfully finished, or false if it is still running.
4349     */
4350    @Override
4351    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4352            boolean finishTask) {
4353        // Refuse possible leaked file descriptors
4354        if (resultData != null && resultData.hasFileDescriptors() == true) {
4355            throw new IllegalArgumentException("File descriptors passed in Intent");
4356        }
4357
4358        synchronized(this) {
4359            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4360            if (r == null) {
4361                return true;
4362            }
4363            // Keep track of the root activity of the task before we finish it
4364            TaskRecord tr = r.task;
4365            ActivityRecord rootR = tr.getRootActivity();
4366            // Do not allow task to finish in Lock Task mode.
4367            if (tr == mStackSupervisor.mLockTaskModeTask) {
4368                if (rootR == r) {
4369                    mStackSupervisor.showLockTaskToast();
4370                    return false;
4371                }
4372            }
4373            if (mController != null) {
4374                // Find the first activity that is not finishing.
4375                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4376                if (next != null) {
4377                    // ask watcher if this is allowed
4378                    boolean resumeOK = true;
4379                    try {
4380                        resumeOK = mController.activityResuming(next.packageName);
4381                    } catch (RemoteException e) {
4382                        mController = null;
4383                        Watchdog.getInstance().setActivityController(null);
4384                    }
4385
4386                    if (!resumeOK) {
4387                        return false;
4388                    }
4389                }
4390            }
4391            final long origId = Binder.clearCallingIdentity();
4392            try {
4393                boolean res;
4394                if (finishTask && r == rootR) {
4395                    // If requested, remove the task that is associated to this activity only if it
4396                    // was the root activity in the task.  The result code and data is ignored because
4397                    // we don't support returning them across task boundaries.
4398                    res = removeTaskByIdLocked(tr.taskId, 0);
4399                } else {
4400                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4401                            resultData, "app-request", true);
4402                }
4403                return res;
4404            } finally {
4405                Binder.restoreCallingIdentity(origId);
4406            }
4407        }
4408    }
4409
4410    @Override
4411    public final void finishHeavyWeightApp() {
4412        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4413                != PackageManager.PERMISSION_GRANTED) {
4414            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4415                    + Binder.getCallingPid()
4416                    + ", uid=" + Binder.getCallingUid()
4417                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4418            Slog.w(TAG, msg);
4419            throw new SecurityException(msg);
4420        }
4421
4422        synchronized(this) {
4423            if (mHeavyWeightProcess == null) {
4424                return;
4425            }
4426
4427            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4428                    mHeavyWeightProcess.activities);
4429            for (int i=0; i<activities.size(); i++) {
4430                ActivityRecord r = activities.get(i);
4431                if (!r.finishing) {
4432                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4433                            null, "finish-heavy", true);
4434                }
4435            }
4436
4437            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4438                    mHeavyWeightProcess.userId, 0));
4439            mHeavyWeightProcess = null;
4440        }
4441    }
4442
4443    @Override
4444    public void crashApplication(int uid, int initialPid, String packageName,
4445            String message) {
4446        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4447                != PackageManager.PERMISSION_GRANTED) {
4448            String msg = "Permission Denial: crashApplication() from pid="
4449                    + Binder.getCallingPid()
4450                    + ", uid=" + Binder.getCallingUid()
4451                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4452            Slog.w(TAG, msg);
4453            throw new SecurityException(msg);
4454        }
4455
4456        synchronized(this) {
4457            ProcessRecord proc = null;
4458
4459            // Figure out which process to kill.  We don't trust that initialPid
4460            // still has any relation to current pids, so must scan through the
4461            // list.
4462            synchronized (mPidsSelfLocked) {
4463                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4464                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4465                    if (p.uid != uid) {
4466                        continue;
4467                    }
4468                    if (p.pid == initialPid) {
4469                        proc = p;
4470                        break;
4471                    }
4472                    if (p.pkgList.containsKey(packageName)) {
4473                        proc = p;
4474                    }
4475                }
4476            }
4477
4478            if (proc == null) {
4479                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4480                        + " initialPid=" + initialPid
4481                        + " packageName=" + packageName);
4482                return;
4483            }
4484
4485            if (proc.thread != null) {
4486                if (proc.pid == Process.myPid()) {
4487                    Log.w(TAG, "crashApplication: trying to crash self!");
4488                    return;
4489                }
4490                long ident = Binder.clearCallingIdentity();
4491                try {
4492                    proc.thread.scheduleCrash(message);
4493                } catch (RemoteException e) {
4494                }
4495                Binder.restoreCallingIdentity(ident);
4496            }
4497        }
4498    }
4499
4500    @Override
4501    public final void finishSubActivity(IBinder token, String resultWho,
4502            int requestCode) {
4503        synchronized(this) {
4504            final long origId = Binder.clearCallingIdentity();
4505            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4506            if (r != null) {
4507                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4508            }
4509            Binder.restoreCallingIdentity(origId);
4510        }
4511    }
4512
4513    @Override
4514    public boolean finishActivityAffinity(IBinder token) {
4515        synchronized(this) {
4516            final long origId = Binder.clearCallingIdentity();
4517            try {
4518                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4519
4520                ActivityRecord rootR = r.task.getRootActivity();
4521                // Do not allow task to finish in Lock Task mode.
4522                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4523                    if (rootR == r) {
4524                        mStackSupervisor.showLockTaskToast();
4525                        return false;
4526                    }
4527                }
4528                boolean res = false;
4529                if (r != null) {
4530                    res = r.task.stack.finishActivityAffinityLocked(r);
4531                }
4532                return res;
4533            } finally {
4534                Binder.restoreCallingIdentity(origId);
4535            }
4536        }
4537    }
4538
4539    @Override
4540    public void finishVoiceTask(IVoiceInteractionSession session) {
4541        synchronized(this) {
4542            final long origId = Binder.clearCallingIdentity();
4543            try {
4544                mStackSupervisor.finishVoiceTask(session);
4545            } finally {
4546                Binder.restoreCallingIdentity(origId);
4547            }
4548        }
4549
4550    }
4551
4552    @Override
4553    public boolean releaseActivityInstance(IBinder token) {
4554        synchronized(this) {
4555            final long origId = Binder.clearCallingIdentity();
4556            try {
4557                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4558                if (r.task == null || r.task.stack == null) {
4559                    return false;
4560                }
4561                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4562            } finally {
4563                Binder.restoreCallingIdentity(origId);
4564            }
4565        }
4566    }
4567
4568    @Override
4569    public void releaseSomeActivities(IApplicationThread appInt) {
4570        synchronized(this) {
4571            final long origId = Binder.clearCallingIdentity();
4572            try {
4573                ProcessRecord app = getRecordForAppLocked(appInt);
4574                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4575            } finally {
4576                Binder.restoreCallingIdentity(origId);
4577            }
4578        }
4579    }
4580
4581    @Override
4582    public boolean willActivityBeVisible(IBinder token) {
4583        synchronized(this) {
4584            ActivityStack stack = ActivityRecord.getStackLocked(token);
4585            if (stack != null) {
4586                return stack.willActivityBeVisibleLocked(token);
4587            }
4588            return false;
4589        }
4590    }
4591
4592    @Override
4593    public void overridePendingTransition(IBinder token, String packageName,
4594            int enterAnim, int exitAnim) {
4595        synchronized(this) {
4596            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4597            if (self == null) {
4598                return;
4599            }
4600
4601            final long origId = Binder.clearCallingIdentity();
4602
4603            if (self.state == ActivityState.RESUMED
4604                    || self.state == ActivityState.PAUSING) {
4605                mWindowManager.overridePendingAppTransition(packageName,
4606                        enterAnim, exitAnim, null);
4607            }
4608
4609            Binder.restoreCallingIdentity(origId);
4610        }
4611    }
4612
4613    /**
4614     * Main function for removing an existing process from the activity manager
4615     * as a result of that process going away.  Clears out all connections
4616     * to the process.
4617     */
4618    private final void handleAppDiedLocked(ProcessRecord app,
4619            boolean restarting, boolean allowRestart) {
4620        int pid = app.pid;
4621        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4622        if (!restarting) {
4623            removeLruProcessLocked(app);
4624            if (pid > 0) {
4625                ProcessList.remove(pid);
4626            }
4627        }
4628
4629        if (mProfileProc == app) {
4630            clearProfilerLocked();
4631        }
4632
4633        // Remove this application's activities from active lists.
4634        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4635
4636        app.activities.clear();
4637
4638        if (app.instrumentationClass != null) {
4639            Slog.w(TAG, "Crash of app " + app.processName
4640                  + " running instrumentation " + app.instrumentationClass);
4641            Bundle info = new Bundle();
4642            info.putString("shortMsg", "Process crashed.");
4643            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4644        }
4645
4646        if (!restarting) {
4647            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4648                // If there was nothing to resume, and we are not already
4649                // restarting this process, but there is a visible activity that
4650                // is hosted by the process...  then make sure all visible
4651                // activities are running, taking care of restarting this
4652                // process.
4653                if (hasVisibleActivities) {
4654                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4655                }
4656            }
4657        }
4658    }
4659
4660    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4661        IBinder threadBinder = thread.asBinder();
4662        // Find the application record.
4663        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4664            ProcessRecord rec = mLruProcesses.get(i);
4665            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4666                return i;
4667            }
4668        }
4669        return -1;
4670    }
4671
4672    final ProcessRecord getRecordForAppLocked(
4673            IApplicationThread thread) {
4674        if (thread == null) {
4675            return null;
4676        }
4677
4678        int appIndex = getLRURecordIndexForAppLocked(thread);
4679        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4680    }
4681
4682    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4683        // If there are no longer any background processes running,
4684        // and the app that died was not running instrumentation,
4685        // then tell everyone we are now low on memory.
4686        boolean haveBg = false;
4687        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4688            ProcessRecord rec = mLruProcesses.get(i);
4689            if (rec.thread != null
4690                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4691                haveBg = true;
4692                break;
4693            }
4694        }
4695
4696        if (!haveBg) {
4697            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4698            if (doReport) {
4699                long now = SystemClock.uptimeMillis();
4700                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4701                    doReport = false;
4702                } else {
4703                    mLastMemUsageReportTime = now;
4704                }
4705            }
4706            final ArrayList<ProcessMemInfo> memInfos
4707                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4708            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4709            long now = SystemClock.uptimeMillis();
4710            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4711                ProcessRecord rec = mLruProcesses.get(i);
4712                if (rec == dyingProc || rec.thread == null) {
4713                    continue;
4714                }
4715                if (doReport) {
4716                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4717                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4718                }
4719                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4720                    // The low memory report is overriding any current
4721                    // state for a GC request.  Make sure to do
4722                    // heavy/important/visible/foreground processes first.
4723                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4724                        rec.lastRequestedGc = 0;
4725                    } else {
4726                        rec.lastRequestedGc = rec.lastLowMemory;
4727                    }
4728                    rec.reportLowMemory = true;
4729                    rec.lastLowMemory = now;
4730                    mProcessesToGc.remove(rec);
4731                    addProcessToGcListLocked(rec);
4732                }
4733            }
4734            if (doReport) {
4735                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4736                mHandler.sendMessage(msg);
4737            }
4738            scheduleAppGcsLocked();
4739        }
4740    }
4741
4742    final void appDiedLocked(ProcessRecord app) {
4743       appDiedLocked(app, app.pid, app.thread);
4744    }
4745
4746    final void appDiedLocked(ProcessRecord app, int pid,
4747            IApplicationThread thread) {
4748
4749        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4750        synchronized (stats) {
4751            stats.noteProcessDiedLocked(app.info.uid, pid);
4752        }
4753
4754        Process.killProcessGroup(app.info.uid, pid);
4755
4756        // Clean up already done if the process has been re-started.
4757        if (app.pid == pid && app.thread != null &&
4758                app.thread.asBinder() == thread.asBinder()) {
4759            boolean doLowMem = app.instrumentationClass == null;
4760            boolean doOomAdj = doLowMem;
4761            if (!app.killedByAm) {
4762                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4763                        + ") has died.");
4764                mAllowLowerMemLevel = true;
4765            } else {
4766                // Note that we always want to do oom adj to update our state with the
4767                // new number of procs.
4768                mAllowLowerMemLevel = false;
4769                doLowMem = false;
4770            }
4771            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4772            if (DEBUG_CLEANUP) Slog.v(
4773                TAG, "Dying app: " + app + ", pid: " + pid
4774                + ", thread: " + thread.asBinder());
4775            handleAppDiedLocked(app, false, true);
4776
4777            if (doOomAdj) {
4778                updateOomAdjLocked();
4779            }
4780            if (doLowMem) {
4781                doLowMemReportIfNeededLocked(app);
4782            }
4783        } else if (app.pid != pid) {
4784            // A new process has already been started.
4785            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4786                    + ") has died and restarted (pid " + app.pid + ").");
4787            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4788        } else if (DEBUG_PROCESSES) {
4789            Slog.d(TAG, "Received spurious death notification for thread "
4790                    + thread.asBinder());
4791        }
4792    }
4793
4794    /**
4795     * If a stack trace dump file is configured, dump process stack traces.
4796     * @param clearTraces causes the dump file to be erased prior to the new
4797     *    traces being written, if true; when false, the new traces will be
4798     *    appended to any existing file content.
4799     * @param firstPids of dalvik VM processes to dump stack traces for first
4800     * @param lastPids of dalvik VM processes to dump stack traces for last
4801     * @param nativeProcs optional list of native process names to dump stack crawls
4802     * @return file containing stack traces, or null if no dump file is configured
4803     */
4804    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4805            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4806        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4807        if (tracesPath == null || tracesPath.length() == 0) {
4808            return null;
4809        }
4810
4811        File tracesFile = new File(tracesPath);
4812        try {
4813            File tracesDir = tracesFile.getParentFile();
4814            if (!tracesDir.exists()) {
4815                tracesFile.mkdirs();
4816                if (!SELinux.restorecon(tracesDir)) {
4817                    return null;
4818                }
4819            }
4820            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4821
4822            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4823            tracesFile.createNewFile();
4824            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4825        } catch (IOException e) {
4826            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4827            return null;
4828        }
4829
4830        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4831        return tracesFile;
4832    }
4833
4834    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4835            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4836        // Use a FileObserver to detect when traces finish writing.
4837        // The order of traces is considered important to maintain for legibility.
4838        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4839            @Override
4840            public synchronized void onEvent(int event, String path) { notify(); }
4841        };
4842
4843        try {
4844            observer.startWatching();
4845
4846            // First collect all of the stacks of the most important pids.
4847            if (firstPids != null) {
4848                try {
4849                    int num = firstPids.size();
4850                    for (int i = 0; i < num; i++) {
4851                        synchronized (observer) {
4852                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4853                            observer.wait(200);  // Wait for write-close, give up after 200msec
4854                        }
4855                    }
4856                } catch (InterruptedException e) {
4857                    Log.wtf(TAG, e);
4858                }
4859            }
4860
4861            // Next collect the stacks of the native pids
4862            if (nativeProcs != null) {
4863                int[] pids = Process.getPidsForCommands(nativeProcs);
4864                if (pids != null) {
4865                    for (int pid : pids) {
4866                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4867                    }
4868                }
4869            }
4870
4871            // Lastly, measure CPU usage.
4872            if (processCpuTracker != null) {
4873                processCpuTracker.init();
4874                System.gc();
4875                processCpuTracker.update();
4876                try {
4877                    synchronized (processCpuTracker) {
4878                        processCpuTracker.wait(500); // measure over 1/2 second.
4879                    }
4880                } catch (InterruptedException e) {
4881                }
4882                processCpuTracker.update();
4883
4884                // We'll take the stack crawls of just the top apps using CPU.
4885                final int N = processCpuTracker.countWorkingStats();
4886                int numProcs = 0;
4887                for (int i=0; i<N && numProcs<5; i++) {
4888                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4889                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4890                        numProcs++;
4891                        try {
4892                            synchronized (observer) {
4893                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4894                                observer.wait(200);  // Wait for write-close, give up after 200msec
4895                            }
4896                        } catch (InterruptedException e) {
4897                            Log.wtf(TAG, e);
4898                        }
4899
4900                    }
4901                }
4902            }
4903        } finally {
4904            observer.stopWatching();
4905        }
4906    }
4907
4908    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4909        if (true || IS_USER_BUILD) {
4910            return;
4911        }
4912        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4913        if (tracesPath == null || tracesPath.length() == 0) {
4914            return;
4915        }
4916
4917        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4918        StrictMode.allowThreadDiskWrites();
4919        try {
4920            final File tracesFile = new File(tracesPath);
4921            final File tracesDir = tracesFile.getParentFile();
4922            final File tracesTmp = new File(tracesDir, "__tmp__");
4923            try {
4924                if (!tracesDir.exists()) {
4925                    tracesFile.mkdirs();
4926                    if (!SELinux.restorecon(tracesDir.getPath())) {
4927                        return;
4928                    }
4929                }
4930                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4931
4932                if (tracesFile.exists()) {
4933                    tracesTmp.delete();
4934                    tracesFile.renameTo(tracesTmp);
4935                }
4936                StringBuilder sb = new StringBuilder();
4937                Time tobj = new Time();
4938                tobj.set(System.currentTimeMillis());
4939                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4940                sb.append(": ");
4941                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4942                sb.append(" since ");
4943                sb.append(msg);
4944                FileOutputStream fos = new FileOutputStream(tracesFile);
4945                fos.write(sb.toString().getBytes());
4946                if (app == null) {
4947                    fos.write("\n*** No application process!".getBytes());
4948                }
4949                fos.close();
4950                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4951            } catch (IOException e) {
4952                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4953                return;
4954            }
4955
4956            if (app != null) {
4957                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4958                firstPids.add(app.pid);
4959                dumpStackTraces(tracesPath, firstPids, null, null, null);
4960            }
4961
4962            File lastTracesFile = null;
4963            File curTracesFile = null;
4964            for (int i=9; i>=0; i--) {
4965                String name = String.format(Locale.US, "slow%02d.txt", i);
4966                curTracesFile = new File(tracesDir, name);
4967                if (curTracesFile.exists()) {
4968                    if (lastTracesFile != null) {
4969                        curTracesFile.renameTo(lastTracesFile);
4970                    } else {
4971                        curTracesFile.delete();
4972                    }
4973                }
4974                lastTracesFile = curTracesFile;
4975            }
4976            tracesFile.renameTo(curTracesFile);
4977            if (tracesTmp.exists()) {
4978                tracesTmp.renameTo(tracesFile);
4979            }
4980        } finally {
4981            StrictMode.setThreadPolicy(oldPolicy);
4982        }
4983    }
4984
4985    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4986            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4987        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4988        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4989
4990        if (mController != null) {
4991            try {
4992                // 0 == continue, -1 = kill process immediately
4993                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4994                if (res < 0 && app.pid != MY_PID) {
4995                    app.kill("anr", true);
4996                }
4997            } catch (RemoteException e) {
4998                mController = null;
4999                Watchdog.getInstance().setActivityController(null);
5000            }
5001        }
5002
5003        long anrTime = SystemClock.uptimeMillis();
5004        if (MONITOR_CPU_USAGE) {
5005            updateCpuStatsNow();
5006        }
5007
5008        synchronized (this) {
5009            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5010            if (mShuttingDown) {
5011                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5012                return;
5013            } else if (app.notResponding) {
5014                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5015                return;
5016            } else if (app.crashing) {
5017                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5018                return;
5019            }
5020
5021            // In case we come through here for the same app before completing
5022            // this one, mark as anring now so we will bail out.
5023            app.notResponding = true;
5024
5025            // Log the ANR to the event log.
5026            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5027                    app.processName, app.info.flags, annotation);
5028
5029            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5030            firstPids.add(app.pid);
5031
5032            int parentPid = app.pid;
5033            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5034            if (parentPid != app.pid) firstPids.add(parentPid);
5035
5036            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5037
5038            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5039                ProcessRecord r = mLruProcesses.get(i);
5040                if (r != null && r.thread != null) {
5041                    int pid = r.pid;
5042                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5043                        if (r.persistent) {
5044                            firstPids.add(pid);
5045                        } else {
5046                            lastPids.put(pid, Boolean.TRUE);
5047                        }
5048                    }
5049                }
5050            }
5051        }
5052
5053        // Log the ANR to the main log.
5054        StringBuilder info = new StringBuilder();
5055        info.setLength(0);
5056        info.append("ANR in ").append(app.processName);
5057        if (activity != null && activity.shortComponentName != null) {
5058            info.append(" (").append(activity.shortComponentName).append(")");
5059        }
5060        info.append("\n");
5061        info.append("PID: ").append(app.pid).append("\n");
5062        if (annotation != null) {
5063            info.append("Reason: ").append(annotation).append("\n");
5064        }
5065        if (parent != null && parent != activity) {
5066            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5067        }
5068
5069        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5070
5071        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5072                NATIVE_STACKS_OF_INTEREST);
5073
5074        String cpuInfo = null;
5075        if (MONITOR_CPU_USAGE) {
5076            updateCpuStatsNow();
5077            synchronized (mProcessCpuThread) {
5078                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5079            }
5080            info.append(processCpuTracker.printCurrentLoad());
5081            info.append(cpuInfo);
5082        }
5083
5084        info.append(processCpuTracker.printCurrentState(anrTime));
5085
5086        Slog.e(TAG, info.toString());
5087        if (tracesFile == null) {
5088            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5089            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5090        }
5091
5092        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5093                cpuInfo, tracesFile, null);
5094
5095        if (mController != null) {
5096            try {
5097                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5098                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5099                if (res != 0) {
5100                    if (res < 0 && app.pid != MY_PID) {
5101                        app.kill("anr", true);
5102                    } else {
5103                        synchronized (this) {
5104                            mServices.scheduleServiceTimeoutLocked(app);
5105                        }
5106                    }
5107                    return;
5108                }
5109            } catch (RemoteException e) {
5110                mController = null;
5111                Watchdog.getInstance().setActivityController(null);
5112            }
5113        }
5114
5115        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5116        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5117                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5118
5119        synchronized (this) {
5120            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5121                app.kill("bg anr", true);
5122                return;
5123            }
5124
5125            // Set the app's notResponding state, and look up the errorReportReceiver
5126            makeAppNotRespondingLocked(app,
5127                    activity != null ? activity.shortComponentName : null,
5128                    annotation != null ? "ANR " + annotation : "ANR",
5129                    info.toString());
5130
5131            // Bring up the infamous App Not Responding dialog
5132            Message msg = Message.obtain();
5133            HashMap<String, Object> map = new HashMap<String, Object>();
5134            msg.what = SHOW_NOT_RESPONDING_MSG;
5135            msg.obj = map;
5136            msg.arg1 = aboveSystem ? 1 : 0;
5137            map.put("app", app);
5138            if (activity != null) {
5139                map.put("activity", activity);
5140            }
5141
5142            mHandler.sendMessage(msg);
5143        }
5144    }
5145
5146    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5147        if (!mLaunchWarningShown) {
5148            mLaunchWarningShown = true;
5149            mHandler.post(new Runnable() {
5150                @Override
5151                public void run() {
5152                    synchronized (ActivityManagerService.this) {
5153                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5154                        d.show();
5155                        mHandler.postDelayed(new Runnable() {
5156                            @Override
5157                            public void run() {
5158                                synchronized (ActivityManagerService.this) {
5159                                    d.dismiss();
5160                                    mLaunchWarningShown = false;
5161                                }
5162                            }
5163                        }, 4000);
5164                    }
5165                }
5166            });
5167        }
5168    }
5169
5170    @Override
5171    public boolean clearApplicationUserData(final String packageName,
5172            final IPackageDataObserver observer, int userId) {
5173        enforceNotIsolatedCaller("clearApplicationUserData");
5174        int uid = Binder.getCallingUid();
5175        int pid = Binder.getCallingPid();
5176        userId = handleIncomingUser(pid, uid,
5177                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5178        long callingId = Binder.clearCallingIdentity();
5179        try {
5180            IPackageManager pm = AppGlobals.getPackageManager();
5181            int pkgUid = -1;
5182            synchronized(this) {
5183                try {
5184                    pkgUid = pm.getPackageUid(packageName, userId);
5185                } catch (RemoteException e) {
5186                }
5187                if (pkgUid == -1) {
5188                    Slog.w(TAG, "Invalid packageName: " + packageName);
5189                    if (observer != null) {
5190                        try {
5191                            observer.onRemoveCompleted(packageName, false);
5192                        } catch (RemoteException e) {
5193                            Slog.i(TAG, "Observer no longer exists.");
5194                        }
5195                    }
5196                    return false;
5197                }
5198                if (uid == pkgUid || checkComponentPermission(
5199                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5200                        pid, uid, -1, true)
5201                        == PackageManager.PERMISSION_GRANTED) {
5202                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5203                } else {
5204                    throw new SecurityException("PID " + pid + " does not have permission "
5205                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5206                                    + " of package " + packageName);
5207                }
5208
5209                // Remove all tasks match the cleared application package and user
5210                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5211                    final TaskRecord tr = mRecentTasks.get(i);
5212                    final String taskPackageName =
5213                            tr.getBaseIntent().getComponent().getPackageName();
5214                    if (tr.userId != userId) continue;
5215                    if (!taskPackageName.equals(packageName)) continue;
5216                    removeTaskByIdLocked(tr.taskId, 0);
5217                }
5218            }
5219
5220            try {
5221                // Clear application user data
5222                pm.clearApplicationUserData(packageName, observer, userId);
5223
5224                synchronized(this) {
5225                    // Remove all permissions granted from/to this package
5226                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5227                }
5228
5229                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5230                        Uri.fromParts("package", packageName, null));
5231                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5232                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5233                        null, null, 0, null, null, null, false, false, userId);
5234            } catch (RemoteException e) {
5235            }
5236        } finally {
5237            Binder.restoreCallingIdentity(callingId);
5238        }
5239        return true;
5240    }
5241
5242    @Override
5243    public void killBackgroundProcesses(final String packageName, int userId) {
5244        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5245                != PackageManager.PERMISSION_GRANTED &&
5246                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5247                        != PackageManager.PERMISSION_GRANTED) {
5248            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5249                    + Binder.getCallingPid()
5250                    + ", uid=" + Binder.getCallingUid()
5251                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5252            Slog.w(TAG, msg);
5253            throw new SecurityException(msg);
5254        }
5255
5256        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5257                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5258        long callingId = Binder.clearCallingIdentity();
5259        try {
5260            IPackageManager pm = AppGlobals.getPackageManager();
5261            synchronized(this) {
5262                int appId = -1;
5263                try {
5264                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5265                } catch (RemoteException e) {
5266                }
5267                if (appId == -1) {
5268                    Slog.w(TAG, "Invalid packageName: " + packageName);
5269                    return;
5270                }
5271                killPackageProcessesLocked(packageName, appId, userId,
5272                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5273            }
5274        } finally {
5275            Binder.restoreCallingIdentity(callingId);
5276        }
5277    }
5278
5279    @Override
5280    public void killAllBackgroundProcesses() {
5281        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5282                != PackageManager.PERMISSION_GRANTED) {
5283            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5284                    + Binder.getCallingPid()
5285                    + ", uid=" + Binder.getCallingUid()
5286                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5287            Slog.w(TAG, msg);
5288            throw new SecurityException(msg);
5289        }
5290
5291        long callingId = Binder.clearCallingIdentity();
5292        try {
5293            synchronized(this) {
5294                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5295                final int NP = mProcessNames.getMap().size();
5296                for (int ip=0; ip<NP; ip++) {
5297                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5298                    final int NA = apps.size();
5299                    for (int ia=0; ia<NA; ia++) {
5300                        ProcessRecord app = apps.valueAt(ia);
5301                        if (app.persistent) {
5302                            // we don't kill persistent processes
5303                            continue;
5304                        }
5305                        if (app.removed) {
5306                            procs.add(app);
5307                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5308                            app.removed = true;
5309                            procs.add(app);
5310                        }
5311                    }
5312                }
5313
5314                int N = procs.size();
5315                for (int i=0; i<N; i++) {
5316                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5317                }
5318                mAllowLowerMemLevel = true;
5319                updateOomAdjLocked();
5320                doLowMemReportIfNeededLocked(null);
5321            }
5322        } finally {
5323            Binder.restoreCallingIdentity(callingId);
5324        }
5325    }
5326
5327    @Override
5328    public void forceStopPackage(final String packageName, int userId) {
5329        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5330                != PackageManager.PERMISSION_GRANTED) {
5331            String msg = "Permission Denial: forceStopPackage() from pid="
5332                    + Binder.getCallingPid()
5333                    + ", uid=" + Binder.getCallingUid()
5334                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5335            Slog.w(TAG, msg);
5336            throw new SecurityException(msg);
5337        }
5338        final int callingPid = Binder.getCallingPid();
5339        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5340                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5341        long callingId = Binder.clearCallingIdentity();
5342        try {
5343            IPackageManager pm = AppGlobals.getPackageManager();
5344            synchronized(this) {
5345                int[] users = userId == UserHandle.USER_ALL
5346                        ? getUsersLocked() : new int[] { userId };
5347                for (int user : users) {
5348                    int pkgUid = -1;
5349                    try {
5350                        pkgUid = pm.getPackageUid(packageName, user);
5351                    } catch (RemoteException e) {
5352                    }
5353                    if (pkgUid == -1) {
5354                        Slog.w(TAG, "Invalid packageName: " + packageName);
5355                        continue;
5356                    }
5357                    try {
5358                        pm.setPackageStoppedState(packageName, true, user);
5359                    } catch (RemoteException e) {
5360                    } catch (IllegalArgumentException e) {
5361                        Slog.w(TAG, "Failed trying to unstop package "
5362                                + packageName + ": " + e);
5363                    }
5364                    if (isUserRunningLocked(user, false)) {
5365                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5366                    }
5367                }
5368            }
5369        } finally {
5370            Binder.restoreCallingIdentity(callingId);
5371        }
5372    }
5373
5374    @Override
5375    public void addPackageDependency(String packageName) {
5376        synchronized (this) {
5377            int callingPid = Binder.getCallingPid();
5378            if (callingPid == Process.myPid()) {
5379                //  Yeah, um, no.
5380                Slog.w(TAG, "Can't addPackageDependency on system process");
5381                return;
5382            }
5383            ProcessRecord proc;
5384            synchronized (mPidsSelfLocked) {
5385                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5386            }
5387            if (proc != null) {
5388                if (proc.pkgDeps == null) {
5389                    proc.pkgDeps = new ArraySet<String>(1);
5390                }
5391                proc.pkgDeps.add(packageName);
5392            }
5393        }
5394    }
5395
5396    /*
5397     * The pkg name and app id have to be specified.
5398     */
5399    @Override
5400    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5401        if (pkg == null) {
5402            return;
5403        }
5404        // Make sure the uid is valid.
5405        if (appid < 0) {
5406            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5407            return;
5408        }
5409        int callerUid = Binder.getCallingUid();
5410        // Only the system server can kill an application
5411        if (callerUid == Process.SYSTEM_UID) {
5412            // Post an aysnc message to kill the application
5413            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5414            msg.arg1 = appid;
5415            msg.arg2 = 0;
5416            Bundle bundle = new Bundle();
5417            bundle.putString("pkg", pkg);
5418            bundle.putString("reason", reason);
5419            msg.obj = bundle;
5420            mHandler.sendMessage(msg);
5421        } else {
5422            throw new SecurityException(callerUid + " cannot kill pkg: " +
5423                    pkg);
5424        }
5425    }
5426
5427    @Override
5428    public void closeSystemDialogs(String reason) {
5429        enforceNotIsolatedCaller("closeSystemDialogs");
5430
5431        final int pid = Binder.getCallingPid();
5432        final int uid = Binder.getCallingUid();
5433        final long origId = Binder.clearCallingIdentity();
5434        try {
5435            synchronized (this) {
5436                // Only allow this from foreground processes, so that background
5437                // applications can't abuse it to prevent system UI from being shown.
5438                if (uid >= Process.FIRST_APPLICATION_UID) {
5439                    ProcessRecord proc;
5440                    synchronized (mPidsSelfLocked) {
5441                        proc = mPidsSelfLocked.get(pid);
5442                    }
5443                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5444                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5445                                + " from background process " + proc);
5446                        return;
5447                    }
5448                }
5449                closeSystemDialogsLocked(reason);
5450            }
5451        } finally {
5452            Binder.restoreCallingIdentity(origId);
5453        }
5454    }
5455
5456    void closeSystemDialogsLocked(String reason) {
5457        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5458        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5459                | Intent.FLAG_RECEIVER_FOREGROUND);
5460        if (reason != null) {
5461            intent.putExtra("reason", reason);
5462        }
5463        mWindowManager.closeSystemDialogs(reason);
5464
5465        mStackSupervisor.closeSystemDialogsLocked();
5466
5467        broadcastIntentLocked(null, null, intent, null,
5468                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5469                Process.SYSTEM_UID, UserHandle.USER_ALL);
5470    }
5471
5472    @Override
5473    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5474        enforceNotIsolatedCaller("getProcessMemoryInfo");
5475        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5476        for (int i=pids.length-1; i>=0; i--) {
5477            ProcessRecord proc;
5478            int oomAdj;
5479            synchronized (this) {
5480                synchronized (mPidsSelfLocked) {
5481                    proc = mPidsSelfLocked.get(pids[i]);
5482                    oomAdj = proc != null ? proc.setAdj : 0;
5483                }
5484            }
5485            infos[i] = new Debug.MemoryInfo();
5486            Debug.getMemoryInfo(pids[i], infos[i]);
5487            if (proc != null) {
5488                synchronized (this) {
5489                    if (proc.thread != null && proc.setAdj == oomAdj) {
5490                        // Record this for posterity if the process has been stable.
5491                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5492                                infos[i].getTotalUss(), false, proc.pkgList);
5493                    }
5494                }
5495            }
5496        }
5497        return infos;
5498    }
5499
5500    @Override
5501    public long[] getProcessPss(int[] pids) {
5502        enforceNotIsolatedCaller("getProcessPss");
5503        long[] pss = new long[pids.length];
5504        for (int i=pids.length-1; i>=0; i--) {
5505            ProcessRecord proc;
5506            int oomAdj;
5507            synchronized (this) {
5508                synchronized (mPidsSelfLocked) {
5509                    proc = mPidsSelfLocked.get(pids[i]);
5510                    oomAdj = proc != null ? proc.setAdj : 0;
5511                }
5512            }
5513            long[] tmpUss = new long[1];
5514            pss[i] = Debug.getPss(pids[i], tmpUss);
5515            if (proc != null) {
5516                synchronized (this) {
5517                    if (proc.thread != null && proc.setAdj == oomAdj) {
5518                        // Record this for posterity if the process has been stable.
5519                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5520                    }
5521                }
5522            }
5523        }
5524        return pss;
5525    }
5526
5527    @Override
5528    public void killApplicationProcess(String processName, int uid) {
5529        if (processName == null) {
5530            return;
5531        }
5532
5533        int callerUid = Binder.getCallingUid();
5534        // Only the system server can kill an application
5535        if (callerUid == Process.SYSTEM_UID) {
5536            synchronized (this) {
5537                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5538                if (app != null && app.thread != null) {
5539                    try {
5540                        app.thread.scheduleSuicide();
5541                    } catch (RemoteException e) {
5542                        // If the other end already died, then our work here is done.
5543                    }
5544                } else {
5545                    Slog.w(TAG, "Process/uid not found attempting kill of "
5546                            + processName + " / " + uid);
5547                }
5548            }
5549        } else {
5550            throw new SecurityException(callerUid + " cannot kill app process: " +
5551                    processName);
5552        }
5553    }
5554
5555    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5556        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5557                false, true, false, false, UserHandle.getUserId(uid), reason);
5558        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5559                Uri.fromParts("package", packageName, null));
5560        if (!mProcessesReady) {
5561            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5562                    | Intent.FLAG_RECEIVER_FOREGROUND);
5563        }
5564        intent.putExtra(Intent.EXTRA_UID, uid);
5565        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5566        broadcastIntentLocked(null, null, intent,
5567                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5568                false, false,
5569                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5570    }
5571
5572    private void forceStopUserLocked(int userId, String reason) {
5573        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5574        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5575        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5576                | Intent.FLAG_RECEIVER_FOREGROUND);
5577        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5578        broadcastIntentLocked(null, null, intent,
5579                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5580                false, false,
5581                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5582    }
5583
5584    private final boolean killPackageProcessesLocked(String packageName, int appId,
5585            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5586            boolean doit, boolean evenPersistent, String reason) {
5587        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5588
5589        // Remove all processes this package may have touched: all with the
5590        // same UID (except for the system or root user), and all whose name
5591        // matches the package name.
5592        final int NP = mProcessNames.getMap().size();
5593        for (int ip=0; ip<NP; ip++) {
5594            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5595            final int NA = apps.size();
5596            for (int ia=0; ia<NA; ia++) {
5597                ProcessRecord app = apps.valueAt(ia);
5598                if (app.persistent && !evenPersistent) {
5599                    // we don't kill persistent processes
5600                    continue;
5601                }
5602                if (app.removed) {
5603                    if (doit) {
5604                        procs.add(app);
5605                    }
5606                    continue;
5607                }
5608
5609                // Skip process if it doesn't meet our oom adj requirement.
5610                if (app.setAdj < minOomAdj) {
5611                    continue;
5612                }
5613
5614                // If no package is specified, we call all processes under the
5615                // give user id.
5616                if (packageName == null) {
5617                    if (app.userId != userId) {
5618                        continue;
5619                    }
5620                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5621                        continue;
5622                    }
5623                // Package has been specified, we want to hit all processes
5624                // that match it.  We need to qualify this by the processes
5625                // that are running under the specified app and user ID.
5626                } else {
5627                    final boolean isDep = app.pkgDeps != null
5628                            && app.pkgDeps.contains(packageName);
5629                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5630                        continue;
5631                    }
5632                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5633                        continue;
5634                    }
5635                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5636                        continue;
5637                    }
5638                }
5639
5640                // Process has passed all conditions, kill it!
5641                if (!doit) {
5642                    return true;
5643                }
5644                app.removed = true;
5645                procs.add(app);
5646            }
5647        }
5648
5649        int N = procs.size();
5650        for (int i=0; i<N; i++) {
5651            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5652        }
5653        updateOomAdjLocked();
5654        return N > 0;
5655    }
5656
5657    private final boolean forceStopPackageLocked(String name, int appId,
5658            boolean callerWillRestart, boolean purgeCache, boolean doit,
5659            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5660        int i;
5661        int N;
5662
5663        if (userId == UserHandle.USER_ALL && name == null) {
5664            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5665        }
5666
5667        if (appId < 0 && name != null) {
5668            try {
5669                appId = UserHandle.getAppId(
5670                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5671            } catch (RemoteException e) {
5672            }
5673        }
5674
5675        if (doit) {
5676            if (name != null) {
5677                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5678                        + " user=" + userId + ": " + reason);
5679            } else {
5680                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5681            }
5682
5683            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5684            for (int ip=pmap.size()-1; ip>=0; ip--) {
5685                SparseArray<Long> ba = pmap.valueAt(ip);
5686                for (i=ba.size()-1; i>=0; i--) {
5687                    boolean remove = false;
5688                    final int entUid = ba.keyAt(i);
5689                    if (name != null) {
5690                        if (userId == UserHandle.USER_ALL) {
5691                            if (UserHandle.getAppId(entUid) == appId) {
5692                                remove = true;
5693                            }
5694                        } else {
5695                            if (entUid == UserHandle.getUid(userId, appId)) {
5696                                remove = true;
5697                            }
5698                        }
5699                    } else if (UserHandle.getUserId(entUid) == userId) {
5700                        remove = true;
5701                    }
5702                    if (remove) {
5703                        ba.removeAt(i);
5704                    }
5705                }
5706                if (ba.size() == 0) {
5707                    pmap.removeAt(ip);
5708                }
5709            }
5710        }
5711
5712        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5713                -100, callerWillRestart, true, doit, evenPersistent,
5714                name == null ? ("stop user " + userId) : ("stop " + name));
5715
5716        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5717            if (!doit) {
5718                return true;
5719            }
5720            didSomething = true;
5721        }
5722
5723        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5724            if (!doit) {
5725                return true;
5726            }
5727            didSomething = true;
5728        }
5729
5730        if (name == null) {
5731            // Remove all sticky broadcasts from this user.
5732            mStickyBroadcasts.remove(userId);
5733        }
5734
5735        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5736        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5737                userId, providers)) {
5738            if (!doit) {
5739                return true;
5740            }
5741            didSomething = true;
5742        }
5743        N = providers.size();
5744        for (i=0; i<N; i++) {
5745            removeDyingProviderLocked(null, providers.get(i), true);
5746        }
5747
5748        // Remove transient permissions granted from/to this package/user
5749        removeUriPermissionsForPackageLocked(name, userId, false);
5750
5751        if (name == null || uninstalling) {
5752            // Remove pending intents.  For now we only do this when force
5753            // stopping users, because we have some problems when doing this
5754            // for packages -- app widgets are not currently cleaned up for
5755            // such packages, so they can be left with bad pending intents.
5756            if (mIntentSenderRecords.size() > 0) {
5757                Iterator<WeakReference<PendingIntentRecord>> it
5758                        = mIntentSenderRecords.values().iterator();
5759                while (it.hasNext()) {
5760                    WeakReference<PendingIntentRecord> wpir = it.next();
5761                    if (wpir == null) {
5762                        it.remove();
5763                        continue;
5764                    }
5765                    PendingIntentRecord pir = wpir.get();
5766                    if (pir == null) {
5767                        it.remove();
5768                        continue;
5769                    }
5770                    if (name == null) {
5771                        // Stopping user, remove all objects for the user.
5772                        if (pir.key.userId != userId) {
5773                            // Not the same user, skip it.
5774                            continue;
5775                        }
5776                    } else {
5777                        if (UserHandle.getAppId(pir.uid) != appId) {
5778                            // Different app id, skip it.
5779                            continue;
5780                        }
5781                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5782                            // Different user, skip it.
5783                            continue;
5784                        }
5785                        if (!pir.key.packageName.equals(name)) {
5786                            // Different package, skip it.
5787                            continue;
5788                        }
5789                    }
5790                    if (!doit) {
5791                        return true;
5792                    }
5793                    didSomething = true;
5794                    it.remove();
5795                    pir.canceled = true;
5796                    if (pir.key.activity != null) {
5797                        pir.key.activity.pendingResults.remove(pir.ref);
5798                    }
5799                }
5800            }
5801        }
5802
5803        if (doit) {
5804            if (purgeCache && name != null) {
5805                AttributeCache ac = AttributeCache.instance();
5806                if (ac != null) {
5807                    ac.removePackage(name);
5808                }
5809            }
5810            if (mBooted) {
5811                mStackSupervisor.resumeTopActivitiesLocked();
5812                mStackSupervisor.scheduleIdleLocked();
5813            }
5814        }
5815
5816        return didSomething;
5817    }
5818
5819    private final boolean removeProcessLocked(ProcessRecord app,
5820            boolean callerWillRestart, boolean allowRestart, String reason) {
5821        final String name = app.processName;
5822        final int uid = app.uid;
5823        if (DEBUG_PROCESSES) Slog.d(
5824            TAG, "Force removing proc " + app.toShortString() + " (" + name
5825            + "/" + uid + ")");
5826
5827        mProcessNames.remove(name, uid);
5828        mIsolatedProcesses.remove(app.uid);
5829        if (mHeavyWeightProcess == app) {
5830            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5831                    mHeavyWeightProcess.userId, 0));
5832            mHeavyWeightProcess = null;
5833        }
5834        boolean needRestart = false;
5835        if (app.pid > 0 && app.pid != MY_PID) {
5836            int pid = app.pid;
5837            synchronized (mPidsSelfLocked) {
5838                mPidsSelfLocked.remove(pid);
5839                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5840            }
5841            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5842            if (app.isolated) {
5843                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5844            }
5845            app.kill(reason, true);
5846            handleAppDiedLocked(app, true, allowRestart);
5847            removeLruProcessLocked(app);
5848
5849            if (app.persistent && !app.isolated) {
5850                if (!callerWillRestart) {
5851                    addAppLocked(app.info, false, null /* ABI override */);
5852                } else {
5853                    needRestart = true;
5854                }
5855            }
5856        } else {
5857            mRemovedProcesses.add(app);
5858        }
5859
5860        return needRestart;
5861    }
5862
5863    private final void processStartTimedOutLocked(ProcessRecord app) {
5864        final int pid = app.pid;
5865        boolean gone = false;
5866        synchronized (mPidsSelfLocked) {
5867            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5868            if (knownApp != null && knownApp.thread == null) {
5869                mPidsSelfLocked.remove(pid);
5870                gone = true;
5871            }
5872        }
5873
5874        if (gone) {
5875            Slog.w(TAG, "Process " + app + " failed to attach");
5876            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5877                    pid, app.uid, app.processName);
5878            mProcessNames.remove(app.processName, app.uid);
5879            mIsolatedProcesses.remove(app.uid);
5880            if (mHeavyWeightProcess == app) {
5881                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5882                        mHeavyWeightProcess.userId, 0));
5883                mHeavyWeightProcess = null;
5884            }
5885            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5886            if (app.isolated) {
5887                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5888            }
5889            // Take care of any launching providers waiting for this process.
5890            checkAppInLaunchingProvidersLocked(app, true);
5891            // Take care of any services that are waiting for the process.
5892            mServices.processStartTimedOutLocked(app);
5893            app.kill("start timeout", true);
5894            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5895                Slog.w(TAG, "Unattached app died before backup, skipping");
5896                try {
5897                    IBackupManager bm = IBackupManager.Stub.asInterface(
5898                            ServiceManager.getService(Context.BACKUP_SERVICE));
5899                    bm.agentDisconnected(app.info.packageName);
5900                } catch (RemoteException e) {
5901                    // Can't happen; the backup manager is local
5902                }
5903            }
5904            if (isPendingBroadcastProcessLocked(pid)) {
5905                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5906                skipPendingBroadcastLocked(pid);
5907            }
5908        } else {
5909            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5910        }
5911    }
5912
5913    private final boolean attachApplicationLocked(IApplicationThread thread,
5914            int pid) {
5915
5916        // Find the application record that is being attached...  either via
5917        // the pid if we are running in multiple processes, or just pull the
5918        // next app record if we are emulating process with anonymous threads.
5919        ProcessRecord app;
5920        if (pid != MY_PID && pid >= 0) {
5921            synchronized (mPidsSelfLocked) {
5922                app = mPidsSelfLocked.get(pid);
5923            }
5924        } else {
5925            app = null;
5926        }
5927
5928        if (app == null) {
5929            Slog.w(TAG, "No pending application record for pid " + pid
5930                    + " (IApplicationThread " + thread + "); dropping process");
5931            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5932            if (pid > 0 && pid != MY_PID) {
5933                Process.killProcessQuiet(pid);
5934                //TODO: Process.killProcessGroup(app.info.uid, pid);
5935            } else {
5936                try {
5937                    thread.scheduleExit();
5938                } catch (Exception e) {
5939                    // Ignore exceptions.
5940                }
5941            }
5942            return false;
5943        }
5944
5945        // If this application record is still attached to a previous
5946        // process, clean it up now.
5947        if (app.thread != null) {
5948            handleAppDiedLocked(app, true, true);
5949        }
5950
5951        // Tell the process all about itself.
5952
5953        if (localLOGV) Slog.v(
5954                TAG, "Binding process pid " + pid + " to record " + app);
5955
5956        final String processName = app.processName;
5957        try {
5958            AppDeathRecipient adr = new AppDeathRecipient(
5959                    app, pid, thread);
5960            thread.asBinder().linkToDeath(adr, 0);
5961            app.deathRecipient = adr;
5962        } catch (RemoteException e) {
5963            app.resetPackageList(mProcessStats);
5964            startProcessLocked(app, "link fail", processName);
5965            return false;
5966        }
5967
5968        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5969
5970        app.makeActive(thread, mProcessStats);
5971        app.curAdj = app.setAdj = -100;
5972        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5973        app.forcingToForeground = null;
5974        updateProcessForegroundLocked(app, false, false);
5975        app.hasShownUi = false;
5976        app.debugging = false;
5977        app.cached = false;
5978
5979        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5980
5981        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5982        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5983
5984        if (!normalMode) {
5985            Slog.i(TAG, "Launching preboot mode app: " + app);
5986        }
5987
5988        if (localLOGV) Slog.v(
5989            TAG, "New app record " + app
5990            + " thread=" + thread.asBinder() + " pid=" + pid);
5991        try {
5992            int testMode = IApplicationThread.DEBUG_OFF;
5993            if (mDebugApp != null && mDebugApp.equals(processName)) {
5994                testMode = mWaitForDebugger
5995                    ? IApplicationThread.DEBUG_WAIT
5996                    : IApplicationThread.DEBUG_ON;
5997                app.debugging = true;
5998                if (mDebugTransient) {
5999                    mDebugApp = mOrigDebugApp;
6000                    mWaitForDebugger = mOrigWaitForDebugger;
6001                }
6002            }
6003            String profileFile = app.instrumentationProfileFile;
6004            ParcelFileDescriptor profileFd = null;
6005            int samplingInterval = 0;
6006            boolean profileAutoStop = false;
6007            if (mProfileApp != null && mProfileApp.equals(processName)) {
6008                mProfileProc = app;
6009                profileFile = mProfileFile;
6010                profileFd = mProfileFd;
6011                samplingInterval = mSamplingInterval;
6012                profileAutoStop = mAutoStopProfiler;
6013            }
6014            boolean enableOpenGlTrace = false;
6015            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6016                enableOpenGlTrace = true;
6017                mOpenGlTraceApp = null;
6018            }
6019
6020            // If the app is being launched for restore or full backup, set it up specially
6021            boolean isRestrictedBackupMode = false;
6022            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6023                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6024                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6025                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6026            }
6027
6028            ensurePackageDexOpt(app.instrumentationInfo != null
6029                    ? app.instrumentationInfo.packageName
6030                    : app.info.packageName);
6031            if (app.instrumentationClass != null) {
6032                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6033            }
6034            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6035                    + processName + " with config " + mConfiguration);
6036            ApplicationInfo appInfo = app.instrumentationInfo != null
6037                    ? app.instrumentationInfo : app.info;
6038            app.compat = compatibilityInfoForPackageLocked(appInfo);
6039            if (profileFd != null) {
6040                profileFd = profileFd.dup();
6041            }
6042            ProfilerInfo profilerInfo = profileFile == null ? null
6043                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6044            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6045                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6046                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6047                    isRestrictedBackupMode || !normalMode, app.persistent,
6048                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6049                    mCoreSettingsObserver.getCoreSettingsLocked());
6050            updateLruProcessLocked(app, false, null);
6051            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6052        } catch (Exception e) {
6053            // todo: Yikes!  What should we do?  For now we will try to
6054            // start another process, but that could easily get us in
6055            // an infinite loop of restarting processes...
6056            Slog.w(TAG, "Exception thrown during bind!", e);
6057
6058            app.resetPackageList(mProcessStats);
6059            app.unlinkDeathRecipient();
6060            startProcessLocked(app, "bind fail", processName);
6061            return false;
6062        }
6063
6064        // Remove this record from the list of starting applications.
6065        mPersistentStartingProcesses.remove(app);
6066        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6067                "Attach application locked removing on hold: " + app);
6068        mProcessesOnHold.remove(app);
6069
6070        boolean badApp = false;
6071        boolean didSomething = false;
6072
6073        // See if the top visible activity is waiting to run in this process...
6074        if (normalMode) {
6075            try {
6076                if (mStackSupervisor.attachApplicationLocked(app)) {
6077                    didSomething = true;
6078                }
6079            } catch (Exception e) {
6080                badApp = true;
6081            }
6082        }
6083
6084        // Find any services that should be running in this process...
6085        if (!badApp) {
6086            try {
6087                didSomething |= mServices.attachApplicationLocked(app, processName);
6088            } catch (Exception e) {
6089                badApp = true;
6090            }
6091        }
6092
6093        // Check if a next-broadcast receiver is in this process...
6094        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6095            try {
6096                didSomething |= sendPendingBroadcastsLocked(app);
6097            } catch (Exception e) {
6098                // If the app died trying to launch the receiver we declare it 'bad'
6099                badApp = true;
6100            }
6101        }
6102
6103        // Check whether the next backup agent is in this process...
6104        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6105            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6106            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6107            try {
6108                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6109                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6110                        mBackupTarget.backupMode);
6111            } catch (Exception e) {
6112                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6113                e.printStackTrace();
6114            }
6115        }
6116
6117        if (badApp) {
6118            // todo: Also need to kill application to deal with all
6119            // kinds of exceptions.
6120            handleAppDiedLocked(app, false, true);
6121            return false;
6122        }
6123
6124        if (!didSomething) {
6125            updateOomAdjLocked();
6126        }
6127
6128        return true;
6129    }
6130
6131    @Override
6132    public final void attachApplication(IApplicationThread thread) {
6133        synchronized (this) {
6134            int callingPid = Binder.getCallingPid();
6135            final long origId = Binder.clearCallingIdentity();
6136            attachApplicationLocked(thread, callingPid);
6137            Binder.restoreCallingIdentity(origId);
6138        }
6139    }
6140
6141    @Override
6142    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6143        final long origId = Binder.clearCallingIdentity();
6144        synchronized (this) {
6145            ActivityStack stack = ActivityRecord.getStackLocked(token);
6146            if (stack != null) {
6147                ActivityRecord r =
6148                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6149                if (stopProfiling) {
6150                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6151                        try {
6152                            mProfileFd.close();
6153                        } catch (IOException e) {
6154                        }
6155                        clearProfilerLocked();
6156                    }
6157                }
6158            }
6159        }
6160        Binder.restoreCallingIdentity(origId);
6161    }
6162
6163    void postEnableScreenAfterBootLocked() {
6164        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6165    }
6166
6167    void enableScreenAfterBoot() {
6168        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6169                SystemClock.uptimeMillis());
6170        mWindowManager.enableScreenAfterBoot();
6171
6172        synchronized (this) {
6173            updateEventDispatchingLocked();
6174        }
6175    }
6176
6177    @Override
6178    public void showBootMessage(final CharSequence msg, final boolean always) {
6179        enforceNotIsolatedCaller("showBootMessage");
6180        mWindowManager.showBootMessage(msg, always);
6181    }
6182
6183    @Override
6184    public void keyguardWaitingForActivityDrawn() {
6185        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6186        final long token = Binder.clearCallingIdentity();
6187        try {
6188            synchronized (this) {
6189                if (DEBUG_LOCKSCREEN) logLockScreen("");
6190                mWindowManager.keyguardWaitingForActivityDrawn();
6191            }
6192        } finally {
6193            Binder.restoreCallingIdentity(token);
6194        }
6195    }
6196
6197    final void finishBooting() {
6198        // Register receivers to handle package update events
6199        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6200
6201        // Let system services know.
6202        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6203
6204        synchronized (this) {
6205            // Ensure that any processes we had put on hold are now started
6206            // up.
6207            final int NP = mProcessesOnHold.size();
6208            if (NP > 0) {
6209                ArrayList<ProcessRecord> procs =
6210                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6211                for (int ip=0; ip<NP; ip++) {
6212                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6213                            + procs.get(ip));
6214                    startProcessLocked(procs.get(ip), "on-hold", null);
6215                }
6216            }
6217
6218            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6219                // Start looking for apps that are abusing wake locks.
6220                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6221                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6222                // Tell anyone interested that we are done booting!
6223                SystemProperties.set("sys.boot_completed", "1");
6224                SystemProperties.set("dev.bootcomplete", "1");
6225                for (int i=0; i<mStartedUsers.size(); i++) {
6226                    UserStartedState uss = mStartedUsers.valueAt(i);
6227                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6228                        uss.mState = UserStartedState.STATE_RUNNING;
6229                        final int userId = mStartedUsers.keyAt(i);
6230                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6231                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6232                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6233                        broadcastIntentLocked(null, null, intent, null,
6234                                new IIntentReceiver.Stub() {
6235                                    @Override
6236                                    public void performReceive(Intent intent, int resultCode,
6237                                            String data, Bundle extras, boolean ordered,
6238                                            boolean sticky, int sendingUser) {
6239                                        synchronized (ActivityManagerService.this) {
6240                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6241                                                    true, false);
6242                                        }
6243                                    }
6244                                },
6245                                0, null, null,
6246                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6247                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6248                                userId);
6249                    }
6250                }
6251                scheduleStartProfilesLocked();
6252            }
6253        }
6254    }
6255
6256    final void ensureBootCompleted() {
6257        boolean booting;
6258        boolean enableScreen;
6259        synchronized (this) {
6260            booting = mBooting;
6261            mBooting = false;
6262            enableScreen = !mBooted;
6263            mBooted = true;
6264        }
6265
6266        if (booting) {
6267            finishBooting();
6268        }
6269
6270        if (enableScreen) {
6271            enableScreenAfterBoot();
6272        }
6273    }
6274
6275    @Override
6276    public final void activityResumed(IBinder token) {
6277        final long origId = Binder.clearCallingIdentity();
6278        synchronized(this) {
6279            ActivityStack stack = ActivityRecord.getStackLocked(token);
6280            if (stack != null) {
6281                ActivityRecord.activityResumedLocked(token);
6282            }
6283        }
6284        Binder.restoreCallingIdentity(origId);
6285    }
6286
6287    @Override
6288    public final void activityPaused(IBinder token) {
6289        final long origId = Binder.clearCallingIdentity();
6290        synchronized(this) {
6291            ActivityStack stack = ActivityRecord.getStackLocked(token);
6292            if (stack != null) {
6293                stack.activityPausedLocked(token, false);
6294            }
6295        }
6296        Binder.restoreCallingIdentity(origId);
6297    }
6298
6299    @Override
6300    public final void activityStopped(IBinder token, Bundle icicle,
6301            PersistableBundle persistentState, CharSequence description) {
6302        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6303
6304        // Refuse possible leaked file descriptors
6305        if (icicle != null && icicle.hasFileDescriptors()) {
6306            throw new IllegalArgumentException("File descriptors passed in Bundle");
6307        }
6308
6309        final long origId = Binder.clearCallingIdentity();
6310
6311        synchronized (this) {
6312            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6313            if (r != null) {
6314                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6315            }
6316        }
6317
6318        trimApplications();
6319
6320        Binder.restoreCallingIdentity(origId);
6321    }
6322
6323    @Override
6324    public final void activityDestroyed(IBinder token) {
6325        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6326        synchronized (this) {
6327            ActivityStack stack = ActivityRecord.getStackLocked(token);
6328            if (stack != null) {
6329                stack.activityDestroyedLocked(token);
6330            }
6331        }
6332    }
6333
6334    @Override
6335    public final void backgroundResourcesReleased(IBinder token) {
6336        final long origId = Binder.clearCallingIdentity();
6337        try {
6338            synchronized (this) {
6339                ActivityStack stack = ActivityRecord.getStackLocked(token);
6340                if (stack != null) {
6341                    stack.backgroundResourcesReleased(token);
6342                }
6343            }
6344        } finally {
6345            Binder.restoreCallingIdentity(origId);
6346        }
6347    }
6348
6349    @Override
6350    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6351        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6352    }
6353
6354    @Override
6355    public final void notifyEnterAnimationComplete(IBinder token) {
6356        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6357    }
6358
6359    @Override
6360    public String getCallingPackage(IBinder token) {
6361        synchronized (this) {
6362            ActivityRecord r = getCallingRecordLocked(token);
6363            return r != null ? r.info.packageName : null;
6364        }
6365    }
6366
6367    @Override
6368    public ComponentName getCallingActivity(IBinder token) {
6369        synchronized (this) {
6370            ActivityRecord r = getCallingRecordLocked(token);
6371            return r != null ? r.intent.getComponent() : null;
6372        }
6373    }
6374
6375    private ActivityRecord getCallingRecordLocked(IBinder token) {
6376        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6377        if (r == null) {
6378            return null;
6379        }
6380        return r.resultTo;
6381    }
6382
6383    @Override
6384    public ComponentName getActivityClassForToken(IBinder token) {
6385        synchronized(this) {
6386            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6387            if (r == null) {
6388                return null;
6389            }
6390            return r.intent.getComponent();
6391        }
6392    }
6393
6394    @Override
6395    public String getPackageForToken(IBinder token) {
6396        synchronized(this) {
6397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6398            if (r == null) {
6399                return null;
6400            }
6401            return r.packageName;
6402        }
6403    }
6404
6405    @Override
6406    public IIntentSender getIntentSender(int type,
6407            String packageName, IBinder token, String resultWho,
6408            int requestCode, Intent[] intents, String[] resolvedTypes,
6409            int flags, Bundle options, int userId) {
6410        enforceNotIsolatedCaller("getIntentSender");
6411        // Refuse possible leaked file descriptors
6412        if (intents != null) {
6413            if (intents.length < 1) {
6414                throw new IllegalArgumentException("Intents array length must be >= 1");
6415            }
6416            for (int i=0; i<intents.length; i++) {
6417                Intent intent = intents[i];
6418                if (intent != null) {
6419                    if (intent.hasFileDescriptors()) {
6420                        throw new IllegalArgumentException("File descriptors passed in Intent");
6421                    }
6422                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6423                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6424                        throw new IllegalArgumentException(
6425                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6426                    }
6427                    intents[i] = new Intent(intent);
6428                }
6429            }
6430            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6431                throw new IllegalArgumentException(
6432                        "Intent array length does not match resolvedTypes length");
6433            }
6434        }
6435        if (options != null) {
6436            if (options.hasFileDescriptors()) {
6437                throw new IllegalArgumentException("File descriptors passed in options");
6438            }
6439        }
6440
6441        synchronized(this) {
6442            int callingUid = Binder.getCallingUid();
6443            int origUserId = userId;
6444            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6445                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6446                    ALLOW_NON_FULL, "getIntentSender", null);
6447            if (origUserId == UserHandle.USER_CURRENT) {
6448                // We don't want to evaluate this until the pending intent is
6449                // actually executed.  However, we do want to always do the
6450                // security checking for it above.
6451                userId = UserHandle.USER_CURRENT;
6452            }
6453            try {
6454                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6455                    int uid = AppGlobals.getPackageManager()
6456                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6457                    if (!UserHandle.isSameApp(callingUid, uid)) {
6458                        String msg = "Permission Denial: getIntentSender() from pid="
6459                            + Binder.getCallingPid()
6460                            + ", uid=" + Binder.getCallingUid()
6461                            + ", (need uid=" + uid + ")"
6462                            + " is not allowed to send as package " + packageName;
6463                        Slog.w(TAG, msg);
6464                        throw new SecurityException(msg);
6465                    }
6466                }
6467
6468                return getIntentSenderLocked(type, packageName, callingUid, userId,
6469                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6470
6471            } catch (RemoteException e) {
6472                throw new SecurityException(e);
6473            }
6474        }
6475    }
6476
6477    IIntentSender getIntentSenderLocked(int type, String packageName,
6478            int callingUid, int userId, IBinder token, String resultWho,
6479            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6480            Bundle options) {
6481        if (DEBUG_MU)
6482            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6483        ActivityRecord activity = null;
6484        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6485            activity = ActivityRecord.isInStackLocked(token);
6486            if (activity == null) {
6487                return null;
6488            }
6489            if (activity.finishing) {
6490                return null;
6491            }
6492        }
6493
6494        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6495        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6496        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6497        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6498                |PendingIntent.FLAG_UPDATE_CURRENT);
6499
6500        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6501                type, packageName, activity, resultWho,
6502                requestCode, intents, resolvedTypes, flags, options, userId);
6503        WeakReference<PendingIntentRecord> ref;
6504        ref = mIntentSenderRecords.get(key);
6505        PendingIntentRecord rec = ref != null ? ref.get() : null;
6506        if (rec != null) {
6507            if (!cancelCurrent) {
6508                if (updateCurrent) {
6509                    if (rec.key.requestIntent != null) {
6510                        rec.key.requestIntent.replaceExtras(intents != null ?
6511                                intents[intents.length - 1] : null);
6512                    }
6513                    if (intents != null) {
6514                        intents[intents.length-1] = rec.key.requestIntent;
6515                        rec.key.allIntents = intents;
6516                        rec.key.allResolvedTypes = resolvedTypes;
6517                    } else {
6518                        rec.key.allIntents = null;
6519                        rec.key.allResolvedTypes = null;
6520                    }
6521                }
6522                return rec;
6523            }
6524            rec.canceled = true;
6525            mIntentSenderRecords.remove(key);
6526        }
6527        if (noCreate) {
6528            return rec;
6529        }
6530        rec = new PendingIntentRecord(this, key, callingUid);
6531        mIntentSenderRecords.put(key, rec.ref);
6532        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6533            if (activity.pendingResults == null) {
6534                activity.pendingResults
6535                        = new HashSet<WeakReference<PendingIntentRecord>>();
6536            }
6537            activity.pendingResults.add(rec.ref);
6538        }
6539        return rec;
6540    }
6541
6542    @Override
6543    public void cancelIntentSender(IIntentSender sender) {
6544        if (!(sender instanceof PendingIntentRecord)) {
6545            return;
6546        }
6547        synchronized(this) {
6548            PendingIntentRecord rec = (PendingIntentRecord)sender;
6549            try {
6550                int uid = AppGlobals.getPackageManager()
6551                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6552                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6553                    String msg = "Permission Denial: cancelIntentSender() from pid="
6554                        + Binder.getCallingPid()
6555                        + ", uid=" + Binder.getCallingUid()
6556                        + " is not allowed to cancel packges "
6557                        + rec.key.packageName;
6558                    Slog.w(TAG, msg);
6559                    throw new SecurityException(msg);
6560                }
6561            } catch (RemoteException e) {
6562                throw new SecurityException(e);
6563            }
6564            cancelIntentSenderLocked(rec, true);
6565        }
6566    }
6567
6568    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6569        rec.canceled = true;
6570        mIntentSenderRecords.remove(rec.key);
6571        if (cleanActivity && rec.key.activity != null) {
6572            rec.key.activity.pendingResults.remove(rec.ref);
6573        }
6574    }
6575
6576    @Override
6577    public String getPackageForIntentSender(IIntentSender pendingResult) {
6578        if (!(pendingResult instanceof PendingIntentRecord)) {
6579            return null;
6580        }
6581        try {
6582            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6583            return res.key.packageName;
6584        } catch (ClassCastException e) {
6585        }
6586        return null;
6587    }
6588
6589    @Override
6590    public int getUidForIntentSender(IIntentSender sender) {
6591        if (sender instanceof PendingIntentRecord) {
6592            try {
6593                PendingIntentRecord res = (PendingIntentRecord)sender;
6594                return res.uid;
6595            } catch (ClassCastException e) {
6596            }
6597        }
6598        return -1;
6599    }
6600
6601    @Override
6602    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6603        if (!(pendingResult instanceof PendingIntentRecord)) {
6604            return false;
6605        }
6606        try {
6607            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6608            if (res.key.allIntents == null) {
6609                return false;
6610            }
6611            for (int i=0; i<res.key.allIntents.length; i++) {
6612                Intent intent = res.key.allIntents[i];
6613                if (intent.getPackage() != null && intent.getComponent() != null) {
6614                    return false;
6615                }
6616            }
6617            return true;
6618        } catch (ClassCastException e) {
6619        }
6620        return false;
6621    }
6622
6623    @Override
6624    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6625        if (!(pendingResult instanceof PendingIntentRecord)) {
6626            return false;
6627        }
6628        try {
6629            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6630            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6631                return true;
6632            }
6633            return false;
6634        } catch (ClassCastException e) {
6635        }
6636        return false;
6637    }
6638
6639    @Override
6640    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6641        if (!(pendingResult instanceof PendingIntentRecord)) {
6642            return null;
6643        }
6644        try {
6645            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6646            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6647        } catch (ClassCastException e) {
6648        }
6649        return null;
6650    }
6651
6652    @Override
6653    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6654        if (!(pendingResult instanceof PendingIntentRecord)) {
6655            return null;
6656        }
6657        try {
6658            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6659            Intent intent = res.key.requestIntent;
6660            if (intent != null) {
6661                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6662                        || res.lastTagPrefix.equals(prefix))) {
6663                    return res.lastTag;
6664                }
6665                res.lastTagPrefix = prefix;
6666                StringBuilder sb = new StringBuilder(128);
6667                if (prefix != null) {
6668                    sb.append(prefix);
6669                }
6670                if (intent.getAction() != null) {
6671                    sb.append(intent.getAction());
6672                } else if (intent.getComponent() != null) {
6673                    intent.getComponent().appendShortString(sb);
6674                } else {
6675                    sb.append("?");
6676                }
6677                return res.lastTag = sb.toString();
6678            }
6679        } catch (ClassCastException e) {
6680        }
6681        return null;
6682    }
6683
6684    @Override
6685    public void setProcessLimit(int max) {
6686        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6687                "setProcessLimit()");
6688        synchronized (this) {
6689            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6690            mProcessLimitOverride = max;
6691        }
6692        trimApplications();
6693    }
6694
6695    @Override
6696    public int getProcessLimit() {
6697        synchronized (this) {
6698            return mProcessLimitOverride;
6699        }
6700    }
6701
6702    void foregroundTokenDied(ForegroundToken token) {
6703        synchronized (ActivityManagerService.this) {
6704            synchronized (mPidsSelfLocked) {
6705                ForegroundToken cur
6706                    = mForegroundProcesses.get(token.pid);
6707                if (cur != token) {
6708                    return;
6709                }
6710                mForegroundProcesses.remove(token.pid);
6711                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6712                if (pr == null) {
6713                    return;
6714                }
6715                pr.forcingToForeground = null;
6716                updateProcessForegroundLocked(pr, false, false);
6717            }
6718            updateOomAdjLocked();
6719        }
6720    }
6721
6722    @Override
6723    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6724        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6725                "setProcessForeground()");
6726        synchronized(this) {
6727            boolean changed = false;
6728
6729            synchronized (mPidsSelfLocked) {
6730                ProcessRecord pr = mPidsSelfLocked.get(pid);
6731                if (pr == null && isForeground) {
6732                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6733                    return;
6734                }
6735                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6736                if (oldToken != null) {
6737                    oldToken.token.unlinkToDeath(oldToken, 0);
6738                    mForegroundProcesses.remove(pid);
6739                    if (pr != null) {
6740                        pr.forcingToForeground = null;
6741                    }
6742                    changed = true;
6743                }
6744                if (isForeground && token != null) {
6745                    ForegroundToken newToken = new ForegroundToken() {
6746                        @Override
6747                        public void binderDied() {
6748                            foregroundTokenDied(this);
6749                        }
6750                    };
6751                    newToken.pid = pid;
6752                    newToken.token = token;
6753                    try {
6754                        token.linkToDeath(newToken, 0);
6755                        mForegroundProcesses.put(pid, newToken);
6756                        pr.forcingToForeground = token;
6757                        changed = true;
6758                    } catch (RemoteException e) {
6759                        // If the process died while doing this, we will later
6760                        // do the cleanup with the process death link.
6761                    }
6762                }
6763            }
6764
6765            if (changed) {
6766                updateOomAdjLocked();
6767            }
6768        }
6769    }
6770
6771    // =========================================================
6772    // PERMISSIONS
6773    // =========================================================
6774
6775    static class PermissionController extends IPermissionController.Stub {
6776        ActivityManagerService mActivityManagerService;
6777        PermissionController(ActivityManagerService activityManagerService) {
6778            mActivityManagerService = activityManagerService;
6779        }
6780
6781        @Override
6782        public boolean checkPermission(String permission, int pid, int uid) {
6783            return mActivityManagerService.checkPermission(permission, pid,
6784                    uid) == PackageManager.PERMISSION_GRANTED;
6785        }
6786    }
6787
6788    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6789        @Override
6790        public int checkComponentPermission(String permission, int pid, int uid,
6791                int owningUid, boolean exported) {
6792            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6793                    owningUid, exported);
6794        }
6795
6796        @Override
6797        public Object getAMSLock() {
6798            return ActivityManagerService.this;
6799        }
6800    }
6801
6802    /**
6803     * This can be called with or without the global lock held.
6804     */
6805    int checkComponentPermission(String permission, int pid, int uid,
6806            int owningUid, boolean exported) {
6807        // We might be performing an operation on behalf of an indirect binder
6808        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6809        // client identity accordingly before proceeding.
6810        Identity tlsIdentity = sCallerIdentity.get();
6811        if (tlsIdentity != null) {
6812            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6813                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6814            uid = tlsIdentity.uid;
6815            pid = tlsIdentity.pid;
6816        }
6817
6818        if (pid == MY_PID) {
6819            return PackageManager.PERMISSION_GRANTED;
6820        }
6821
6822        return ActivityManager.checkComponentPermission(permission, uid,
6823                owningUid, exported);
6824    }
6825
6826    /**
6827     * As the only public entry point for permissions checking, this method
6828     * can enforce the semantic that requesting a check on a null global
6829     * permission is automatically denied.  (Internally a null permission
6830     * string is used when calling {@link #checkComponentPermission} in cases
6831     * when only uid-based security is needed.)
6832     *
6833     * This can be called with or without the global lock held.
6834     */
6835    @Override
6836    public int checkPermission(String permission, int pid, int uid) {
6837        if (permission == null) {
6838            return PackageManager.PERMISSION_DENIED;
6839        }
6840        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6841    }
6842
6843    /**
6844     * Binder IPC calls go through the public entry point.
6845     * This can be called with or without the global lock held.
6846     */
6847    int checkCallingPermission(String permission) {
6848        return checkPermission(permission,
6849                Binder.getCallingPid(),
6850                UserHandle.getAppId(Binder.getCallingUid()));
6851    }
6852
6853    /**
6854     * This can be called with or without the global lock held.
6855     */
6856    void enforceCallingPermission(String permission, String func) {
6857        if (checkCallingPermission(permission)
6858                == PackageManager.PERMISSION_GRANTED) {
6859            return;
6860        }
6861
6862        String msg = "Permission Denial: " + func + " from pid="
6863                + Binder.getCallingPid()
6864                + ", uid=" + Binder.getCallingUid()
6865                + " requires " + permission;
6866        Slog.w(TAG, msg);
6867        throw new SecurityException(msg);
6868    }
6869
6870    /**
6871     * Determine if UID is holding permissions required to access {@link Uri} in
6872     * the given {@link ProviderInfo}. Final permission checking is always done
6873     * in {@link ContentProvider}.
6874     */
6875    private final boolean checkHoldingPermissionsLocked(
6876            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6877        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6878                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6879        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6880            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6881                    != PERMISSION_GRANTED) {
6882                return false;
6883            }
6884        }
6885        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6886    }
6887
6888    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6889            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6890        if (pi.applicationInfo.uid == uid) {
6891            return true;
6892        } else if (!pi.exported) {
6893            return false;
6894        }
6895
6896        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6897        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6898        try {
6899            // check if target holds top-level <provider> permissions
6900            if (!readMet && pi.readPermission != null && considerUidPermissions
6901                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6902                readMet = true;
6903            }
6904            if (!writeMet && pi.writePermission != null && considerUidPermissions
6905                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6906                writeMet = true;
6907            }
6908
6909            // track if unprotected read/write is allowed; any denied
6910            // <path-permission> below removes this ability
6911            boolean allowDefaultRead = pi.readPermission == null;
6912            boolean allowDefaultWrite = pi.writePermission == null;
6913
6914            // check if target holds any <path-permission> that match uri
6915            final PathPermission[] pps = pi.pathPermissions;
6916            if (pps != null) {
6917                final String path = grantUri.uri.getPath();
6918                int i = pps.length;
6919                while (i > 0 && (!readMet || !writeMet)) {
6920                    i--;
6921                    PathPermission pp = pps[i];
6922                    if (pp.match(path)) {
6923                        if (!readMet) {
6924                            final String pprperm = pp.getReadPermission();
6925                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6926                                    + pprperm + " for " + pp.getPath()
6927                                    + ": match=" + pp.match(path)
6928                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6929                            if (pprperm != null) {
6930                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6931                                        == PERMISSION_GRANTED) {
6932                                    readMet = true;
6933                                } else {
6934                                    allowDefaultRead = false;
6935                                }
6936                            }
6937                        }
6938                        if (!writeMet) {
6939                            final String ppwperm = pp.getWritePermission();
6940                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6941                                    + ppwperm + " for " + pp.getPath()
6942                                    + ": match=" + pp.match(path)
6943                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6944                            if (ppwperm != null) {
6945                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6946                                        == PERMISSION_GRANTED) {
6947                                    writeMet = true;
6948                                } else {
6949                                    allowDefaultWrite = false;
6950                                }
6951                            }
6952                        }
6953                    }
6954                }
6955            }
6956
6957            // grant unprotected <provider> read/write, if not blocked by
6958            // <path-permission> above
6959            if (allowDefaultRead) readMet = true;
6960            if (allowDefaultWrite) writeMet = true;
6961
6962        } catch (RemoteException e) {
6963            return false;
6964        }
6965
6966        return readMet && writeMet;
6967    }
6968
6969    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6970        ProviderInfo pi = null;
6971        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6972        if (cpr != null) {
6973            pi = cpr.info;
6974        } else {
6975            try {
6976                pi = AppGlobals.getPackageManager().resolveContentProvider(
6977                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6978            } catch (RemoteException ex) {
6979            }
6980        }
6981        return pi;
6982    }
6983
6984    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6985        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6986        if (targetUris != null) {
6987            return targetUris.get(grantUri);
6988        }
6989        return null;
6990    }
6991
6992    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6993            String targetPkg, int targetUid, GrantUri grantUri) {
6994        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6995        if (targetUris == null) {
6996            targetUris = Maps.newArrayMap();
6997            mGrantedUriPermissions.put(targetUid, targetUris);
6998        }
6999
7000        UriPermission perm = targetUris.get(grantUri);
7001        if (perm == null) {
7002            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7003            targetUris.put(grantUri, perm);
7004        }
7005
7006        return perm;
7007    }
7008
7009    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7010            final int modeFlags) {
7011        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7012        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7013                : UriPermission.STRENGTH_OWNED;
7014
7015        // Root gets to do everything.
7016        if (uid == 0) {
7017            return true;
7018        }
7019
7020        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7021        if (perms == null) return false;
7022
7023        // First look for exact match
7024        final UriPermission exactPerm = perms.get(grantUri);
7025        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7026            return true;
7027        }
7028
7029        // No exact match, look for prefixes
7030        final int N = perms.size();
7031        for (int i = 0; i < N; i++) {
7032            final UriPermission perm = perms.valueAt(i);
7033            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7034                    && perm.getStrength(modeFlags) >= minStrength) {
7035                return true;
7036            }
7037        }
7038
7039        return false;
7040    }
7041
7042    /**
7043     * @param uri This uri must NOT contain an embedded userId.
7044     * @param userId The userId in which the uri is to be resolved.
7045     */
7046    @Override
7047    public int checkUriPermission(Uri uri, int pid, int uid,
7048            final int modeFlags, int userId) {
7049        enforceNotIsolatedCaller("checkUriPermission");
7050
7051        // Another redirected-binder-call permissions check as in
7052        // {@link checkComponentPermission}.
7053        Identity tlsIdentity = sCallerIdentity.get();
7054        if (tlsIdentity != null) {
7055            uid = tlsIdentity.uid;
7056            pid = tlsIdentity.pid;
7057        }
7058
7059        // Our own process gets to do everything.
7060        if (pid == MY_PID) {
7061            return PackageManager.PERMISSION_GRANTED;
7062        }
7063        synchronized (this) {
7064            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7065                    ? PackageManager.PERMISSION_GRANTED
7066                    : PackageManager.PERMISSION_DENIED;
7067        }
7068    }
7069
7070    /**
7071     * Check if the targetPkg can be granted permission to access uri by
7072     * the callingUid using the given modeFlags.  Throws a security exception
7073     * if callingUid is not allowed to do this.  Returns the uid of the target
7074     * if the URI permission grant should be performed; returns -1 if it is not
7075     * needed (for example targetPkg already has permission to access the URI).
7076     * If you already know the uid of the target, you can supply it in
7077     * lastTargetUid else set that to -1.
7078     */
7079    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7080            final int modeFlags, int lastTargetUid) {
7081        if (!Intent.isAccessUriMode(modeFlags)) {
7082            return -1;
7083        }
7084
7085        if (targetPkg != null) {
7086            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7087                    "Checking grant " + targetPkg + " permission to " + grantUri);
7088        }
7089
7090        final IPackageManager pm = AppGlobals.getPackageManager();
7091
7092        // If this is not a content: uri, we can't do anything with it.
7093        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7094            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7095                    "Can't grant URI permission for non-content URI: " + grantUri);
7096            return -1;
7097        }
7098
7099        final String authority = grantUri.uri.getAuthority();
7100        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7101        if (pi == null) {
7102            Slog.w(TAG, "No content provider found for permission check: " +
7103                    grantUri.uri.toSafeString());
7104            return -1;
7105        }
7106
7107        int targetUid = lastTargetUid;
7108        if (targetUid < 0 && targetPkg != null) {
7109            try {
7110                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7111                if (targetUid < 0) {
7112                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7113                            "Can't grant URI permission no uid for: " + targetPkg);
7114                    return -1;
7115                }
7116            } catch (RemoteException ex) {
7117                return -1;
7118            }
7119        }
7120
7121        if (targetUid >= 0) {
7122            // First...  does the target actually need this permission?
7123            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7124                // No need to grant the target this permission.
7125                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7126                        "Target " + targetPkg + " already has full permission to " + grantUri);
7127                return -1;
7128            }
7129        } else {
7130            // First...  there is no target package, so can anyone access it?
7131            boolean allowed = pi.exported;
7132            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7133                if (pi.readPermission != null) {
7134                    allowed = false;
7135                }
7136            }
7137            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7138                if (pi.writePermission != null) {
7139                    allowed = false;
7140                }
7141            }
7142            if (allowed) {
7143                return -1;
7144            }
7145        }
7146
7147        /* There is a special cross user grant if:
7148         * - The target is on another user.
7149         * - Apps on the current user can access the uri without any uid permissions.
7150         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7151         * grant uri permissions.
7152         */
7153        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7154                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7155                modeFlags, false /*without considering the uid permissions*/);
7156
7157        // Second...  is the provider allowing granting of URI permissions?
7158        if (!specialCrossUserGrant) {
7159            if (!pi.grantUriPermissions) {
7160                throw new SecurityException("Provider " + pi.packageName
7161                        + "/" + pi.name
7162                        + " does not allow granting of Uri permissions (uri "
7163                        + grantUri + ")");
7164            }
7165            if (pi.uriPermissionPatterns != null) {
7166                final int N = pi.uriPermissionPatterns.length;
7167                boolean allowed = false;
7168                for (int i=0; i<N; i++) {
7169                    if (pi.uriPermissionPatterns[i] != null
7170                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7171                        allowed = true;
7172                        break;
7173                    }
7174                }
7175                if (!allowed) {
7176                    throw new SecurityException("Provider " + pi.packageName
7177                            + "/" + pi.name
7178                            + " does not allow granting of permission to path of Uri "
7179                            + grantUri);
7180                }
7181            }
7182        }
7183
7184        // Third...  does the caller itself have permission to access
7185        // this uri?
7186        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7187            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7188                // Require they hold a strong enough Uri permission
7189                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7190                    throw new SecurityException("Uid " + callingUid
7191                            + " does not have permission to uri " + grantUri);
7192                }
7193            }
7194        }
7195        return targetUid;
7196    }
7197
7198    /**
7199     * @param uri This uri must NOT contain an embedded userId.
7200     * @param userId The userId in which the uri is to be resolved.
7201     */
7202    @Override
7203    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7204            final int modeFlags, int userId) {
7205        enforceNotIsolatedCaller("checkGrantUriPermission");
7206        synchronized(this) {
7207            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7208                    new GrantUri(userId, uri, false), modeFlags, -1);
7209        }
7210    }
7211
7212    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7213            final int modeFlags, UriPermissionOwner owner) {
7214        if (!Intent.isAccessUriMode(modeFlags)) {
7215            return;
7216        }
7217
7218        // So here we are: the caller has the assumed permission
7219        // to the uri, and the target doesn't.  Let's now give this to
7220        // the target.
7221
7222        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7223                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7224
7225        final String authority = grantUri.uri.getAuthority();
7226        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7227        if (pi == null) {
7228            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7229            return;
7230        }
7231
7232        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7233            grantUri.prefix = true;
7234        }
7235        final UriPermission perm = findOrCreateUriPermissionLocked(
7236                pi.packageName, targetPkg, targetUid, grantUri);
7237        perm.grantModes(modeFlags, owner);
7238    }
7239
7240    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7241            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7242        if (targetPkg == null) {
7243            throw new NullPointerException("targetPkg");
7244        }
7245        int targetUid;
7246        final IPackageManager pm = AppGlobals.getPackageManager();
7247        try {
7248            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7249        } catch (RemoteException ex) {
7250            return;
7251        }
7252
7253        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7254                targetUid);
7255        if (targetUid < 0) {
7256            return;
7257        }
7258
7259        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7260                owner);
7261    }
7262
7263    static class NeededUriGrants extends ArrayList<GrantUri> {
7264        final String targetPkg;
7265        final int targetUid;
7266        final int flags;
7267
7268        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7269            this.targetPkg = targetPkg;
7270            this.targetUid = targetUid;
7271            this.flags = flags;
7272        }
7273    }
7274
7275    /**
7276     * Like checkGrantUriPermissionLocked, but takes an Intent.
7277     */
7278    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7279            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7280        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7281                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7282                + " clip=" + (intent != null ? intent.getClipData() : null)
7283                + " from " + intent + "; flags=0x"
7284                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7285
7286        if (targetPkg == null) {
7287            throw new NullPointerException("targetPkg");
7288        }
7289
7290        if (intent == null) {
7291            return null;
7292        }
7293        Uri data = intent.getData();
7294        ClipData clip = intent.getClipData();
7295        if (data == null && clip == null) {
7296            return null;
7297        }
7298        // Default userId for uris in the intent (if they don't specify it themselves)
7299        int contentUserHint = intent.getContentUserHint();
7300        if (contentUserHint == UserHandle.USER_CURRENT) {
7301            contentUserHint = UserHandle.getUserId(callingUid);
7302        }
7303        final IPackageManager pm = AppGlobals.getPackageManager();
7304        int targetUid;
7305        if (needed != null) {
7306            targetUid = needed.targetUid;
7307        } else {
7308            try {
7309                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7310            } catch (RemoteException ex) {
7311                return null;
7312            }
7313            if (targetUid < 0) {
7314                if (DEBUG_URI_PERMISSION) {
7315                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7316                            + " on user " + targetUserId);
7317                }
7318                return null;
7319            }
7320        }
7321        if (data != null) {
7322            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7323            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7324                    targetUid);
7325            if (targetUid > 0) {
7326                if (needed == null) {
7327                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7328                }
7329                needed.add(grantUri);
7330            }
7331        }
7332        if (clip != null) {
7333            for (int i=0; i<clip.getItemCount(); i++) {
7334                Uri uri = clip.getItemAt(i).getUri();
7335                if (uri != null) {
7336                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7337                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7338                            targetUid);
7339                    if (targetUid > 0) {
7340                        if (needed == null) {
7341                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7342                        }
7343                        needed.add(grantUri);
7344                    }
7345                } else {
7346                    Intent clipIntent = clip.getItemAt(i).getIntent();
7347                    if (clipIntent != null) {
7348                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7349                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7350                        if (newNeeded != null) {
7351                            needed = newNeeded;
7352                        }
7353                    }
7354                }
7355            }
7356        }
7357
7358        return needed;
7359    }
7360
7361    /**
7362     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7363     */
7364    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7365            UriPermissionOwner owner) {
7366        if (needed != null) {
7367            for (int i=0; i<needed.size(); i++) {
7368                GrantUri grantUri = needed.get(i);
7369                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7370                        grantUri, needed.flags, owner);
7371            }
7372        }
7373    }
7374
7375    void grantUriPermissionFromIntentLocked(int callingUid,
7376            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7377        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7378                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7379        if (needed == null) {
7380            return;
7381        }
7382
7383        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7384    }
7385
7386    /**
7387     * @param uri This uri must NOT contain an embedded userId.
7388     * @param userId The userId in which the uri is to be resolved.
7389     */
7390    @Override
7391    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7392            final int modeFlags, int userId) {
7393        enforceNotIsolatedCaller("grantUriPermission");
7394        GrantUri grantUri = new GrantUri(userId, uri, false);
7395        synchronized(this) {
7396            final ProcessRecord r = getRecordForAppLocked(caller);
7397            if (r == null) {
7398                throw new SecurityException("Unable to find app for caller "
7399                        + caller
7400                        + " when granting permission to uri " + grantUri);
7401            }
7402            if (targetPkg == null) {
7403                throw new IllegalArgumentException("null target");
7404            }
7405            if (grantUri == null) {
7406                throw new IllegalArgumentException("null uri");
7407            }
7408
7409            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7410                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7411                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7412                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7413
7414            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7415                    UserHandle.getUserId(r.uid));
7416        }
7417    }
7418
7419    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7420        if (perm.modeFlags == 0) {
7421            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7422                    perm.targetUid);
7423            if (perms != null) {
7424                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7425                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7426
7427                perms.remove(perm.uri);
7428                if (perms.isEmpty()) {
7429                    mGrantedUriPermissions.remove(perm.targetUid);
7430                }
7431            }
7432        }
7433    }
7434
7435    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7436        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7437
7438        final IPackageManager pm = AppGlobals.getPackageManager();
7439        final String authority = grantUri.uri.getAuthority();
7440        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7441        if (pi == null) {
7442            Slog.w(TAG, "No content provider found for permission revoke: "
7443                    + grantUri.toSafeString());
7444            return;
7445        }
7446
7447        // Does the caller have this permission on the URI?
7448        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7449            // Right now, if you are not the original owner of the permission,
7450            // you are not allowed to revoke it.
7451            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7452                throw new SecurityException("Uid " + callingUid
7453                        + " does not have permission to uri " + grantUri);
7454            //}
7455        }
7456
7457        boolean persistChanged = false;
7458
7459        // Go through all of the permissions and remove any that match.
7460        int N = mGrantedUriPermissions.size();
7461        for (int i = 0; i < N; i++) {
7462            final int targetUid = mGrantedUriPermissions.keyAt(i);
7463            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7464
7465            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7466                final UriPermission perm = it.next();
7467                if (perm.uri.sourceUserId == grantUri.sourceUserId
7468                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7469                    if (DEBUG_URI_PERMISSION)
7470                        Slog.v(TAG,
7471                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7472                    persistChanged |= perm.revokeModes(
7473                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7474                    if (perm.modeFlags == 0) {
7475                        it.remove();
7476                    }
7477                }
7478            }
7479
7480            if (perms.isEmpty()) {
7481                mGrantedUriPermissions.remove(targetUid);
7482                N--;
7483                i--;
7484            }
7485        }
7486
7487        if (persistChanged) {
7488            schedulePersistUriGrants();
7489        }
7490    }
7491
7492    /**
7493     * @param uri This uri must NOT contain an embedded userId.
7494     * @param userId The userId in which the uri is to be resolved.
7495     */
7496    @Override
7497    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7498            int userId) {
7499        enforceNotIsolatedCaller("revokeUriPermission");
7500        synchronized(this) {
7501            final ProcessRecord r = getRecordForAppLocked(caller);
7502            if (r == null) {
7503                throw new SecurityException("Unable to find app for caller "
7504                        + caller
7505                        + " when revoking permission to uri " + uri);
7506            }
7507            if (uri == null) {
7508                Slog.w(TAG, "revokeUriPermission: null uri");
7509                return;
7510            }
7511
7512            if (!Intent.isAccessUriMode(modeFlags)) {
7513                return;
7514            }
7515
7516            final IPackageManager pm = AppGlobals.getPackageManager();
7517            final String authority = uri.getAuthority();
7518            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7519            if (pi == null) {
7520                Slog.w(TAG, "No content provider found for permission revoke: "
7521                        + uri.toSafeString());
7522                return;
7523            }
7524
7525            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7526        }
7527    }
7528
7529    /**
7530     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7531     * given package.
7532     *
7533     * @param packageName Package name to match, or {@code null} to apply to all
7534     *            packages.
7535     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7536     *            to all users.
7537     * @param persistable If persistable grants should be removed.
7538     */
7539    private void removeUriPermissionsForPackageLocked(
7540            String packageName, int userHandle, boolean persistable) {
7541        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7542            throw new IllegalArgumentException("Must narrow by either package or user");
7543        }
7544
7545        boolean persistChanged = false;
7546
7547        int N = mGrantedUriPermissions.size();
7548        for (int i = 0; i < N; i++) {
7549            final int targetUid = mGrantedUriPermissions.keyAt(i);
7550            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7551
7552            // Only inspect grants matching user
7553            if (userHandle == UserHandle.USER_ALL
7554                    || userHandle == UserHandle.getUserId(targetUid)) {
7555                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7556                    final UriPermission perm = it.next();
7557
7558                    // Only inspect grants matching package
7559                    if (packageName == null || perm.sourcePkg.equals(packageName)
7560                            || perm.targetPkg.equals(packageName)) {
7561                        persistChanged |= perm.revokeModes(
7562                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7563
7564                        // Only remove when no modes remain; any persisted grants
7565                        // will keep this alive.
7566                        if (perm.modeFlags == 0) {
7567                            it.remove();
7568                        }
7569                    }
7570                }
7571
7572                if (perms.isEmpty()) {
7573                    mGrantedUriPermissions.remove(targetUid);
7574                    N--;
7575                    i--;
7576                }
7577            }
7578        }
7579
7580        if (persistChanged) {
7581            schedulePersistUriGrants();
7582        }
7583    }
7584
7585    @Override
7586    public IBinder newUriPermissionOwner(String name) {
7587        enforceNotIsolatedCaller("newUriPermissionOwner");
7588        synchronized(this) {
7589            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7590            return owner.getExternalTokenLocked();
7591        }
7592    }
7593
7594    /**
7595     * @param uri This uri must NOT contain an embedded userId.
7596     * @param sourceUserId The userId in which the uri is to be resolved.
7597     * @param targetUserId The userId of the app that receives the grant.
7598     */
7599    @Override
7600    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7601            final int modeFlags, int sourceUserId, int targetUserId) {
7602        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7603                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7604        synchronized(this) {
7605            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7606            if (owner == null) {
7607                throw new IllegalArgumentException("Unknown owner: " + token);
7608            }
7609            if (fromUid != Binder.getCallingUid()) {
7610                if (Binder.getCallingUid() != Process.myUid()) {
7611                    // Only system code can grant URI permissions on behalf
7612                    // of other users.
7613                    throw new SecurityException("nice try");
7614                }
7615            }
7616            if (targetPkg == null) {
7617                throw new IllegalArgumentException("null target");
7618            }
7619            if (uri == null) {
7620                throw new IllegalArgumentException("null uri");
7621            }
7622
7623            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7624                    modeFlags, owner, targetUserId);
7625        }
7626    }
7627
7628    /**
7629     * @param uri This uri must NOT contain an embedded userId.
7630     * @param userId The userId in which the uri is to be resolved.
7631     */
7632    @Override
7633    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7634        synchronized(this) {
7635            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7636            if (owner == null) {
7637                throw new IllegalArgumentException("Unknown owner: " + token);
7638            }
7639
7640            if (uri == null) {
7641                owner.removeUriPermissionsLocked(mode);
7642            } else {
7643                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7644            }
7645        }
7646    }
7647
7648    private void schedulePersistUriGrants() {
7649        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7650            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7651                    10 * DateUtils.SECOND_IN_MILLIS);
7652        }
7653    }
7654
7655    private void writeGrantedUriPermissions() {
7656        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7657
7658        // Snapshot permissions so we can persist without lock
7659        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7660        synchronized (this) {
7661            final int size = mGrantedUriPermissions.size();
7662            for (int i = 0; i < size; i++) {
7663                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7664                for (UriPermission perm : perms.values()) {
7665                    if (perm.persistedModeFlags != 0) {
7666                        persist.add(perm.snapshot());
7667                    }
7668                }
7669            }
7670        }
7671
7672        FileOutputStream fos = null;
7673        try {
7674            fos = mGrantFile.startWrite();
7675
7676            XmlSerializer out = new FastXmlSerializer();
7677            out.setOutput(fos, "utf-8");
7678            out.startDocument(null, true);
7679            out.startTag(null, TAG_URI_GRANTS);
7680            for (UriPermission.Snapshot perm : persist) {
7681                out.startTag(null, TAG_URI_GRANT);
7682                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7683                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7684                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7685                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7686                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7687                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7688                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7689                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7690                out.endTag(null, TAG_URI_GRANT);
7691            }
7692            out.endTag(null, TAG_URI_GRANTS);
7693            out.endDocument();
7694
7695            mGrantFile.finishWrite(fos);
7696        } catch (IOException e) {
7697            if (fos != null) {
7698                mGrantFile.failWrite(fos);
7699            }
7700        }
7701    }
7702
7703    private void readGrantedUriPermissionsLocked() {
7704        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7705
7706        final long now = System.currentTimeMillis();
7707
7708        FileInputStream fis = null;
7709        try {
7710            fis = mGrantFile.openRead();
7711            final XmlPullParser in = Xml.newPullParser();
7712            in.setInput(fis, null);
7713
7714            int type;
7715            while ((type = in.next()) != END_DOCUMENT) {
7716                final String tag = in.getName();
7717                if (type == START_TAG) {
7718                    if (TAG_URI_GRANT.equals(tag)) {
7719                        final int sourceUserId;
7720                        final int targetUserId;
7721                        final int userHandle = readIntAttribute(in,
7722                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7723                        if (userHandle != UserHandle.USER_NULL) {
7724                            // For backwards compatibility.
7725                            sourceUserId = userHandle;
7726                            targetUserId = userHandle;
7727                        } else {
7728                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7729                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7730                        }
7731                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7732                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7733                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7734                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7735                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7736                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7737
7738                        // Sanity check that provider still belongs to source package
7739                        final ProviderInfo pi = getProviderInfoLocked(
7740                                uri.getAuthority(), sourceUserId);
7741                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7742                            int targetUid = -1;
7743                            try {
7744                                targetUid = AppGlobals.getPackageManager()
7745                                        .getPackageUid(targetPkg, targetUserId);
7746                            } catch (RemoteException e) {
7747                            }
7748                            if (targetUid != -1) {
7749                                final UriPermission perm = findOrCreateUriPermissionLocked(
7750                                        sourcePkg, targetPkg, targetUid,
7751                                        new GrantUri(sourceUserId, uri, prefix));
7752                                perm.initPersistedModes(modeFlags, createdTime);
7753                            }
7754                        } else {
7755                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7756                                    + " but instead found " + pi);
7757                        }
7758                    }
7759                }
7760            }
7761        } catch (FileNotFoundException e) {
7762            // Missing grants is okay
7763        } catch (IOException e) {
7764            Log.wtf(TAG, "Failed reading Uri grants", e);
7765        } catch (XmlPullParserException e) {
7766            Log.wtf(TAG, "Failed reading Uri grants", e);
7767        } finally {
7768            IoUtils.closeQuietly(fis);
7769        }
7770    }
7771
7772    /**
7773     * @param uri This uri must NOT contain an embedded userId.
7774     * @param userId The userId in which the uri is to be resolved.
7775     */
7776    @Override
7777    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7778        enforceNotIsolatedCaller("takePersistableUriPermission");
7779
7780        Preconditions.checkFlagsArgument(modeFlags,
7781                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7782
7783        synchronized (this) {
7784            final int callingUid = Binder.getCallingUid();
7785            boolean persistChanged = false;
7786            GrantUri grantUri = new GrantUri(userId, uri, false);
7787
7788            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7789                    new GrantUri(userId, uri, false));
7790            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7791                    new GrantUri(userId, uri, true));
7792
7793            final boolean exactValid = (exactPerm != null)
7794                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7795            final boolean prefixValid = (prefixPerm != null)
7796                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7797
7798            if (!(exactValid || prefixValid)) {
7799                throw new SecurityException("No persistable permission grants found for UID "
7800                        + callingUid + " and Uri " + grantUri.toSafeString());
7801            }
7802
7803            if (exactValid) {
7804                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7805            }
7806            if (prefixValid) {
7807                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7808            }
7809
7810            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7811
7812            if (persistChanged) {
7813                schedulePersistUriGrants();
7814            }
7815        }
7816    }
7817
7818    /**
7819     * @param uri This uri must NOT contain an embedded userId.
7820     * @param userId The userId in which the uri is to be resolved.
7821     */
7822    @Override
7823    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7824        enforceNotIsolatedCaller("releasePersistableUriPermission");
7825
7826        Preconditions.checkFlagsArgument(modeFlags,
7827                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7828
7829        synchronized (this) {
7830            final int callingUid = Binder.getCallingUid();
7831            boolean persistChanged = false;
7832
7833            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7834                    new GrantUri(userId, uri, false));
7835            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7836                    new GrantUri(userId, uri, true));
7837            if (exactPerm == null && prefixPerm == null) {
7838                throw new SecurityException("No permission grants found for UID " + callingUid
7839                        + " and Uri " + uri.toSafeString());
7840            }
7841
7842            if (exactPerm != null) {
7843                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7844                removeUriPermissionIfNeededLocked(exactPerm);
7845            }
7846            if (prefixPerm != null) {
7847                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7848                removeUriPermissionIfNeededLocked(prefixPerm);
7849            }
7850
7851            if (persistChanged) {
7852                schedulePersistUriGrants();
7853            }
7854        }
7855    }
7856
7857    /**
7858     * Prune any older {@link UriPermission} for the given UID until outstanding
7859     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7860     *
7861     * @return if any mutations occured that require persisting.
7862     */
7863    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7864        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7865        if (perms == null) return false;
7866        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7867
7868        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7869        for (UriPermission perm : perms.values()) {
7870            if (perm.persistedModeFlags != 0) {
7871                persisted.add(perm);
7872            }
7873        }
7874
7875        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7876        if (trimCount <= 0) return false;
7877
7878        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7879        for (int i = 0; i < trimCount; i++) {
7880            final UriPermission perm = persisted.get(i);
7881
7882            if (DEBUG_URI_PERMISSION) {
7883                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7884            }
7885
7886            perm.releasePersistableModes(~0);
7887            removeUriPermissionIfNeededLocked(perm);
7888        }
7889
7890        return true;
7891    }
7892
7893    @Override
7894    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7895            String packageName, boolean incoming) {
7896        enforceNotIsolatedCaller("getPersistedUriPermissions");
7897        Preconditions.checkNotNull(packageName, "packageName");
7898
7899        final int callingUid = Binder.getCallingUid();
7900        final IPackageManager pm = AppGlobals.getPackageManager();
7901        try {
7902            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7903            if (packageUid != callingUid) {
7904                throw new SecurityException(
7905                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7906            }
7907        } catch (RemoteException e) {
7908            throw new SecurityException("Failed to verify package name ownership");
7909        }
7910
7911        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7912        synchronized (this) {
7913            if (incoming) {
7914                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7915                        callingUid);
7916                if (perms == null) {
7917                    Slog.w(TAG, "No permission grants found for " + packageName);
7918                } else {
7919                    for (UriPermission perm : perms.values()) {
7920                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7921                            result.add(perm.buildPersistedPublicApiObject());
7922                        }
7923                    }
7924                }
7925            } else {
7926                final int size = mGrantedUriPermissions.size();
7927                for (int i = 0; i < size; i++) {
7928                    final ArrayMap<GrantUri, UriPermission> perms =
7929                            mGrantedUriPermissions.valueAt(i);
7930                    for (UriPermission perm : perms.values()) {
7931                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7932                            result.add(perm.buildPersistedPublicApiObject());
7933                        }
7934                    }
7935                }
7936            }
7937        }
7938        return new ParceledListSlice<android.content.UriPermission>(result);
7939    }
7940
7941    @Override
7942    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7943        synchronized (this) {
7944            ProcessRecord app =
7945                who != null ? getRecordForAppLocked(who) : null;
7946            if (app == null) return;
7947
7948            Message msg = Message.obtain();
7949            msg.what = WAIT_FOR_DEBUGGER_MSG;
7950            msg.obj = app;
7951            msg.arg1 = waiting ? 1 : 0;
7952            mHandler.sendMessage(msg);
7953        }
7954    }
7955
7956    @Override
7957    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7958        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7959        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7960        outInfo.availMem = Process.getFreeMemory();
7961        outInfo.totalMem = Process.getTotalMemory();
7962        outInfo.threshold = homeAppMem;
7963        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7964        outInfo.hiddenAppThreshold = cachedAppMem;
7965        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7966                ProcessList.SERVICE_ADJ);
7967        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7968                ProcessList.VISIBLE_APP_ADJ);
7969        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7970                ProcessList.FOREGROUND_APP_ADJ);
7971    }
7972
7973    // =========================================================
7974    // TASK MANAGEMENT
7975    // =========================================================
7976
7977    @Override
7978    public List<IAppTask> getAppTasks(String callingPackage) {
7979        int callingUid = Binder.getCallingUid();
7980        long ident = Binder.clearCallingIdentity();
7981
7982        synchronized(this) {
7983            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7984            try {
7985                if (localLOGV) Slog.v(TAG, "getAppTasks");
7986
7987                final int N = mRecentTasks.size();
7988                for (int i = 0; i < N; i++) {
7989                    TaskRecord tr = mRecentTasks.get(i);
7990                    // Skip tasks that do not match the caller.  We don't need to verify
7991                    // callingPackage, because we are also limiting to callingUid and know
7992                    // that will limit to the correct security sandbox.
7993                    if (tr.effectiveUid != callingUid) {
7994                        continue;
7995                    }
7996                    Intent intent = tr.getBaseIntent();
7997                    if (intent == null ||
7998                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7999                        continue;
8000                    }
8001                    ActivityManager.RecentTaskInfo taskInfo =
8002                            createRecentTaskInfoFromTaskRecord(tr);
8003                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8004                    list.add(taskImpl);
8005                }
8006            } finally {
8007                Binder.restoreCallingIdentity(ident);
8008            }
8009            return list;
8010        }
8011    }
8012
8013    @Override
8014    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8015        final int callingUid = Binder.getCallingUid();
8016        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8017
8018        synchronized(this) {
8019            if (localLOGV) Slog.v(
8020                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8021
8022            final boolean allowed = checkCallingPermission(
8023                    android.Manifest.permission.GET_TASKS)
8024                    == PackageManager.PERMISSION_GRANTED;
8025            if (!allowed) {
8026                Slog.w(TAG, "getTasks: caller " + callingUid
8027                        + " does not hold GET_TASKS; limiting output");
8028            }
8029
8030            // TODO: Improve with MRU list from all ActivityStacks.
8031            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8032        }
8033
8034        return list;
8035    }
8036
8037    TaskRecord getMostRecentTask() {
8038        return mRecentTasks.get(0);
8039    }
8040
8041    /**
8042     * Creates a new RecentTaskInfo from a TaskRecord.
8043     */
8044    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8045        // Update the task description to reflect any changes in the task stack
8046        tr.updateTaskDescription();
8047
8048        // Compose the recent task info
8049        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8050        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8051        rti.persistentId = tr.taskId;
8052        rti.baseIntent = new Intent(tr.getBaseIntent());
8053        rti.origActivity = tr.origActivity;
8054        rti.description = tr.lastDescription;
8055        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8056        rti.userId = tr.userId;
8057        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8058        rti.firstActiveTime = tr.firstActiveTime;
8059        rti.lastActiveTime = tr.lastActiveTime;
8060        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8061        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8062        return rti;
8063    }
8064
8065    @Override
8066    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8067        final int callingUid = Binder.getCallingUid();
8068        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8069                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8070
8071        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8072        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8073        synchronized (this) {
8074            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8075                    == PackageManager.PERMISSION_GRANTED;
8076            if (!allowed) {
8077                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8078                        + " does not hold GET_TASKS; limiting output");
8079            }
8080            final boolean detailed = checkCallingPermission(
8081                    android.Manifest.permission.GET_DETAILED_TASKS)
8082                    == PackageManager.PERMISSION_GRANTED;
8083
8084            final int N = mRecentTasks.size();
8085            ArrayList<ActivityManager.RecentTaskInfo> res
8086                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8087                            maxNum < N ? maxNum : N);
8088
8089            final Set<Integer> includedUsers;
8090            if (includeProfiles) {
8091                includedUsers = getProfileIdsLocked(userId);
8092            } else {
8093                includedUsers = new HashSet<Integer>();
8094            }
8095            includedUsers.add(Integer.valueOf(userId));
8096
8097            for (int i=0; i<N && maxNum > 0; i++) {
8098                TaskRecord tr = mRecentTasks.get(i);
8099                // Only add calling user or related users recent tasks
8100                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8101                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8102                    continue;
8103                }
8104
8105                // Return the entry if desired by the caller.  We always return
8106                // the first entry, because callers always expect this to be the
8107                // foreground app.  We may filter others if the caller has
8108                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8109                // we should exclude the entry.
8110
8111                if (i == 0
8112                        || withExcluded
8113                        || (tr.intent == null)
8114                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8115                                == 0)) {
8116                    if (!allowed) {
8117                        // If the caller doesn't have the GET_TASKS permission, then only
8118                        // allow them to see a small subset of tasks -- their own and home.
8119                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8120                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8121                            continue;
8122                        }
8123                    }
8124                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8125                        if (tr.stack != null && tr.stack.isHomeStack()) {
8126                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8127                            continue;
8128                        }
8129                    }
8130                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8131                        // Don't include auto remove tasks that are finished or finishing.
8132                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8133                                + tr);
8134                        continue;
8135                    }
8136                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8137                            && !tr.isAvailable) {
8138                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8139                        continue;
8140                    }
8141
8142                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8143                    if (!detailed) {
8144                        rti.baseIntent.replaceExtras((Bundle)null);
8145                    }
8146
8147                    res.add(rti);
8148                    maxNum--;
8149                }
8150            }
8151            return res;
8152        }
8153    }
8154
8155    private TaskRecord recentTaskForIdLocked(int id) {
8156        final int N = mRecentTasks.size();
8157            for (int i=0; i<N; i++) {
8158                TaskRecord tr = mRecentTasks.get(i);
8159                if (tr.taskId == id) {
8160                    return tr;
8161                }
8162            }
8163            return null;
8164    }
8165
8166    @Override
8167    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8168        synchronized (this) {
8169            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8170                    "getTaskThumbnail()");
8171            TaskRecord tr = recentTaskForIdLocked(id);
8172            if (tr != null) {
8173                return tr.getTaskThumbnailLocked();
8174            }
8175        }
8176        return null;
8177    }
8178
8179    @Override
8180    public int addAppTask(IBinder activityToken, Intent intent,
8181            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8182        final int callingUid = Binder.getCallingUid();
8183        final long callingIdent = Binder.clearCallingIdentity();
8184
8185        try {
8186            synchronized (this) {
8187                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8188                if (r == null) {
8189                    throw new IllegalArgumentException("Activity does not exist; token="
8190                            + activityToken);
8191                }
8192                ComponentName comp = intent.getComponent();
8193                if (comp == null) {
8194                    throw new IllegalArgumentException("Intent " + intent
8195                            + " must specify explicit component");
8196                }
8197                if (thumbnail.getWidth() != mThumbnailWidth
8198                        || thumbnail.getHeight() != mThumbnailHeight) {
8199                    throw new IllegalArgumentException("Bad thumbnail size: got "
8200                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8201                            + mThumbnailWidth + "x" + mThumbnailHeight);
8202                }
8203                if (intent.getSelector() != null) {
8204                    intent.setSelector(null);
8205                }
8206                if (intent.getSourceBounds() != null) {
8207                    intent.setSourceBounds(null);
8208                }
8209                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8210                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8211                        // The caller has added this as an auto-remove task...  that makes no
8212                        // sense, so turn off auto-remove.
8213                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8214                    }
8215                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8216                    // Must be a new task.
8217                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8218                }
8219                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8220                    mLastAddedTaskActivity = null;
8221                }
8222                ActivityInfo ainfo = mLastAddedTaskActivity;
8223                if (ainfo == null) {
8224                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8225                            comp, 0, UserHandle.getUserId(callingUid));
8226                    if (ainfo.applicationInfo.uid != callingUid) {
8227                        throw new SecurityException(
8228                                "Can't add task for another application: target uid="
8229                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8230                    }
8231                }
8232
8233                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8234                        intent, description);
8235
8236                int trimIdx = trimRecentsForTask(task, false);
8237                if (trimIdx >= 0) {
8238                    // If this would have caused a trim, then we'll abort because that
8239                    // means it would be added at the end of the list but then just removed.
8240                    return -1;
8241                }
8242
8243                final int N = mRecentTasks.size();
8244                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8245                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8246                    tr.removedFromRecents(mTaskPersister);
8247                }
8248
8249                task.inRecents = true;
8250                mRecentTasks.add(task);
8251                r.task.stack.addTask(task, false, false);
8252
8253                task.setLastThumbnail(thumbnail);
8254                task.freeLastThumbnail();
8255
8256                return task.taskId;
8257            }
8258        } finally {
8259            Binder.restoreCallingIdentity(callingIdent);
8260        }
8261    }
8262
8263    @Override
8264    public Point getAppTaskThumbnailSize() {
8265        synchronized (this) {
8266            return new Point(mThumbnailWidth,  mThumbnailHeight);
8267        }
8268    }
8269
8270    @Override
8271    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8272        synchronized (this) {
8273            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8274            if (r != null) {
8275                r.taskDescription = td;
8276                r.task.updateTaskDescription();
8277            }
8278        }
8279    }
8280
8281    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8282        mRecentTasks.remove(tr);
8283        tr.removedFromRecents(mTaskPersister);
8284        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8285        Intent baseIntent = new Intent(
8286                tr.intent != null ? tr.intent : tr.affinityIntent);
8287        ComponentName component = baseIntent.getComponent();
8288        if (component == null) {
8289            Slog.w(TAG, "Now component for base intent of task: " + tr);
8290            return;
8291        }
8292
8293        // Find any running services associated with this app.
8294        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8295
8296        if (killProcesses) {
8297            // Find any running processes associated with this app.
8298            final String pkg = component.getPackageName();
8299            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8300            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8301            for (int i=0; i<pmap.size(); i++) {
8302                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8303                for (int j=0; j<uids.size(); j++) {
8304                    ProcessRecord proc = uids.valueAt(j);
8305                    if (proc.userId != tr.userId) {
8306                        continue;
8307                    }
8308                    if (!proc.pkgList.containsKey(pkg)) {
8309                        continue;
8310                    }
8311                    procs.add(proc);
8312                }
8313            }
8314
8315            // Kill the running processes.
8316            for (int i=0; i<procs.size(); i++) {
8317                ProcessRecord pr = procs.get(i);
8318                if (pr == mHomeProcess) {
8319                    // Don't kill the home process along with tasks from the same package.
8320                    continue;
8321                }
8322                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8323                    pr.kill("remove task", true);
8324                } else {
8325                    pr.waitingToKill = "remove task";
8326                }
8327            }
8328        }
8329    }
8330
8331    /**
8332     * Removes the task with the specified task id.
8333     *
8334     * @param taskId Identifier of the task to be removed.
8335     * @param flags Additional operational flags.  May be 0 or
8336     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8337     * @return Returns true if the given task was found and removed.
8338     */
8339    private boolean removeTaskByIdLocked(int taskId, int flags) {
8340        TaskRecord tr = recentTaskForIdLocked(taskId);
8341        if (tr != null) {
8342            tr.removeTaskActivitiesLocked();
8343            cleanUpRemovedTaskLocked(tr, flags);
8344            if (tr.isPersistable) {
8345                notifyTaskPersisterLocked(null, true);
8346            }
8347            return true;
8348        }
8349        return false;
8350    }
8351
8352    @Override
8353    public boolean removeTask(int taskId, int flags) {
8354        synchronized (this) {
8355            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8356                    "removeTask()");
8357            long ident = Binder.clearCallingIdentity();
8358            try {
8359                return removeTaskByIdLocked(taskId, flags);
8360            } finally {
8361                Binder.restoreCallingIdentity(ident);
8362            }
8363        }
8364    }
8365
8366    /**
8367     * TODO: Add mController hook
8368     */
8369    @Override
8370    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8371        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8372                "moveTaskToFront()");
8373
8374        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8375        synchronized(this) {
8376            moveTaskToFrontLocked(taskId, flags, options);
8377        }
8378    }
8379
8380    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8381        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8382                Binder.getCallingUid(), "Task to front")) {
8383            ActivityOptions.abort(options);
8384            return;
8385        }
8386        final long origId = Binder.clearCallingIdentity();
8387        try {
8388            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8389            if (task == null) {
8390                return;
8391            }
8392            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8393                mStackSupervisor.showLockTaskToast();
8394                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8395                return;
8396            }
8397            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8398            if (prev != null && prev.isRecentsActivity()) {
8399                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8400            }
8401            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8402        } finally {
8403            Binder.restoreCallingIdentity(origId);
8404        }
8405        ActivityOptions.abort(options);
8406    }
8407
8408    @Override
8409    public void moveTaskToBack(int taskId) {
8410        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8411                "moveTaskToBack()");
8412
8413        synchronized(this) {
8414            TaskRecord tr = recentTaskForIdLocked(taskId);
8415            if (tr != null) {
8416                if (tr == mStackSupervisor.mLockTaskModeTask) {
8417                    mStackSupervisor.showLockTaskToast();
8418                    return;
8419                }
8420                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8421                ActivityStack stack = tr.stack;
8422                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8423                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8424                            Binder.getCallingUid(), "Task to back")) {
8425                        return;
8426                    }
8427                }
8428                final long origId = Binder.clearCallingIdentity();
8429                try {
8430                    stack.moveTaskToBackLocked(taskId, null);
8431                } finally {
8432                    Binder.restoreCallingIdentity(origId);
8433                }
8434            }
8435        }
8436    }
8437
8438    /**
8439     * Moves an activity, and all of the other activities within the same task, to the bottom
8440     * of the history stack.  The activity's order within the task is unchanged.
8441     *
8442     * @param token A reference to the activity we wish to move
8443     * @param nonRoot If false then this only works if the activity is the root
8444     *                of a task; if true it will work for any activity in a task.
8445     * @return Returns true if the move completed, false if not.
8446     */
8447    @Override
8448    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8449        enforceNotIsolatedCaller("moveActivityTaskToBack");
8450        synchronized(this) {
8451            final long origId = Binder.clearCallingIdentity();
8452            try {
8453                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8454                if (taskId >= 0) {
8455                    if ((mStackSupervisor.mLockTaskModeTask != null)
8456                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8457                        mStackSupervisor.showLockTaskToast();
8458                        return false;
8459                    }
8460                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8461                }
8462            } finally {
8463                Binder.restoreCallingIdentity(origId);
8464            }
8465        }
8466        return false;
8467    }
8468
8469    @Override
8470    public void moveTaskBackwards(int task) {
8471        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8472                "moveTaskBackwards()");
8473
8474        synchronized(this) {
8475            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8476                    Binder.getCallingUid(), "Task backwards")) {
8477                return;
8478            }
8479            final long origId = Binder.clearCallingIdentity();
8480            moveTaskBackwardsLocked(task);
8481            Binder.restoreCallingIdentity(origId);
8482        }
8483    }
8484
8485    private final void moveTaskBackwardsLocked(int task) {
8486        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8487    }
8488
8489    @Override
8490    public IBinder getHomeActivityToken() throws RemoteException {
8491        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8492                "getHomeActivityToken()");
8493        synchronized (this) {
8494            return mStackSupervisor.getHomeActivityToken();
8495        }
8496    }
8497
8498    @Override
8499    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8500            IActivityContainerCallback callback) throws RemoteException {
8501        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8502                "createActivityContainer()");
8503        synchronized (this) {
8504            if (parentActivityToken == null) {
8505                throw new IllegalArgumentException("parent token must not be null");
8506            }
8507            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8508            if (r == null) {
8509                return null;
8510            }
8511            if (callback == null) {
8512                throw new IllegalArgumentException("callback must not be null");
8513            }
8514            return mStackSupervisor.createActivityContainer(r, callback);
8515        }
8516    }
8517
8518    @Override
8519    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8520        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8521                "deleteActivityContainer()");
8522        synchronized (this) {
8523            mStackSupervisor.deleteActivityContainer(container);
8524        }
8525    }
8526
8527    @Override
8528    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8529            throws RemoteException {
8530        synchronized (this) {
8531            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8532            if (stack != null) {
8533                return stack.mActivityContainer;
8534            }
8535            return null;
8536        }
8537    }
8538
8539    @Override
8540    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8541        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8542                "moveTaskToStack()");
8543        if (stackId == HOME_STACK_ID) {
8544            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8545                    new RuntimeException("here").fillInStackTrace());
8546        }
8547        synchronized (this) {
8548            long ident = Binder.clearCallingIdentity();
8549            try {
8550                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8551                        + stackId + " toTop=" + toTop);
8552                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8553            } finally {
8554                Binder.restoreCallingIdentity(ident);
8555            }
8556        }
8557    }
8558
8559    @Override
8560    public void resizeStack(int stackBoxId, Rect bounds) {
8561        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8562                "resizeStackBox()");
8563        long ident = Binder.clearCallingIdentity();
8564        try {
8565            mWindowManager.resizeStack(stackBoxId, bounds);
8566        } finally {
8567            Binder.restoreCallingIdentity(ident);
8568        }
8569    }
8570
8571    @Override
8572    public List<StackInfo> getAllStackInfos() {
8573        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8574                "getAllStackInfos()");
8575        long ident = Binder.clearCallingIdentity();
8576        try {
8577            synchronized (this) {
8578                return mStackSupervisor.getAllStackInfosLocked();
8579            }
8580        } finally {
8581            Binder.restoreCallingIdentity(ident);
8582        }
8583    }
8584
8585    @Override
8586    public StackInfo getStackInfo(int stackId) {
8587        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8588                "getStackInfo()");
8589        long ident = Binder.clearCallingIdentity();
8590        try {
8591            synchronized (this) {
8592                return mStackSupervisor.getStackInfoLocked(stackId);
8593            }
8594        } finally {
8595            Binder.restoreCallingIdentity(ident);
8596        }
8597    }
8598
8599    @Override
8600    public boolean isInHomeStack(int taskId) {
8601        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8602                "getStackInfo()");
8603        long ident = Binder.clearCallingIdentity();
8604        try {
8605            synchronized (this) {
8606                TaskRecord tr = recentTaskForIdLocked(taskId);
8607                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8608            }
8609        } finally {
8610            Binder.restoreCallingIdentity(ident);
8611        }
8612    }
8613
8614    @Override
8615    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8616        synchronized(this) {
8617            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8618        }
8619    }
8620
8621    private boolean isLockTaskAuthorized(String pkg) {
8622        final DevicePolicyManager dpm = (DevicePolicyManager)
8623                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8624        try {
8625            int uid = mContext.getPackageManager().getPackageUid(pkg,
8626                    Binder.getCallingUserHandle().getIdentifier());
8627            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8628        } catch (NameNotFoundException e) {
8629            return false;
8630        }
8631    }
8632
8633    void startLockTaskMode(TaskRecord task) {
8634        final String pkg;
8635        synchronized (this) {
8636            pkg = task.intent.getComponent().getPackageName();
8637        }
8638        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8639        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8640            final TaskRecord taskRecord = task;
8641            mHandler.post(new Runnable() {
8642                @Override
8643                public void run() {
8644                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8645                }
8646            });
8647            return;
8648        }
8649        long ident = Binder.clearCallingIdentity();
8650        try {
8651            synchronized (this) {
8652                // Since we lost lock on task, make sure it is still there.
8653                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8654                if (task != null) {
8655                    if (!isSystemInitiated
8656                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8657                        throw new IllegalArgumentException("Invalid task, not in foreground");
8658                    }
8659                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8660                }
8661            }
8662        } finally {
8663            Binder.restoreCallingIdentity(ident);
8664        }
8665    }
8666
8667    @Override
8668    public void startLockTaskMode(int taskId) {
8669        final TaskRecord task;
8670        long ident = Binder.clearCallingIdentity();
8671        try {
8672            synchronized (this) {
8673                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8674            }
8675        } finally {
8676            Binder.restoreCallingIdentity(ident);
8677        }
8678        if (task != null) {
8679            startLockTaskMode(task);
8680        }
8681    }
8682
8683    @Override
8684    public void startLockTaskMode(IBinder token) {
8685        final TaskRecord task;
8686        long ident = Binder.clearCallingIdentity();
8687        try {
8688            synchronized (this) {
8689                final ActivityRecord r = ActivityRecord.forToken(token);
8690                if (r == null) {
8691                    return;
8692                }
8693                task = r.task;
8694            }
8695        } finally {
8696            Binder.restoreCallingIdentity(ident);
8697        }
8698        if (task != null) {
8699            startLockTaskMode(task);
8700        }
8701    }
8702
8703    @Override
8704    public void startLockTaskModeOnCurrent() throws RemoteException {
8705        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8706                "startLockTaskModeOnCurrent");
8707        ActivityRecord r = null;
8708        synchronized (this) {
8709            r = mStackSupervisor.topRunningActivityLocked();
8710        }
8711        startLockTaskMode(r.task);
8712    }
8713
8714    @Override
8715    public void stopLockTaskMode() {
8716        // Verify that the user matches the package of the intent for the TaskRecord
8717        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8718        // and stopLockTaskMode.
8719        final int callingUid = Binder.getCallingUid();
8720        if (callingUid != Process.SYSTEM_UID) {
8721            try {
8722                String pkg =
8723                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8724                int uid = mContext.getPackageManager().getPackageUid(pkg,
8725                        Binder.getCallingUserHandle().getIdentifier());
8726                if (uid != callingUid) {
8727                    throw new SecurityException("Invalid uid, expected " + uid);
8728                }
8729            } catch (NameNotFoundException e) {
8730                Log.d(TAG, "stopLockTaskMode " + e);
8731                return;
8732            }
8733        }
8734        long ident = Binder.clearCallingIdentity();
8735        try {
8736            Log.d(TAG, "stopLockTaskMode");
8737            // Stop lock task
8738            synchronized (this) {
8739                mStackSupervisor.setLockTaskModeLocked(null, false);
8740            }
8741        } finally {
8742            Binder.restoreCallingIdentity(ident);
8743        }
8744    }
8745
8746    @Override
8747    public void stopLockTaskModeOnCurrent() throws RemoteException {
8748        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8749                "stopLockTaskModeOnCurrent");
8750        long ident = Binder.clearCallingIdentity();
8751        try {
8752            stopLockTaskMode();
8753        } finally {
8754            Binder.restoreCallingIdentity(ident);
8755        }
8756    }
8757
8758    @Override
8759    public boolean isInLockTaskMode() {
8760        synchronized (this) {
8761            return mStackSupervisor.isInLockTaskMode();
8762        }
8763    }
8764
8765    // =========================================================
8766    // CONTENT PROVIDERS
8767    // =========================================================
8768
8769    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8770        List<ProviderInfo> providers = null;
8771        try {
8772            providers = AppGlobals.getPackageManager().
8773                queryContentProviders(app.processName, app.uid,
8774                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8775        } catch (RemoteException ex) {
8776        }
8777        if (DEBUG_MU)
8778            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8779        int userId = app.userId;
8780        if (providers != null) {
8781            int N = providers.size();
8782            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8783            for (int i=0; i<N; i++) {
8784                ProviderInfo cpi =
8785                    (ProviderInfo)providers.get(i);
8786                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8787                        cpi.name, cpi.flags);
8788                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8789                    // This is a singleton provider, but a user besides the
8790                    // default user is asking to initialize a process it runs
8791                    // in...  well, no, it doesn't actually run in this process,
8792                    // it runs in the process of the default user.  Get rid of it.
8793                    providers.remove(i);
8794                    N--;
8795                    i--;
8796                    continue;
8797                }
8798
8799                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8800                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8801                if (cpr == null) {
8802                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8803                    mProviderMap.putProviderByClass(comp, cpr);
8804                }
8805                if (DEBUG_MU)
8806                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8807                app.pubProviders.put(cpi.name, cpr);
8808                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8809                    // Don't add this if it is a platform component that is marked
8810                    // to run in multiple processes, because this is actually
8811                    // part of the framework so doesn't make sense to track as a
8812                    // separate apk in the process.
8813                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8814                            mProcessStats);
8815                }
8816                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8817            }
8818        }
8819        return providers;
8820    }
8821
8822    /**
8823     * Check if {@link ProcessRecord} has a possible chance at accessing the
8824     * given {@link ProviderInfo}. Final permission checking is always done
8825     * in {@link ContentProvider}.
8826     */
8827    private final String checkContentProviderPermissionLocked(
8828            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8829        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8830        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8831        boolean checkedGrants = false;
8832        if (checkUser) {
8833            // Looking for cross-user grants before enforcing the typical cross-users permissions
8834            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8835            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8836                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8837                    return null;
8838                }
8839                checkedGrants = true;
8840            }
8841            userId = handleIncomingUser(callingPid, callingUid, userId,
8842                    false, ALLOW_NON_FULL,
8843                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8844            if (userId != tmpTargetUserId) {
8845                // When we actually went to determine the final targer user ID, this ended
8846                // up different than our initial check for the authority.  This is because
8847                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8848                // SELF.  So we need to re-check the grants again.
8849                checkedGrants = false;
8850            }
8851        }
8852        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8853                cpi.applicationInfo.uid, cpi.exported)
8854                == PackageManager.PERMISSION_GRANTED) {
8855            return null;
8856        }
8857        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8858                cpi.applicationInfo.uid, cpi.exported)
8859                == PackageManager.PERMISSION_GRANTED) {
8860            return null;
8861        }
8862
8863        PathPermission[] pps = cpi.pathPermissions;
8864        if (pps != null) {
8865            int i = pps.length;
8866            while (i > 0) {
8867                i--;
8868                PathPermission pp = pps[i];
8869                String pprperm = pp.getReadPermission();
8870                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8871                        cpi.applicationInfo.uid, cpi.exported)
8872                        == PackageManager.PERMISSION_GRANTED) {
8873                    return null;
8874                }
8875                String ppwperm = pp.getWritePermission();
8876                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8877                        cpi.applicationInfo.uid, cpi.exported)
8878                        == PackageManager.PERMISSION_GRANTED) {
8879                    return null;
8880                }
8881            }
8882        }
8883        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8884            return null;
8885        }
8886
8887        String msg;
8888        if (!cpi.exported) {
8889            msg = "Permission Denial: opening provider " + cpi.name
8890                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8891                    + ", uid=" + callingUid + ") that is not exported from uid "
8892                    + cpi.applicationInfo.uid;
8893        } else {
8894            msg = "Permission Denial: opening provider " + cpi.name
8895                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8896                    + ", uid=" + callingUid + ") requires "
8897                    + cpi.readPermission + " or " + cpi.writePermission;
8898        }
8899        Slog.w(TAG, msg);
8900        return msg;
8901    }
8902
8903    /**
8904     * Returns if the ContentProvider has granted a uri to callingUid
8905     */
8906    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8907        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8908        if (perms != null) {
8909            for (int i=perms.size()-1; i>=0; i--) {
8910                GrantUri grantUri = perms.keyAt(i);
8911                if (grantUri.sourceUserId == userId || !checkUser) {
8912                    if (matchesProvider(grantUri.uri, cpi)) {
8913                        return true;
8914                    }
8915                }
8916            }
8917        }
8918        return false;
8919    }
8920
8921    /**
8922     * Returns true if the uri authority is one of the authorities specified in the provider.
8923     */
8924    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8925        String uriAuth = uri.getAuthority();
8926        String cpiAuth = cpi.authority;
8927        if (cpiAuth.indexOf(';') == -1) {
8928            return cpiAuth.equals(uriAuth);
8929        }
8930        String[] cpiAuths = cpiAuth.split(";");
8931        int length = cpiAuths.length;
8932        for (int i = 0; i < length; i++) {
8933            if (cpiAuths[i].equals(uriAuth)) return true;
8934        }
8935        return false;
8936    }
8937
8938    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8939            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8940        if (r != null) {
8941            for (int i=0; i<r.conProviders.size(); i++) {
8942                ContentProviderConnection conn = r.conProviders.get(i);
8943                if (conn.provider == cpr) {
8944                    if (DEBUG_PROVIDER) Slog.v(TAG,
8945                            "Adding provider requested by "
8946                            + r.processName + " from process "
8947                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8948                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8949                    if (stable) {
8950                        conn.stableCount++;
8951                        conn.numStableIncs++;
8952                    } else {
8953                        conn.unstableCount++;
8954                        conn.numUnstableIncs++;
8955                    }
8956                    return conn;
8957                }
8958            }
8959            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8960            if (stable) {
8961                conn.stableCount = 1;
8962                conn.numStableIncs = 1;
8963            } else {
8964                conn.unstableCount = 1;
8965                conn.numUnstableIncs = 1;
8966            }
8967            cpr.connections.add(conn);
8968            r.conProviders.add(conn);
8969            return conn;
8970        }
8971        cpr.addExternalProcessHandleLocked(externalProcessToken);
8972        return null;
8973    }
8974
8975    boolean decProviderCountLocked(ContentProviderConnection conn,
8976            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8977        if (conn != null) {
8978            cpr = conn.provider;
8979            if (DEBUG_PROVIDER) Slog.v(TAG,
8980                    "Removing provider requested by "
8981                    + conn.client.processName + " from process "
8982                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8983                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8984            if (stable) {
8985                conn.stableCount--;
8986            } else {
8987                conn.unstableCount--;
8988            }
8989            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8990                cpr.connections.remove(conn);
8991                conn.client.conProviders.remove(conn);
8992                return true;
8993            }
8994            return false;
8995        }
8996        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8997        return false;
8998    }
8999
9000    private void checkTime(long startTime, String where) {
9001        long now = SystemClock.elapsedRealtime();
9002        if ((now-startTime) > 1000) {
9003            // If we are taking more than a second, log about it.
9004            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9005        }
9006    }
9007
9008    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9009            String name, IBinder token, boolean stable, int userId) {
9010        ContentProviderRecord cpr;
9011        ContentProviderConnection conn = null;
9012        ProviderInfo cpi = null;
9013
9014        synchronized(this) {
9015            long startTime = SystemClock.elapsedRealtime();
9016
9017            ProcessRecord r = null;
9018            if (caller != null) {
9019                r = getRecordForAppLocked(caller);
9020                if (r == null) {
9021                    throw new SecurityException(
9022                            "Unable to find app for caller " + caller
9023                          + " (pid=" + Binder.getCallingPid()
9024                          + ") when getting content provider " + name);
9025                }
9026            }
9027
9028            boolean checkCrossUser = true;
9029
9030            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9031
9032            // First check if this content provider has been published...
9033            cpr = mProviderMap.getProviderByName(name, userId);
9034            // If that didn't work, check if it exists for user 0 and then
9035            // verify that it's a singleton provider before using it.
9036            if (cpr == null && userId != UserHandle.USER_OWNER) {
9037                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9038                if (cpr != null) {
9039                    cpi = cpr.info;
9040                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9041                            cpi.name, cpi.flags)
9042                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9043                        userId = UserHandle.USER_OWNER;
9044                        checkCrossUser = false;
9045                    } else {
9046                        cpr = null;
9047                        cpi = null;
9048                    }
9049                }
9050            }
9051
9052            boolean providerRunning = cpr != null;
9053            if (providerRunning) {
9054                cpi = cpr.info;
9055                String msg;
9056                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9057                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9058                        != null) {
9059                    throw new SecurityException(msg);
9060                }
9061                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9062
9063                if (r != null && cpr.canRunHere(r)) {
9064                    // This provider has been published or is in the process
9065                    // of being published...  but it is also allowed to run
9066                    // in the caller's process, so don't make a connection
9067                    // and just let the caller instantiate its own instance.
9068                    ContentProviderHolder holder = cpr.newHolder(null);
9069                    // don't give caller the provider object, it needs
9070                    // to make its own.
9071                    holder.provider = null;
9072                    return holder;
9073                }
9074
9075                final long origId = Binder.clearCallingIdentity();
9076
9077                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9078
9079                // In this case the provider instance already exists, so we can
9080                // return it right away.
9081                conn = incProviderCountLocked(r, cpr, token, stable);
9082                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9083                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9084                        // If this is a perceptible app accessing the provider,
9085                        // make sure to count it as being accessed and thus
9086                        // back up on the LRU list.  This is good because
9087                        // content providers are often expensive to start.
9088                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9089                        updateLruProcessLocked(cpr.proc, false, null);
9090                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9091                    }
9092                }
9093
9094                if (cpr.proc != null) {
9095                    if (false) {
9096                        if (cpr.name.flattenToShortString().equals(
9097                                "com.android.providers.calendar/.CalendarProvider2")) {
9098                            Slog.v(TAG, "****************** KILLING "
9099                                + cpr.name.flattenToShortString());
9100                            Process.killProcess(cpr.proc.pid);
9101                        }
9102                    }
9103                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9104                    boolean success = updateOomAdjLocked(cpr.proc);
9105                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9106                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9107                    // NOTE: there is still a race here where a signal could be
9108                    // pending on the process even though we managed to update its
9109                    // adj level.  Not sure what to do about this, but at least
9110                    // the race is now smaller.
9111                    if (!success) {
9112                        // Uh oh...  it looks like the provider's process
9113                        // has been killed on us.  We need to wait for a new
9114                        // process to be started, and make sure its death
9115                        // doesn't kill our process.
9116                        Slog.i(TAG,
9117                                "Existing provider " + cpr.name.flattenToShortString()
9118                                + " is crashing; detaching " + r);
9119                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9120                        checkTime(startTime, "getContentProviderImpl: before appDied");
9121                        appDiedLocked(cpr.proc);
9122                        checkTime(startTime, "getContentProviderImpl: after appDied");
9123                        if (!lastRef) {
9124                            // This wasn't the last ref our process had on
9125                            // the provider...  we have now been killed, bail.
9126                            return null;
9127                        }
9128                        providerRunning = false;
9129                        conn = null;
9130                    }
9131                }
9132
9133                Binder.restoreCallingIdentity(origId);
9134            }
9135
9136            boolean singleton;
9137            if (!providerRunning) {
9138                try {
9139                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9140                    cpi = AppGlobals.getPackageManager().
9141                        resolveContentProvider(name,
9142                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9143                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9144                } catch (RemoteException ex) {
9145                }
9146                if (cpi == null) {
9147                    return null;
9148                }
9149                // If the provider is a singleton AND
9150                // (it's a call within the same user || the provider is a
9151                // privileged app)
9152                // Then allow connecting to the singleton provider
9153                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9154                        cpi.name, cpi.flags)
9155                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9156                if (singleton) {
9157                    userId = UserHandle.USER_OWNER;
9158                }
9159                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9160                checkTime(startTime, "getContentProviderImpl: got app info for user");
9161
9162                String msg;
9163                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9164                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9165                        != null) {
9166                    throw new SecurityException(msg);
9167                }
9168                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9169
9170                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9171                        && !cpi.processName.equals("system")) {
9172                    // If this content provider does not run in the system
9173                    // process, and the system is not yet ready to run other
9174                    // processes, then fail fast instead of hanging.
9175                    throw new IllegalArgumentException(
9176                            "Attempt to launch content provider before system ready");
9177                }
9178
9179                // Make sure that the user who owns this provider is started.  If not,
9180                // we don't want to allow it to run.
9181                if (mStartedUsers.get(userId) == null) {
9182                    Slog.w(TAG, "Unable to launch app "
9183                            + cpi.applicationInfo.packageName + "/"
9184                            + cpi.applicationInfo.uid + " for provider "
9185                            + name + ": user " + userId + " is stopped");
9186                    return null;
9187                }
9188
9189                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9190                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9191                cpr = mProviderMap.getProviderByClass(comp, userId);
9192                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9193                final boolean firstClass = cpr == null;
9194                if (firstClass) {
9195                    try {
9196                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9197                        ApplicationInfo ai =
9198                            AppGlobals.getPackageManager().
9199                                getApplicationInfo(
9200                                        cpi.applicationInfo.packageName,
9201                                        STOCK_PM_FLAGS, userId);
9202                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9203                        if (ai == null) {
9204                            Slog.w(TAG, "No package info for content provider "
9205                                    + cpi.name);
9206                            return null;
9207                        }
9208                        ai = getAppInfoForUser(ai, userId);
9209                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9210                    } catch (RemoteException ex) {
9211                        // pm is in same process, this will never happen.
9212                    }
9213                }
9214
9215                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9216
9217                if (r != null && cpr.canRunHere(r)) {
9218                    // If this is a multiprocess provider, then just return its
9219                    // info and allow the caller to instantiate it.  Only do
9220                    // this if the provider is the same user as the caller's
9221                    // process, or can run as root (so can be in any process).
9222                    return cpr.newHolder(null);
9223                }
9224
9225                if (DEBUG_PROVIDER) {
9226                    RuntimeException e = new RuntimeException("here");
9227                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9228                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9229                }
9230
9231                // This is single process, and our app is now connecting to it.
9232                // See if we are already in the process of launching this
9233                // provider.
9234                final int N = mLaunchingProviders.size();
9235                int i;
9236                for (i=0; i<N; i++) {
9237                    if (mLaunchingProviders.get(i) == cpr) {
9238                        break;
9239                    }
9240                }
9241
9242                // If the provider is not already being launched, then get it
9243                // started.
9244                if (i >= N) {
9245                    final long origId = Binder.clearCallingIdentity();
9246
9247                    try {
9248                        // Content provider is now in use, its package can't be stopped.
9249                        try {
9250                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9251                            AppGlobals.getPackageManager().setPackageStoppedState(
9252                                    cpr.appInfo.packageName, false, userId);
9253                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9254                        } catch (RemoteException e) {
9255                        } catch (IllegalArgumentException e) {
9256                            Slog.w(TAG, "Failed trying to unstop package "
9257                                    + cpr.appInfo.packageName + ": " + e);
9258                        }
9259
9260                        // Use existing process if already started
9261                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9262                        ProcessRecord proc = getProcessRecordLocked(
9263                                cpi.processName, cpr.appInfo.uid, false);
9264                        if (proc != null && proc.thread != null) {
9265                            if (DEBUG_PROVIDER) {
9266                                Slog.d(TAG, "Installing in existing process " + proc);
9267                            }
9268                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9269                            proc.pubProviders.put(cpi.name, cpr);
9270                            try {
9271                                proc.thread.scheduleInstallProvider(cpi);
9272                            } catch (RemoteException e) {
9273                            }
9274                        } else {
9275                            checkTime(startTime, "getContentProviderImpl: before start process");
9276                            proc = startProcessLocked(cpi.processName,
9277                                    cpr.appInfo, false, 0, "content provider",
9278                                    new ComponentName(cpi.applicationInfo.packageName,
9279                                            cpi.name), false, false, false);
9280                            checkTime(startTime, "getContentProviderImpl: after start process");
9281                            if (proc == null) {
9282                                Slog.w(TAG, "Unable to launch app "
9283                                        + cpi.applicationInfo.packageName + "/"
9284                                        + cpi.applicationInfo.uid + " for provider "
9285                                        + name + ": process is bad");
9286                                return null;
9287                            }
9288                        }
9289                        cpr.launchingApp = proc;
9290                        mLaunchingProviders.add(cpr);
9291                    } finally {
9292                        Binder.restoreCallingIdentity(origId);
9293                    }
9294                }
9295
9296                checkTime(startTime, "getContentProviderImpl: updating data structures");
9297
9298                // Make sure the provider is published (the same provider class
9299                // may be published under multiple names).
9300                if (firstClass) {
9301                    mProviderMap.putProviderByClass(comp, cpr);
9302                }
9303
9304                mProviderMap.putProviderByName(name, cpr);
9305                conn = incProviderCountLocked(r, cpr, token, stable);
9306                if (conn != null) {
9307                    conn.waiting = true;
9308                }
9309            }
9310            checkTime(startTime, "getContentProviderImpl: done!");
9311        }
9312
9313        // Wait for the provider to be published...
9314        synchronized (cpr) {
9315            while (cpr.provider == null) {
9316                if (cpr.launchingApp == null) {
9317                    Slog.w(TAG, "Unable to launch app "
9318                            + cpi.applicationInfo.packageName + "/"
9319                            + cpi.applicationInfo.uid + " for provider "
9320                            + name + ": launching app became null");
9321                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9322                            UserHandle.getUserId(cpi.applicationInfo.uid),
9323                            cpi.applicationInfo.packageName,
9324                            cpi.applicationInfo.uid, name);
9325                    return null;
9326                }
9327                try {
9328                    if (DEBUG_MU) {
9329                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9330                                + cpr.launchingApp);
9331                    }
9332                    if (conn != null) {
9333                        conn.waiting = true;
9334                    }
9335                    cpr.wait();
9336                } catch (InterruptedException ex) {
9337                } finally {
9338                    if (conn != null) {
9339                        conn.waiting = false;
9340                    }
9341                }
9342            }
9343        }
9344        return cpr != null ? cpr.newHolder(conn) : null;
9345    }
9346
9347    @Override
9348    public final ContentProviderHolder getContentProvider(
9349            IApplicationThread caller, String name, int userId, boolean stable) {
9350        enforceNotIsolatedCaller("getContentProvider");
9351        if (caller == null) {
9352            String msg = "null IApplicationThread when getting content provider "
9353                    + name;
9354            Slog.w(TAG, msg);
9355            throw new SecurityException(msg);
9356        }
9357        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9358        // with cross-user grant.
9359        return getContentProviderImpl(caller, name, null, stable, userId);
9360    }
9361
9362    public ContentProviderHolder getContentProviderExternal(
9363            String name, int userId, IBinder token) {
9364        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9365            "Do not have permission in call getContentProviderExternal()");
9366        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9367                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9368        return getContentProviderExternalUnchecked(name, token, userId);
9369    }
9370
9371    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9372            IBinder token, int userId) {
9373        return getContentProviderImpl(null, name, token, true, userId);
9374    }
9375
9376    /**
9377     * Drop a content provider from a ProcessRecord's bookkeeping
9378     */
9379    public void removeContentProvider(IBinder connection, boolean stable) {
9380        enforceNotIsolatedCaller("removeContentProvider");
9381        long ident = Binder.clearCallingIdentity();
9382        try {
9383            synchronized (this) {
9384                ContentProviderConnection conn;
9385                try {
9386                    conn = (ContentProviderConnection)connection;
9387                } catch (ClassCastException e) {
9388                    String msg ="removeContentProvider: " + connection
9389                            + " not a ContentProviderConnection";
9390                    Slog.w(TAG, msg);
9391                    throw new IllegalArgumentException(msg);
9392                }
9393                if (conn == null) {
9394                    throw new NullPointerException("connection is null");
9395                }
9396                if (decProviderCountLocked(conn, null, null, stable)) {
9397                    updateOomAdjLocked();
9398                }
9399            }
9400        } finally {
9401            Binder.restoreCallingIdentity(ident);
9402        }
9403    }
9404
9405    public void removeContentProviderExternal(String name, IBinder token) {
9406        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9407            "Do not have permission in call removeContentProviderExternal()");
9408        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9409    }
9410
9411    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9412        synchronized (this) {
9413            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9414            if(cpr == null) {
9415                //remove from mProvidersByClass
9416                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9417                return;
9418            }
9419
9420            //update content provider record entry info
9421            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9422            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9423            if (localCpr.hasExternalProcessHandles()) {
9424                if (localCpr.removeExternalProcessHandleLocked(token)) {
9425                    updateOomAdjLocked();
9426                } else {
9427                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9428                            + " with no external reference for token: "
9429                            + token + ".");
9430                }
9431            } else {
9432                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9433                        + " with no external references.");
9434            }
9435        }
9436    }
9437
9438    public final void publishContentProviders(IApplicationThread caller,
9439            List<ContentProviderHolder> providers) {
9440        if (providers == null) {
9441            return;
9442        }
9443
9444        enforceNotIsolatedCaller("publishContentProviders");
9445        synchronized (this) {
9446            final ProcessRecord r = getRecordForAppLocked(caller);
9447            if (DEBUG_MU)
9448                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9449            if (r == null) {
9450                throw new SecurityException(
9451                        "Unable to find app for caller " + caller
9452                      + " (pid=" + Binder.getCallingPid()
9453                      + ") when publishing content providers");
9454            }
9455
9456            final long origId = Binder.clearCallingIdentity();
9457
9458            final int N = providers.size();
9459            for (int i=0; i<N; i++) {
9460                ContentProviderHolder src = providers.get(i);
9461                if (src == null || src.info == null || src.provider == null) {
9462                    continue;
9463                }
9464                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9465                if (DEBUG_MU)
9466                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9467                if (dst != null) {
9468                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9469                    mProviderMap.putProviderByClass(comp, dst);
9470                    String names[] = dst.info.authority.split(";");
9471                    for (int j = 0; j < names.length; j++) {
9472                        mProviderMap.putProviderByName(names[j], dst);
9473                    }
9474
9475                    int NL = mLaunchingProviders.size();
9476                    int j;
9477                    for (j=0; j<NL; j++) {
9478                        if (mLaunchingProviders.get(j) == dst) {
9479                            mLaunchingProviders.remove(j);
9480                            j--;
9481                            NL--;
9482                        }
9483                    }
9484                    synchronized (dst) {
9485                        dst.provider = src.provider;
9486                        dst.proc = r;
9487                        dst.notifyAll();
9488                    }
9489                    updateOomAdjLocked(r);
9490                }
9491            }
9492
9493            Binder.restoreCallingIdentity(origId);
9494        }
9495    }
9496
9497    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9498        ContentProviderConnection conn;
9499        try {
9500            conn = (ContentProviderConnection)connection;
9501        } catch (ClassCastException e) {
9502            String msg ="refContentProvider: " + connection
9503                    + " not a ContentProviderConnection";
9504            Slog.w(TAG, msg);
9505            throw new IllegalArgumentException(msg);
9506        }
9507        if (conn == null) {
9508            throw new NullPointerException("connection is null");
9509        }
9510
9511        synchronized (this) {
9512            if (stable > 0) {
9513                conn.numStableIncs += stable;
9514            }
9515            stable = conn.stableCount + stable;
9516            if (stable < 0) {
9517                throw new IllegalStateException("stableCount < 0: " + stable);
9518            }
9519
9520            if (unstable > 0) {
9521                conn.numUnstableIncs += unstable;
9522            }
9523            unstable = conn.unstableCount + unstable;
9524            if (unstable < 0) {
9525                throw new IllegalStateException("unstableCount < 0: " + unstable);
9526            }
9527
9528            if ((stable+unstable) <= 0) {
9529                throw new IllegalStateException("ref counts can't go to zero here: stable="
9530                        + stable + " unstable=" + unstable);
9531            }
9532            conn.stableCount = stable;
9533            conn.unstableCount = unstable;
9534            return !conn.dead;
9535        }
9536    }
9537
9538    public void unstableProviderDied(IBinder connection) {
9539        ContentProviderConnection conn;
9540        try {
9541            conn = (ContentProviderConnection)connection;
9542        } catch (ClassCastException e) {
9543            String msg ="refContentProvider: " + connection
9544                    + " not a ContentProviderConnection";
9545            Slog.w(TAG, msg);
9546            throw new IllegalArgumentException(msg);
9547        }
9548        if (conn == null) {
9549            throw new NullPointerException("connection is null");
9550        }
9551
9552        // Safely retrieve the content provider associated with the connection.
9553        IContentProvider provider;
9554        synchronized (this) {
9555            provider = conn.provider.provider;
9556        }
9557
9558        if (provider == null) {
9559            // Um, yeah, we're way ahead of you.
9560            return;
9561        }
9562
9563        // Make sure the caller is being honest with us.
9564        if (provider.asBinder().pingBinder()) {
9565            // Er, no, still looks good to us.
9566            synchronized (this) {
9567                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9568                        + " says " + conn + " died, but we don't agree");
9569                return;
9570            }
9571        }
9572
9573        // Well look at that!  It's dead!
9574        synchronized (this) {
9575            if (conn.provider.provider != provider) {
9576                // But something changed...  good enough.
9577                return;
9578            }
9579
9580            ProcessRecord proc = conn.provider.proc;
9581            if (proc == null || proc.thread == null) {
9582                // Seems like the process is already cleaned up.
9583                return;
9584            }
9585
9586            // As far as we're concerned, this is just like receiving a
9587            // death notification...  just a bit prematurely.
9588            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9589                    + ") early provider death");
9590            final long ident = Binder.clearCallingIdentity();
9591            try {
9592                appDiedLocked(proc);
9593            } finally {
9594                Binder.restoreCallingIdentity(ident);
9595            }
9596        }
9597    }
9598
9599    @Override
9600    public void appNotRespondingViaProvider(IBinder connection) {
9601        enforceCallingPermission(
9602                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9603
9604        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9605        if (conn == null) {
9606            Slog.w(TAG, "ContentProviderConnection is null");
9607            return;
9608        }
9609
9610        final ProcessRecord host = conn.provider.proc;
9611        if (host == null) {
9612            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9613            return;
9614        }
9615
9616        final long token = Binder.clearCallingIdentity();
9617        try {
9618            appNotResponding(host, null, null, false, "ContentProvider not responding");
9619        } finally {
9620            Binder.restoreCallingIdentity(token);
9621        }
9622    }
9623
9624    public final void installSystemProviders() {
9625        List<ProviderInfo> providers;
9626        synchronized (this) {
9627            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9628            providers = generateApplicationProvidersLocked(app);
9629            if (providers != null) {
9630                for (int i=providers.size()-1; i>=0; i--) {
9631                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9632                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9633                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9634                                + ": not system .apk");
9635                        providers.remove(i);
9636                    }
9637                }
9638            }
9639        }
9640        if (providers != null) {
9641            mSystemThread.installSystemProviders(providers);
9642        }
9643
9644        mCoreSettingsObserver = new CoreSettingsObserver(this);
9645
9646        //mUsageStatsService.monitorPackages();
9647    }
9648
9649    /**
9650     * Allows apps to retrieve the MIME type of a URI.
9651     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9652     * users, then it does not need permission to access the ContentProvider.
9653     * Either, it needs cross-user uri grants.
9654     *
9655     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9656     *
9657     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9658     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9659     */
9660    public String getProviderMimeType(Uri uri, int userId) {
9661        enforceNotIsolatedCaller("getProviderMimeType");
9662        final String name = uri.getAuthority();
9663        int callingUid = Binder.getCallingUid();
9664        int callingPid = Binder.getCallingPid();
9665        long ident = 0;
9666        boolean clearedIdentity = false;
9667        userId = unsafeConvertIncomingUser(userId);
9668        if (canClearIdentity(callingPid, callingUid, userId)) {
9669            clearedIdentity = true;
9670            ident = Binder.clearCallingIdentity();
9671        }
9672        ContentProviderHolder holder = null;
9673        try {
9674            holder = getContentProviderExternalUnchecked(name, null, userId);
9675            if (holder != null) {
9676                return holder.provider.getType(uri);
9677            }
9678        } catch (RemoteException e) {
9679            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9680            return null;
9681        } finally {
9682            // We need to clear the identity to call removeContentProviderExternalUnchecked
9683            if (!clearedIdentity) {
9684                ident = Binder.clearCallingIdentity();
9685            }
9686            try {
9687                if (holder != null) {
9688                    removeContentProviderExternalUnchecked(name, null, userId);
9689                }
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694
9695        return null;
9696    }
9697
9698    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9699        if (UserHandle.getUserId(callingUid) == userId) {
9700            return true;
9701        }
9702        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9703                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9704                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9705                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9706                return true;
9707        }
9708        return false;
9709    }
9710
9711    // =========================================================
9712    // GLOBAL MANAGEMENT
9713    // =========================================================
9714
9715    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9716            boolean isolated, int isolatedUid) {
9717        String proc = customProcess != null ? customProcess : info.processName;
9718        BatteryStatsImpl.Uid.Proc ps = null;
9719        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9720        int uid = info.uid;
9721        if (isolated) {
9722            if (isolatedUid == 0) {
9723                int userId = UserHandle.getUserId(uid);
9724                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9725                while (true) {
9726                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9727                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9728                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9729                    }
9730                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9731                    mNextIsolatedProcessUid++;
9732                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9733                        // No process for this uid, use it.
9734                        break;
9735                    }
9736                    stepsLeft--;
9737                    if (stepsLeft <= 0) {
9738                        return null;
9739                    }
9740                }
9741            } else {
9742                // Special case for startIsolatedProcess (internal only), where
9743                // the uid of the isolated process is specified by the caller.
9744                uid = isolatedUid;
9745            }
9746        }
9747        return new ProcessRecord(stats, info, proc, uid);
9748    }
9749
9750    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9751            String abiOverride) {
9752        ProcessRecord app;
9753        if (!isolated) {
9754            app = getProcessRecordLocked(info.processName, info.uid, true);
9755        } else {
9756            app = null;
9757        }
9758
9759        if (app == null) {
9760            app = newProcessRecordLocked(info, null, isolated, 0);
9761            mProcessNames.put(info.processName, app.uid, app);
9762            if (isolated) {
9763                mIsolatedProcesses.put(app.uid, app);
9764            }
9765            updateLruProcessLocked(app, false, null);
9766            updateOomAdjLocked();
9767        }
9768
9769        // This package really, really can not be stopped.
9770        try {
9771            AppGlobals.getPackageManager().setPackageStoppedState(
9772                    info.packageName, false, UserHandle.getUserId(app.uid));
9773        } catch (RemoteException e) {
9774        } catch (IllegalArgumentException e) {
9775            Slog.w(TAG, "Failed trying to unstop package "
9776                    + info.packageName + ": " + e);
9777        }
9778
9779        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9780                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9781            app.persistent = true;
9782            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9783        }
9784        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9785            mPersistentStartingProcesses.add(app);
9786            startProcessLocked(app, "added application", app.processName, abiOverride,
9787                    null /* entryPoint */, null /* entryPointArgs */);
9788        }
9789
9790        return app;
9791    }
9792
9793    public void unhandledBack() {
9794        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9795                "unhandledBack()");
9796
9797        synchronized(this) {
9798            final long origId = Binder.clearCallingIdentity();
9799            try {
9800                getFocusedStack().unhandledBackLocked();
9801            } finally {
9802                Binder.restoreCallingIdentity(origId);
9803            }
9804        }
9805    }
9806
9807    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9808        enforceNotIsolatedCaller("openContentUri");
9809        final int userId = UserHandle.getCallingUserId();
9810        String name = uri.getAuthority();
9811        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9812        ParcelFileDescriptor pfd = null;
9813        if (cph != null) {
9814            // We record the binder invoker's uid in thread-local storage before
9815            // going to the content provider to open the file.  Later, in the code
9816            // that handles all permissions checks, we look for this uid and use
9817            // that rather than the Activity Manager's own uid.  The effect is that
9818            // we do the check against the caller's permissions even though it looks
9819            // to the content provider like the Activity Manager itself is making
9820            // the request.
9821            sCallerIdentity.set(new Identity(
9822                    Binder.getCallingPid(), Binder.getCallingUid()));
9823            try {
9824                pfd = cph.provider.openFile(null, uri, "r", null);
9825            } catch (FileNotFoundException e) {
9826                // do nothing; pfd will be returned null
9827            } finally {
9828                // Ensure that whatever happens, we clean up the identity state
9829                sCallerIdentity.remove();
9830            }
9831
9832            // We've got the fd now, so we're done with the provider.
9833            removeContentProviderExternalUnchecked(name, null, userId);
9834        } else {
9835            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9836        }
9837        return pfd;
9838    }
9839
9840    // Actually is sleeping or shutting down or whatever else in the future
9841    // is an inactive state.
9842    public boolean isSleepingOrShuttingDown() {
9843        return mSleeping || mShuttingDown;
9844    }
9845
9846    public boolean isSleeping() {
9847        return mSleeping;
9848    }
9849
9850    void goingToSleep() {
9851        synchronized(this) {
9852            mWentToSleep = true;
9853            updateEventDispatchingLocked();
9854            goToSleepIfNeededLocked();
9855        }
9856    }
9857
9858    void finishRunningVoiceLocked() {
9859        if (mRunningVoice) {
9860            mRunningVoice = false;
9861            goToSleepIfNeededLocked();
9862        }
9863    }
9864
9865    void goToSleepIfNeededLocked() {
9866        if (mWentToSleep && !mRunningVoice) {
9867            if (!mSleeping) {
9868                mSleeping = true;
9869                mStackSupervisor.goingToSleepLocked();
9870
9871                // Initialize the wake times of all processes.
9872                checkExcessivePowerUsageLocked(false);
9873                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9874                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9875                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9876            }
9877        }
9878    }
9879
9880    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9881        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9882            // Never persist the home stack.
9883            return;
9884        }
9885        mTaskPersister.wakeup(task, flush);
9886    }
9887
9888    @Override
9889    public boolean shutdown(int timeout) {
9890        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9891                != PackageManager.PERMISSION_GRANTED) {
9892            throw new SecurityException("Requires permission "
9893                    + android.Manifest.permission.SHUTDOWN);
9894        }
9895
9896        boolean timedout = false;
9897
9898        synchronized(this) {
9899            mShuttingDown = true;
9900            updateEventDispatchingLocked();
9901            timedout = mStackSupervisor.shutdownLocked(timeout);
9902        }
9903
9904        mAppOpsService.shutdown();
9905        if (mUsageStatsService != null) {
9906            mUsageStatsService.prepareShutdown();
9907        }
9908        mBatteryStatsService.shutdown();
9909        synchronized (this) {
9910            mProcessStats.shutdownLocked();
9911        }
9912        notifyTaskPersisterLocked(null, true);
9913
9914        return timedout;
9915    }
9916
9917    public final void activitySlept(IBinder token) {
9918        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9919
9920        final long origId = Binder.clearCallingIdentity();
9921
9922        synchronized (this) {
9923            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9924            if (r != null) {
9925                mStackSupervisor.activitySleptLocked(r);
9926            }
9927        }
9928
9929        Binder.restoreCallingIdentity(origId);
9930    }
9931
9932    void logLockScreen(String msg) {
9933        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9934                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9935                mWentToSleep + " mSleeping=" + mSleeping);
9936    }
9937
9938    private void comeOutOfSleepIfNeededLocked() {
9939        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9940            if (mSleeping) {
9941                mSleeping = false;
9942                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9943            }
9944        }
9945    }
9946
9947    void wakingUp() {
9948        synchronized(this) {
9949            mWentToSleep = false;
9950            updateEventDispatchingLocked();
9951            comeOutOfSleepIfNeededLocked();
9952        }
9953    }
9954
9955    void startRunningVoiceLocked() {
9956        if (!mRunningVoice) {
9957            mRunningVoice = true;
9958            comeOutOfSleepIfNeededLocked();
9959        }
9960    }
9961
9962    private void updateEventDispatchingLocked() {
9963        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9964    }
9965
9966    public void setLockScreenShown(boolean shown) {
9967        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9968                != PackageManager.PERMISSION_GRANTED) {
9969            throw new SecurityException("Requires permission "
9970                    + android.Manifest.permission.DEVICE_POWER);
9971        }
9972
9973        synchronized(this) {
9974            long ident = Binder.clearCallingIdentity();
9975            try {
9976                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9977                mLockScreenShown = shown;
9978                comeOutOfSleepIfNeededLocked();
9979            } finally {
9980                Binder.restoreCallingIdentity(ident);
9981            }
9982        }
9983    }
9984
9985    @Override
9986    public void stopAppSwitches() {
9987        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9988                != PackageManager.PERMISSION_GRANTED) {
9989            throw new SecurityException("Requires permission "
9990                    + android.Manifest.permission.STOP_APP_SWITCHES);
9991        }
9992
9993        synchronized(this) {
9994            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9995                    + APP_SWITCH_DELAY_TIME;
9996            mDidAppSwitch = false;
9997            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9998            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9999            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10000        }
10001    }
10002
10003    public void resumeAppSwitches() {
10004        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10005                != PackageManager.PERMISSION_GRANTED) {
10006            throw new SecurityException("Requires permission "
10007                    + android.Manifest.permission.STOP_APP_SWITCHES);
10008        }
10009
10010        synchronized(this) {
10011            // Note that we don't execute any pending app switches... we will
10012            // let those wait until either the timeout, or the next start
10013            // activity request.
10014            mAppSwitchesAllowedTime = 0;
10015        }
10016    }
10017
10018    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10019            String name) {
10020        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10021            return true;
10022        }
10023
10024        final int perm = checkComponentPermission(
10025                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10026                callingUid, -1, true);
10027        if (perm == PackageManager.PERMISSION_GRANTED) {
10028            return true;
10029        }
10030
10031        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10032        return false;
10033    }
10034
10035    public void setDebugApp(String packageName, boolean waitForDebugger,
10036            boolean persistent) {
10037        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10038                "setDebugApp()");
10039
10040        long ident = Binder.clearCallingIdentity();
10041        try {
10042            // Note that this is not really thread safe if there are multiple
10043            // callers into it at the same time, but that's not a situation we
10044            // care about.
10045            if (persistent) {
10046                final ContentResolver resolver = mContext.getContentResolver();
10047                Settings.Global.putString(
10048                    resolver, Settings.Global.DEBUG_APP,
10049                    packageName);
10050                Settings.Global.putInt(
10051                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10052                    waitForDebugger ? 1 : 0);
10053            }
10054
10055            synchronized (this) {
10056                if (!persistent) {
10057                    mOrigDebugApp = mDebugApp;
10058                    mOrigWaitForDebugger = mWaitForDebugger;
10059                }
10060                mDebugApp = packageName;
10061                mWaitForDebugger = waitForDebugger;
10062                mDebugTransient = !persistent;
10063                if (packageName != null) {
10064                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10065                            false, UserHandle.USER_ALL, "set debug app");
10066                }
10067            }
10068        } finally {
10069            Binder.restoreCallingIdentity(ident);
10070        }
10071    }
10072
10073    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10074        synchronized (this) {
10075            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10076            if (!isDebuggable) {
10077                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10078                    throw new SecurityException("Process not debuggable: " + app.packageName);
10079                }
10080            }
10081
10082            mOpenGlTraceApp = processName;
10083        }
10084    }
10085
10086    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10087        synchronized (this) {
10088            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10089            if (!isDebuggable) {
10090                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10091                    throw new SecurityException("Process not debuggable: " + app.packageName);
10092                }
10093            }
10094            mProfileApp = processName;
10095            mProfileFile = profilerInfo.profileFile;
10096            if (mProfileFd != null) {
10097                try {
10098                    mProfileFd.close();
10099                } catch (IOException e) {
10100                }
10101                mProfileFd = null;
10102            }
10103            mProfileFd = profilerInfo.profileFd;
10104            mSamplingInterval = profilerInfo.samplingInterval;
10105            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10106            mProfileType = 0;
10107        }
10108    }
10109
10110    @Override
10111    public void setAlwaysFinish(boolean enabled) {
10112        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10113                "setAlwaysFinish()");
10114
10115        Settings.Global.putInt(
10116                mContext.getContentResolver(),
10117                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10118
10119        synchronized (this) {
10120            mAlwaysFinishActivities = enabled;
10121        }
10122    }
10123
10124    @Override
10125    public void setActivityController(IActivityController controller) {
10126        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10127                "setActivityController()");
10128        synchronized (this) {
10129            mController = controller;
10130            Watchdog.getInstance().setActivityController(controller);
10131        }
10132    }
10133
10134    @Override
10135    public void setUserIsMonkey(boolean userIsMonkey) {
10136        synchronized (this) {
10137            synchronized (mPidsSelfLocked) {
10138                final int callingPid = Binder.getCallingPid();
10139                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10140                if (precessRecord == null) {
10141                    throw new SecurityException("Unknown process: " + callingPid);
10142                }
10143                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10144                    throw new SecurityException("Only an instrumentation process "
10145                            + "with a UiAutomation can call setUserIsMonkey");
10146                }
10147            }
10148            mUserIsMonkey = userIsMonkey;
10149        }
10150    }
10151
10152    @Override
10153    public boolean isUserAMonkey() {
10154        synchronized (this) {
10155            // If there is a controller also implies the user is a monkey.
10156            return (mUserIsMonkey || mController != null);
10157        }
10158    }
10159
10160    public void requestBugReport() {
10161        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10162        SystemProperties.set("ctl.start", "bugreport");
10163    }
10164
10165    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10166        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10167    }
10168
10169    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10170        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10171            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10172        }
10173        return KEY_DISPATCHING_TIMEOUT;
10174    }
10175
10176    @Override
10177    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10178        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10179                != PackageManager.PERMISSION_GRANTED) {
10180            throw new SecurityException("Requires permission "
10181                    + android.Manifest.permission.FILTER_EVENTS);
10182        }
10183        ProcessRecord proc;
10184        long timeout;
10185        synchronized (this) {
10186            synchronized (mPidsSelfLocked) {
10187                proc = mPidsSelfLocked.get(pid);
10188            }
10189            timeout = getInputDispatchingTimeoutLocked(proc);
10190        }
10191
10192        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10193            return -1;
10194        }
10195
10196        return timeout;
10197    }
10198
10199    /**
10200     * Handle input dispatching timeouts.
10201     * Returns whether input dispatching should be aborted or not.
10202     */
10203    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10204            final ActivityRecord activity, final ActivityRecord parent,
10205            final boolean aboveSystem, String reason) {
10206        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10207                != PackageManager.PERMISSION_GRANTED) {
10208            throw new SecurityException("Requires permission "
10209                    + android.Manifest.permission.FILTER_EVENTS);
10210        }
10211
10212        final String annotation;
10213        if (reason == null) {
10214            annotation = "Input dispatching timed out";
10215        } else {
10216            annotation = "Input dispatching timed out (" + reason + ")";
10217        }
10218
10219        if (proc != null) {
10220            synchronized (this) {
10221                if (proc.debugging) {
10222                    return false;
10223                }
10224
10225                if (mDidDexOpt) {
10226                    // Give more time since we were dexopting.
10227                    mDidDexOpt = false;
10228                    return false;
10229                }
10230
10231                if (proc.instrumentationClass != null) {
10232                    Bundle info = new Bundle();
10233                    info.putString("shortMsg", "keyDispatchingTimedOut");
10234                    info.putString("longMsg", annotation);
10235                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10236                    return true;
10237                }
10238            }
10239            mHandler.post(new Runnable() {
10240                @Override
10241                public void run() {
10242                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10243                }
10244            });
10245        }
10246
10247        return true;
10248    }
10249
10250    public Bundle getAssistContextExtras(int requestType) {
10251        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10252                "getAssistContextExtras()");
10253        PendingAssistExtras pae;
10254        Bundle extras = new Bundle();
10255        synchronized (this) {
10256            ActivityRecord activity = getFocusedStack().mResumedActivity;
10257            if (activity == null) {
10258                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10259                return null;
10260            }
10261            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10262            if (activity.app == null || activity.app.thread == null) {
10263                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10264                return extras;
10265            }
10266            if (activity.app.pid == Binder.getCallingPid()) {
10267                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10268                return extras;
10269            }
10270            pae = new PendingAssistExtras(activity);
10271            try {
10272                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10273                        requestType);
10274                mPendingAssistExtras.add(pae);
10275                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10276            } catch (RemoteException e) {
10277                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10278                return extras;
10279            }
10280        }
10281        synchronized (pae) {
10282            while (!pae.haveResult) {
10283                try {
10284                    pae.wait();
10285                } catch (InterruptedException e) {
10286                }
10287            }
10288            if (pae.result != null) {
10289                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10290            }
10291        }
10292        synchronized (this) {
10293            mPendingAssistExtras.remove(pae);
10294            mHandler.removeCallbacks(pae);
10295        }
10296        return extras;
10297    }
10298
10299    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10300        PendingAssistExtras pae = (PendingAssistExtras)token;
10301        synchronized (pae) {
10302            pae.result = extras;
10303            pae.haveResult = true;
10304            pae.notifyAll();
10305        }
10306    }
10307
10308    public void registerProcessObserver(IProcessObserver observer) {
10309        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10310                "registerProcessObserver()");
10311        synchronized (this) {
10312            mProcessObservers.register(observer);
10313        }
10314    }
10315
10316    @Override
10317    public void unregisterProcessObserver(IProcessObserver observer) {
10318        synchronized (this) {
10319            mProcessObservers.unregister(observer);
10320        }
10321    }
10322
10323    @Override
10324    public boolean convertFromTranslucent(IBinder token) {
10325        final long origId = Binder.clearCallingIdentity();
10326        try {
10327            synchronized (this) {
10328                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10329                if (r == null) {
10330                    return false;
10331                }
10332                final boolean translucentChanged = r.changeWindowTranslucency(true);
10333                if (translucentChanged) {
10334                    r.task.stack.releaseBackgroundResources();
10335                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10336                }
10337                mWindowManager.setAppFullscreen(token, true);
10338                return translucentChanged;
10339            }
10340        } finally {
10341            Binder.restoreCallingIdentity(origId);
10342        }
10343    }
10344
10345    @Override
10346    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10347        final long origId = Binder.clearCallingIdentity();
10348        try {
10349            synchronized (this) {
10350                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10351                if (r == null) {
10352                    return false;
10353                }
10354                int index = r.task.mActivities.lastIndexOf(r);
10355                if (index > 0) {
10356                    ActivityRecord under = r.task.mActivities.get(index - 1);
10357                    under.returningOptions = options;
10358                }
10359                final boolean translucentChanged = r.changeWindowTranslucency(false);
10360                if (translucentChanged) {
10361                    r.task.stack.convertToTranslucent(r);
10362                }
10363                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10364                mWindowManager.setAppFullscreen(token, false);
10365                return translucentChanged;
10366            }
10367        } finally {
10368            Binder.restoreCallingIdentity(origId);
10369        }
10370    }
10371
10372    @Override
10373    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10374        final long origId = Binder.clearCallingIdentity();
10375        try {
10376            synchronized (this) {
10377                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10378                if (r != null) {
10379                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10380                }
10381            }
10382            return false;
10383        } finally {
10384            Binder.restoreCallingIdentity(origId);
10385        }
10386    }
10387
10388    @Override
10389    public boolean isBackgroundVisibleBehind(IBinder token) {
10390        final long origId = Binder.clearCallingIdentity();
10391        try {
10392            synchronized (this) {
10393                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10394                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10395                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10396                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10397                return visible;
10398            }
10399        } finally {
10400            Binder.restoreCallingIdentity(origId);
10401        }
10402    }
10403
10404    @Override
10405    public ActivityOptions getActivityOptions(IBinder token) {
10406        final long origId = Binder.clearCallingIdentity();
10407        try {
10408            synchronized (this) {
10409                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10410                if (r != null) {
10411                    final ActivityOptions activityOptions = r.pendingOptions;
10412                    r.pendingOptions = null;
10413                    return activityOptions;
10414                }
10415                return null;
10416            }
10417        } finally {
10418            Binder.restoreCallingIdentity(origId);
10419        }
10420    }
10421
10422    @Override
10423    public void setImmersive(IBinder token, boolean immersive) {
10424        synchronized(this) {
10425            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10426            if (r == null) {
10427                throw new IllegalArgumentException();
10428            }
10429            r.immersive = immersive;
10430
10431            // update associated state if we're frontmost
10432            if (r == mFocusedActivity) {
10433                if (DEBUG_IMMERSIVE) {
10434                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10435                }
10436                applyUpdateLockStateLocked(r);
10437            }
10438        }
10439    }
10440
10441    @Override
10442    public boolean isImmersive(IBinder token) {
10443        synchronized (this) {
10444            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10445            if (r == null) {
10446                throw new IllegalArgumentException();
10447            }
10448            return r.immersive;
10449        }
10450    }
10451
10452    public boolean isTopActivityImmersive() {
10453        enforceNotIsolatedCaller("startActivity");
10454        synchronized (this) {
10455            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10456            return (r != null) ? r.immersive : false;
10457        }
10458    }
10459
10460    @Override
10461    public boolean isTopOfTask(IBinder token) {
10462        synchronized (this) {
10463            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10464            if (r == null) {
10465                throw new IllegalArgumentException();
10466            }
10467            return r.task.getTopActivity() == r;
10468        }
10469    }
10470
10471    public final void enterSafeMode() {
10472        synchronized(this) {
10473            // It only makes sense to do this before the system is ready
10474            // and started launching other packages.
10475            if (!mSystemReady) {
10476                try {
10477                    AppGlobals.getPackageManager().enterSafeMode();
10478                } catch (RemoteException e) {
10479                }
10480            }
10481
10482            mSafeMode = true;
10483        }
10484    }
10485
10486    public final void showSafeModeOverlay() {
10487        View v = LayoutInflater.from(mContext).inflate(
10488                com.android.internal.R.layout.safe_mode, null);
10489        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10490        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10491        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10492        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10493        lp.gravity = Gravity.BOTTOM | Gravity.START;
10494        lp.format = v.getBackground().getOpacity();
10495        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10496                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10497        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10498        ((WindowManager)mContext.getSystemService(
10499                Context.WINDOW_SERVICE)).addView(v, lp);
10500    }
10501
10502    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10503        if (!(sender instanceof PendingIntentRecord)) {
10504            return;
10505        }
10506        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10507        synchronized (stats) {
10508            if (mBatteryStatsService.isOnBattery()) {
10509                mBatteryStatsService.enforceCallingPermission();
10510                PendingIntentRecord rec = (PendingIntentRecord)sender;
10511                int MY_UID = Binder.getCallingUid();
10512                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10513                BatteryStatsImpl.Uid.Pkg pkg =
10514                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10515                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10516                pkg.incWakeupsLocked();
10517            }
10518        }
10519    }
10520
10521    public boolean killPids(int[] pids, String pReason, boolean secure) {
10522        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10523            throw new SecurityException("killPids only available to the system");
10524        }
10525        String reason = (pReason == null) ? "Unknown" : pReason;
10526        // XXX Note: don't acquire main activity lock here, because the window
10527        // manager calls in with its locks held.
10528
10529        boolean killed = false;
10530        synchronized (mPidsSelfLocked) {
10531            int[] types = new int[pids.length];
10532            int worstType = 0;
10533            for (int i=0; i<pids.length; i++) {
10534                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10535                if (proc != null) {
10536                    int type = proc.setAdj;
10537                    types[i] = type;
10538                    if (type > worstType) {
10539                        worstType = type;
10540                    }
10541                }
10542            }
10543
10544            // If the worst oom_adj is somewhere in the cached proc LRU range,
10545            // then constrain it so we will kill all cached procs.
10546            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10547                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10548                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10549            }
10550
10551            // If this is not a secure call, don't let it kill processes that
10552            // are important.
10553            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10554                worstType = ProcessList.SERVICE_ADJ;
10555            }
10556
10557            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10558            for (int i=0; i<pids.length; i++) {
10559                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10560                if (proc == null) {
10561                    continue;
10562                }
10563                int adj = proc.setAdj;
10564                if (adj >= worstType && !proc.killedByAm) {
10565                    proc.kill(reason, true);
10566                    killed = true;
10567                }
10568            }
10569        }
10570        return killed;
10571    }
10572
10573    @Override
10574    public void killUid(int uid, String reason) {
10575        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10576            throw new SecurityException("killUid only available to the system");
10577        }
10578        synchronized (this) {
10579            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10580                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10581                    reason != null ? reason : "kill uid");
10582        }
10583    }
10584
10585    @Override
10586    public boolean killProcessesBelowForeground(String reason) {
10587        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10588            throw new SecurityException("killProcessesBelowForeground() only available to system");
10589        }
10590
10591        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10592    }
10593
10594    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10595        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10596            throw new SecurityException("killProcessesBelowAdj() only available to system");
10597        }
10598
10599        boolean killed = false;
10600        synchronized (mPidsSelfLocked) {
10601            final int size = mPidsSelfLocked.size();
10602            for (int i = 0; i < size; i++) {
10603                final int pid = mPidsSelfLocked.keyAt(i);
10604                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10605                if (proc == null) continue;
10606
10607                final int adj = proc.setAdj;
10608                if (adj > belowAdj && !proc.killedByAm) {
10609                    proc.kill(reason, true);
10610                    killed = true;
10611                }
10612            }
10613        }
10614        return killed;
10615    }
10616
10617    @Override
10618    public void hang(final IBinder who, boolean allowRestart) {
10619        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10620                != PackageManager.PERMISSION_GRANTED) {
10621            throw new SecurityException("Requires permission "
10622                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10623        }
10624
10625        final IBinder.DeathRecipient death = new DeathRecipient() {
10626            @Override
10627            public void binderDied() {
10628                synchronized (this) {
10629                    notifyAll();
10630                }
10631            }
10632        };
10633
10634        try {
10635            who.linkToDeath(death, 0);
10636        } catch (RemoteException e) {
10637            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10638            return;
10639        }
10640
10641        synchronized (this) {
10642            Watchdog.getInstance().setAllowRestart(allowRestart);
10643            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10644            synchronized (death) {
10645                while (who.isBinderAlive()) {
10646                    try {
10647                        death.wait();
10648                    } catch (InterruptedException e) {
10649                    }
10650                }
10651            }
10652            Watchdog.getInstance().setAllowRestart(true);
10653        }
10654    }
10655
10656    @Override
10657    public void restart() {
10658        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10659                != PackageManager.PERMISSION_GRANTED) {
10660            throw new SecurityException("Requires permission "
10661                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10662        }
10663
10664        Log.i(TAG, "Sending shutdown broadcast...");
10665
10666        BroadcastReceiver br = new BroadcastReceiver() {
10667            @Override public void onReceive(Context context, Intent intent) {
10668                // Now the broadcast is done, finish up the low-level shutdown.
10669                Log.i(TAG, "Shutting down activity manager...");
10670                shutdown(10000);
10671                Log.i(TAG, "Shutdown complete, restarting!");
10672                Process.killProcess(Process.myPid());
10673                System.exit(10);
10674            }
10675        };
10676
10677        // First send the high-level shut down broadcast.
10678        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10679        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10680        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10681        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10682        mContext.sendOrderedBroadcastAsUser(intent,
10683                UserHandle.ALL, null, br, mHandler, 0, null, null);
10684        */
10685        br.onReceive(mContext, intent);
10686    }
10687
10688    private long getLowRamTimeSinceIdle(long now) {
10689        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10690    }
10691
10692    @Override
10693    public void performIdleMaintenance() {
10694        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10695                != PackageManager.PERMISSION_GRANTED) {
10696            throw new SecurityException("Requires permission "
10697                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10698        }
10699
10700        synchronized (this) {
10701            final long now = SystemClock.uptimeMillis();
10702            final long timeSinceLastIdle = now - mLastIdleTime;
10703            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10704            mLastIdleTime = now;
10705            mLowRamTimeSinceLastIdle = 0;
10706            if (mLowRamStartTime != 0) {
10707                mLowRamStartTime = now;
10708            }
10709
10710            StringBuilder sb = new StringBuilder(128);
10711            sb.append("Idle maintenance over ");
10712            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10713            sb.append(" low RAM for ");
10714            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10715            Slog.i(TAG, sb.toString());
10716
10717            // If at least 1/3 of our time since the last idle period has been spent
10718            // with RAM low, then we want to kill processes.
10719            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10720
10721            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10722                ProcessRecord proc = mLruProcesses.get(i);
10723                if (proc.notCachedSinceIdle) {
10724                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10725                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10726                        if (doKilling && proc.initialIdlePss != 0
10727                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10728                            proc.kill("idle maint (pss " + proc.lastPss
10729                                    + " from " + proc.initialIdlePss + ")", true);
10730                        }
10731                    }
10732                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10733                    proc.notCachedSinceIdle = true;
10734                    proc.initialIdlePss = 0;
10735                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10736                            isSleeping(), now);
10737                }
10738            }
10739
10740            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10741            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10742        }
10743    }
10744
10745    private void retrieveSettings() {
10746        final ContentResolver resolver = mContext.getContentResolver();
10747        String debugApp = Settings.Global.getString(
10748            resolver, Settings.Global.DEBUG_APP);
10749        boolean waitForDebugger = Settings.Global.getInt(
10750            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10751        boolean alwaysFinishActivities = Settings.Global.getInt(
10752            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10753        boolean forceRtl = Settings.Global.getInt(
10754                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10755        // Transfer any global setting for forcing RTL layout, into a System Property
10756        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10757
10758        Configuration configuration = new Configuration();
10759        Settings.System.getConfiguration(resolver, configuration);
10760        if (forceRtl) {
10761            // This will take care of setting the correct layout direction flags
10762            configuration.setLayoutDirection(configuration.locale);
10763        }
10764
10765        synchronized (this) {
10766            mDebugApp = mOrigDebugApp = debugApp;
10767            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10768            mAlwaysFinishActivities = alwaysFinishActivities;
10769            // This happens before any activities are started, so we can
10770            // change mConfiguration in-place.
10771            updateConfigurationLocked(configuration, null, false, true);
10772            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10773        }
10774    }
10775
10776    /** Loads resources after the current configuration has been set. */
10777    private void loadResourcesOnSystemReady() {
10778        final Resources res = mContext.getResources();
10779        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10780        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10781        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10782    }
10783
10784    public boolean testIsSystemReady() {
10785        // no need to synchronize(this) just to read & return the value
10786        return mSystemReady;
10787    }
10788
10789    private static File getCalledPreBootReceiversFile() {
10790        File dataDir = Environment.getDataDirectory();
10791        File systemDir = new File(dataDir, "system");
10792        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10793        return fname;
10794    }
10795
10796    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10797        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10798        File file = getCalledPreBootReceiversFile();
10799        FileInputStream fis = null;
10800        try {
10801            fis = new FileInputStream(file);
10802            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10803            int fvers = dis.readInt();
10804            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10805                String vers = dis.readUTF();
10806                String codename = dis.readUTF();
10807                String build = dis.readUTF();
10808                if (android.os.Build.VERSION.RELEASE.equals(vers)
10809                        && android.os.Build.VERSION.CODENAME.equals(codename)
10810                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10811                    int num = dis.readInt();
10812                    while (num > 0) {
10813                        num--;
10814                        String pkg = dis.readUTF();
10815                        String cls = dis.readUTF();
10816                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10817                    }
10818                }
10819            }
10820        } catch (FileNotFoundException e) {
10821        } catch (IOException e) {
10822            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10823        } finally {
10824            if (fis != null) {
10825                try {
10826                    fis.close();
10827                } catch (IOException e) {
10828                }
10829            }
10830        }
10831        return lastDoneReceivers;
10832    }
10833
10834    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10835        File file = getCalledPreBootReceiversFile();
10836        FileOutputStream fos = null;
10837        DataOutputStream dos = null;
10838        try {
10839            fos = new FileOutputStream(file);
10840            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10841            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10842            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10843            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10844            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10845            dos.writeInt(list.size());
10846            for (int i=0; i<list.size(); i++) {
10847                dos.writeUTF(list.get(i).getPackageName());
10848                dos.writeUTF(list.get(i).getClassName());
10849            }
10850        } catch (IOException e) {
10851            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10852            file.delete();
10853        } finally {
10854            FileUtils.sync(fos);
10855            if (dos != null) {
10856                try {
10857                    dos.close();
10858                } catch (IOException e) {
10859                    // TODO Auto-generated catch block
10860                    e.printStackTrace();
10861                }
10862            }
10863        }
10864    }
10865
10866    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10867            ArrayList<ComponentName> doneReceivers, int userId) {
10868        boolean waitingUpdate = false;
10869        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10870        List<ResolveInfo> ris = null;
10871        try {
10872            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10873                    intent, null, 0, userId);
10874        } catch (RemoteException e) {
10875        }
10876        if (ris != null) {
10877            for (int i=ris.size()-1; i>=0; i--) {
10878                if ((ris.get(i).activityInfo.applicationInfo.flags
10879                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10880                    ris.remove(i);
10881                }
10882            }
10883            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10884
10885            // For User 0, load the version number. When delivering to a new user, deliver
10886            // to all receivers.
10887            if (userId == UserHandle.USER_OWNER) {
10888                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10889                for (int i=0; i<ris.size(); i++) {
10890                    ActivityInfo ai = ris.get(i).activityInfo;
10891                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10892                    if (lastDoneReceivers.contains(comp)) {
10893                        // We already did the pre boot receiver for this app with the current
10894                        // platform version, so don't do it again...
10895                        ris.remove(i);
10896                        i--;
10897                        // ...however, do keep it as one that has been done, so we don't
10898                        // forget about it when rewriting the file of last done receivers.
10899                        doneReceivers.add(comp);
10900                    }
10901                }
10902            }
10903
10904            // If primary user, send broadcast to all available users, else just to userId
10905            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10906                    : new int[] { userId };
10907            for (int i = 0; i < ris.size(); i++) {
10908                ActivityInfo ai = ris.get(i).activityInfo;
10909                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10910                doneReceivers.add(comp);
10911                intent.setComponent(comp);
10912                for (int j=0; j<users.length; j++) {
10913                    IIntentReceiver finisher = null;
10914                    // On last receiver and user, set up a completion callback
10915                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10916                        finisher = new IIntentReceiver.Stub() {
10917                            public void performReceive(Intent intent, int resultCode,
10918                                    String data, Bundle extras, boolean ordered,
10919                                    boolean sticky, int sendingUser) {
10920                                // The raw IIntentReceiver interface is called
10921                                // with the AM lock held, so redispatch to
10922                                // execute our code without the lock.
10923                                mHandler.post(onFinishCallback);
10924                            }
10925                        };
10926                    }
10927                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10928                            + " for user " + users[j]);
10929                    broadcastIntentLocked(null, null, intent, null, finisher,
10930                            0, null, null, null, AppOpsManager.OP_NONE,
10931                            true, false, MY_PID, Process.SYSTEM_UID,
10932                            users[j]);
10933                    if (finisher != null) {
10934                        waitingUpdate = true;
10935                    }
10936                }
10937            }
10938        }
10939
10940        return waitingUpdate;
10941    }
10942
10943    public void systemReady(final Runnable goingCallback) {
10944        synchronized(this) {
10945            if (mSystemReady) {
10946                // If we're done calling all the receivers, run the next "boot phase" passed in
10947                // by the SystemServer
10948                if (goingCallback != null) {
10949                    goingCallback.run();
10950                }
10951                return;
10952            }
10953
10954            // Make sure we have the current profile info, since it is needed for
10955            // security checks.
10956            updateCurrentProfileIdsLocked();
10957
10958            if (mRecentTasks == null) {
10959                mRecentTasks = mTaskPersister.restoreTasksLocked();
10960                if (!mRecentTasks.isEmpty()) {
10961                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10962                }
10963                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10964                mTaskPersister.startPersisting();
10965            }
10966
10967            // Check to see if there are any update receivers to run.
10968            if (!mDidUpdate) {
10969                if (mWaitingUpdate) {
10970                    return;
10971                }
10972                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10973                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10974                    public void run() {
10975                        synchronized (ActivityManagerService.this) {
10976                            mDidUpdate = true;
10977                        }
10978                        writeLastDonePreBootReceivers(doneReceivers);
10979                        showBootMessage(mContext.getText(
10980                                R.string.android_upgrading_complete),
10981                                false);
10982                        systemReady(goingCallback);
10983                    }
10984                }, doneReceivers, UserHandle.USER_OWNER);
10985
10986                if (mWaitingUpdate) {
10987                    return;
10988                }
10989                mDidUpdate = true;
10990            }
10991
10992            mAppOpsService.systemReady();
10993            mSystemReady = true;
10994        }
10995
10996        ArrayList<ProcessRecord> procsToKill = null;
10997        synchronized(mPidsSelfLocked) {
10998            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10999                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11000                if (!isAllowedWhileBooting(proc.info)){
11001                    if (procsToKill == null) {
11002                        procsToKill = new ArrayList<ProcessRecord>();
11003                    }
11004                    procsToKill.add(proc);
11005                }
11006            }
11007        }
11008
11009        synchronized(this) {
11010            if (procsToKill != null) {
11011                for (int i=procsToKill.size()-1; i>=0; i--) {
11012                    ProcessRecord proc = procsToKill.get(i);
11013                    Slog.i(TAG, "Removing system update proc: " + proc);
11014                    removeProcessLocked(proc, true, false, "system update done");
11015                }
11016            }
11017
11018            // Now that we have cleaned up any update processes, we
11019            // are ready to start launching real processes and know that
11020            // we won't trample on them any more.
11021            mProcessesReady = true;
11022        }
11023
11024        Slog.i(TAG, "System now ready");
11025        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11026            SystemClock.uptimeMillis());
11027
11028        synchronized(this) {
11029            // Make sure we have no pre-ready processes sitting around.
11030
11031            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11032                ResolveInfo ri = mContext.getPackageManager()
11033                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11034                                STOCK_PM_FLAGS);
11035                CharSequence errorMsg = null;
11036                if (ri != null) {
11037                    ActivityInfo ai = ri.activityInfo;
11038                    ApplicationInfo app = ai.applicationInfo;
11039                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11040                        mTopAction = Intent.ACTION_FACTORY_TEST;
11041                        mTopData = null;
11042                        mTopComponent = new ComponentName(app.packageName,
11043                                ai.name);
11044                    } else {
11045                        errorMsg = mContext.getResources().getText(
11046                                com.android.internal.R.string.factorytest_not_system);
11047                    }
11048                } else {
11049                    errorMsg = mContext.getResources().getText(
11050                            com.android.internal.R.string.factorytest_no_action);
11051                }
11052                if (errorMsg != null) {
11053                    mTopAction = null;
11054                    mTopData = null;
11055                    mTopComponent = null;
11056                    Message msg = Message.obtain();
11057                    msg.what = SHOW_FACTORY_ERROR_MSG;
11058                    msg.getData().putCharSequence("msg", errorMsg);
11059                    mHandler.sendMessage(msg);
11060                }
11061            }
11062        }
11063
11064        retrieveSettings();
11065        loadResourcesOnSystemReady();
11066
11067        synchronized (this) {
11068            readGrantedUriPermissionsLocked();
11069        }
11070
11071        if (goingCallback != null) goingCallback.run();
11072
11073        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11074                Integer.toString(mCurrentUserId), mCurrentUserId);
11075        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11076                Integer.toString(mCurrentUserId), mCurrentUserId);
11077        mSystemServiceManager.startUser(mCurrentUserId);
11078
11079        synchronized (this) {
11080            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11081                try {
11082                    List apps = AppGlobals.getPackageManager().
11083                        getPersistentApplications(STOCK_PM_FLAGS);
11084                    if (apps != null) {
11085                        int N = apps.size();
11086                        int i;
11087                        for (i=0; i<N; i++) {
11088                            ApplicationInfo info
11089                                = (ApplicationInfo)apps.get(i);
11090                            if (info != null &&
11091                                    !info.packageName.equals("android")) {
11092                                addAppLocked(info, false, null /* ABI override */);
11093                            }
11094                        }
11095                    }
11096                } catch (RemoteException ex) {
11097                    // pm is in same process, this will never happen.
11098                }
11099            }
11100
11101            // Start up initial activity.
11102            mBooting = true;
11103
11104            try {
11105                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11106                    Message msg = Message.obtain();
11107                    msg.what = SHOW_UID_ERROR_MSG;
11108                    mHandler.sendMessage(msg);
11109                }
11110            } catch (RemoteException e) {
11111            }
11112
11113            long ident = Binder.clearCallingIdentity();
11114            try {
11115                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11116                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11117                        | Intent.FLAG_RECEIVER_FOREGROUND);
11118                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11119                broadcastIntentLocked(null, null, intent,
11120                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11121                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11122                intent = new Intent(Intent.ACTION_USER_STARTING);
11123                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11124                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11125                broadcastIntentLocked(null, null, intent,
11126                        null, new IIntentReceiver.Stub() {
11127                            @Override
11128                            public void performReceive(Intent intent, int resultCode, String data,
11129                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11130                                    throws RemoteException {
11131                            }
11132                        }, 0, null, null,
11133                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11134                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11135            } catch (Throwable t) {
11136                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11137            } finally {
11138                Binder.restoreCallingIdentity(ident);
11139            }
11140            mStackSupervisor.resumeTopActivitiesLocked();
11141            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11142        }
11143    }
11144
11145    private boolean makeAppCrashingLocked(ProcessRecord app,
11146            String shortMsg, String longMsg, String stackTrace) {
11147        app.crashing = true;
11148        app.crashingReport = generateProcessError(app,
11149                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11150        startAppProblemLocked(app);
11151        app.stopFreezingAllLocked();
11152        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11153    }
11154
11155    private void makeAppNotRespondingLocked(ProcessRecord app,
11156            String activity, String shortMsg, String longMsg) {
11157        app.notResponding = true;
11158        app.notRespondingReport = generateProcessError(app,
11159                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11160                activity, shortMsg, longMsg, null);
11161        startAppProblemLocked(app);
11162        app.stopFreezingAllLocked();
11163    }
11164
11165    /**
11166     * Generate a process error record, suitable for attachment to a ProcessRecord.
11167     *
11168     * @param app The ProcessRecord in which the error occurred.
11169     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11170     *                      ActivityManager.AppErrorStateInfo
11171     * @param activity The activity associated with the crash, if known.
11172     * @param shortMsg Short message describing the crash.
11173     * @param longMsg Long message describing the crash.
11174     * @param stackTrace Full crash stack trace, may be null.
11175     *
11176     * @return Returns a fully-formed AppErrorStateInfo record.
11177     */
11178    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11179            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11180        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11181
11182        report.condition = condition;
11183        report.processName = app.processName;
11184        report.pid = app.pid;
11185        report.uid = app.info.uid;
11186        report.tag = activity;
11187        report.shortMsg = shortMsg;
11188        report.longMsg = longMsg;
11189        report.stackTrace = stackTrace;
11190
11191        return report;
11192    }
11193
11194    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11195        synchronized (this) {
11196            app.crashing = false;
11197            app.crashingReport = null;
11198            app.notResponding = false;
11199            app.notRespondingReport = null;
11200            if (app.anrDialog == fromDialog) {
11201                app.anrDialog = null;
11202            }
11203            if (app.waitDialog == fromDialog) {
11204                app.waitDialog = null;
11205            }
11206            if (app.pid > 0 && app.pid != MY_PID) {
11207                handleAppCrashLocked(app, null, null, null);
11208                app.kill("user request after error", true);
11209            }
11210        }
11211    }
11212
11213    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11214            String stackTrace) {
11215        long now = SystemClock.uptimeMillis();
11216
11217        Long crashTime;
11218        if (!app.isolated) {
11219            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11220        } else {
11221            crashTime = null;
11222        }
11223        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11224            // This process loses!
11225            Slog.w(TAG, "Process " + app.info.processName
11226                    + " has crashed too many times: killing!");
11227            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11228                    app.userId, app.info.processName, app.uid);
11229            mStackSupervisor.handleAppCrashLocked(app);
11230            if (!app.persistent) {
11231                // We don't want to start this process again until the user
11232                // explicitly does so...  but for persistent process, we really
11233                // need to keep it running.  If a persistent process is actually
11234                // repeatedly crashing, then badness for everyone.
11235                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11236                        app.info.processName);
11237                if (!app.isolated) {
11238                    // XXX We don't have a way to mark isolated processes
11239                    // as bad, since they don't have a peristent identity.
11240                    mBadProcesses.put(app.info.processName, app.uid,
11241                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11242                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11243                }
11244                app.bad = true;
11245                app.removed = true;
11246                // Don't let services in this process be restarted and potentially
11247                // annoy the user repeatedly.  Unless it is persistent, since those
11248                // processes run critical code.
11249                removeProcessLocked(app, false, false, "crash");
11250                mStackSupervisor.resumeTopActivitiesLocked();
11251                return false;
11252            }
11253            mStackSupervisor.resumeTopActivitiesLocked();
11254        } else {
11255            mStackSupervisor.finishTopRunningActivityLocked(app);
11256        }
11257
11258        // Bump up the crash count of any services currently running in the proc.
11259        for (int i=app.services.size()-1; i>=0; i--) {
11260            // Any services running in the application need to be placed
11261            // back in the pending list.
11262            ServiceRecord sr = app.services.valueAt(i);
11263            sr.crashCount++;
11264        }
11265
11266        // If the crashing process is what we consider to be the "home process" and it has been
11267        // replaced by a third-party app, clear the package preferred activities from packages
11268        // with a home activity running in the process to prevent a repeatedly crashing app
11269        // from blocking the user to manually clear the list.
11270        final ArrayList<ActivityRecord> activities = app.activities;
11271        if (app == mHomeProcess && activities.size() > 0
11272                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11273            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11274                final ActivityRecord r = activities.get(activityNdx);
11275                if (r.isHomeActivity()) {
11276                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11277                    try {
11278                        ActivityThread.getPackageManager()
11279                                .clearPackagePreferredActivities(r.packageName);
11280                    } catch (RemoteException c) {
11281                        // pm is in same process, this will never happen.
11282                    }
11283                }
11284            }
11285        }
11286
11287        if (!app.isolated) {
11288            // XXX Can't keep track of crash times for isolated processes,
11289            // because they don't have a perisistent identity.
11290            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11291        }
11292
11293        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11294        return true;
11295    }
11296
11297    void startAppProblemLocked(ProcessRecord app) {
11298        // If this app is not running under the current user, then we
11299        // can't give it a report button because that would require
11300        // launching the report UI under a different user.
11301        app.errorReportReceiver = null;
11302
11303        for (int userId : mCurrentProfileIds) {
11304            if (app.userId == userId) {
11305                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11306                        mContext, app.info.packageName, app.info.flags);
11307            }
11308        }
11309        skipCurrentReceiverLocked(app);
11310    }
11311
11312    void skipCurrentReceiverLocked(ProcessRecord app) {
11313        for (BroadcastQueue queue : mBroadcastQueues) {
11314            queue.skipCurrentReceiverLocked(app);
11315        }
11316    }
11317
11318    /**
11319     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11320     * The application process will exit immediately after this call returns.
11321     * @param app object of the crashing app, null for the system server
11322     * @param crashInfo describing the exception
11323     */
11324    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11325        ProcessRecord r = findAppProcess(app, "Crash");
11326        final String processName = app == null ? "system_server"
11327                : (r == null ? "unknown" : r.processName);
11328
11329        handleApplicationCrashInner("crash", r, processName, crashInfo);
11330    }
11331
11332    /* Native crash reporting uses this inner version because it needs to be somewhat
11333     * decoupled from the AM-managed cleanup lifecycle
11334     */
11335    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11336            ApplicationErrorReport.CrashInfo crashInfo) {
11337        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11338                UserHandle.getUserId(Binder.getCallingUid()), processName,
11339                r == null ? -1 : r.info.flags,
11340                crashInfo.exceptionClassName,
11341                crashInfo.exceptionMessage,
11342                crashInfo.throwFileName,
11343                crashInfo.throwLineNumber);
11344
11345        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11346
11347        crashApplication(r, crashInfo);
11348    }
11349
11350    public void handleApplicationStrictModeViolation(
11351            IBinder app,
11352            int violationMask,
11353            StrictMode.ViolationInfo info) {
11354        ProcessRecord r = findAppProcess(app, "StrictMode");
11355        if (r == null) {
11356            return;
11357        }
11358
11359        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11360            Integer stackFingerprint = info.hashCode();
11361            boolean logIt = true;
11362            synchronized (mAlreadyLoggedViolatedStacks) {
11363                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11364                    logIt = false;
11365                    // TODO: sub-sample into EventLog for these, with
11366                    // the info.durationMillis?  Then we'd get
11367                    // the relative pain numbers, without logging all
11368                    // the stack traces repeatedly.  We'd want to do
11369                    // likewise in the client code, which also does
11370                    // dup suppression, before the Binder call.
11371                } else {
11372                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11373                        mAlreadyLoggedViolatedStacks.clear();
11374                    }
11375                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11376                }
11377            }
11378            if (logIt) {
11379                logStrictModeViolationToDropBox(r, info);
11380            }
11381        }
11382
11383        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11384            AppErrorResult result = new AppErrorResult();
11385            synchronized (this) {
11386                final long origId = Binder.clearCallingIdentity();
11387
11388                Message msg = Message.obtain();
11389                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11390                HashMap<String, Object> data = new HashMap<String, Object>();
11391                data.put("result", result);
11392                data.put("app", r);
11393                data.put("violationMask", violationMask);
11394                data.put("info", info);
11395                msg.obj = data;
11396                mHandler.sendMessage(msg);
11397
11398                Binder.restoreCallingIdentity(origId);
11399            }
11400            int res = result.get();
11401            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11402        }
11403    }
11404
11405    // Depending on the policy in effect, there could be a bunch of
11406    // these in quick succession so we try to batch these together to
11407    // minimize disk writes, number of dropbox entries, and maximize
11408    // compression, by having more fewer, larger records.
11409    private void logStrictModeViolationToDropBox(
11410            ProcessRecord process,
11411            StrictMode.ViolationInfo info) {
11412        if (info == null) {
11413            return;
11414        }
11415        final boolean isSystemApp = process == null ||
11416                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11417                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11418        final String processName = process == null ? "unknown" : process.processName;
11419        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11420        final DropBoxManager dbox = (DropBoxManager)
11421                mContext.getSystemService(Context.DROPBOX_SERVICE);
11422
11423        // Exit early if the dropbox isn't configured to accept this report type.
11424        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11425
11426        boolean bufferWasEmpty;
11427        boolean needsFlush;
11428        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11429        synchronized (sb) {
11430            bufferWasEmpty = sb.length() == 0;
11431            appendDropBoxProcessHeaders(process, processName, sb);
11432            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11433            sb.append("System-App: ").append(isSystemApp).append("\n");
11434            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11435            if (info.violationNumThisLoop != 0) {
11436                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11437            }
11438            if (info.numAnimationsRunning != 0) {
11439                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11440            }
11441            if (info.broadcastIntentAction != null) {
11442                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11443            }
11444            if (info.durationMillis != -1) {
11445                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11446            }
11447            if (info.numInstances != -1) {
11448                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11449            }
11450            if (info.tags != null) {
11451                for (String tag : info.tags) {
11452                    sb.append("Span-Tag: ").append(tag).append("\n");
11453                }
11454            }
11455            sb.append("\n");
11456            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11457                sb.append(info.crashInfo.stackTrace);
11458            }
11459            sb.append("\n");
11460
11461            // Only buffer up to ~64k.  Various logging bits truncate
11462            // things at 128k.
11463            needsFlush = (sb.length() > 64 * 1024);
11464        }
11465
11466        // Flush immediately if the buffer's grown too large, or this
11467        // is a non-system app.  Non-system apps are isolated with a
11468        // different tag & policy and not batched.
11469        //
11470        // Batching is useful during internal testing with
11471        // StrictMode settings turned up high.  Without batching,
11472        // thousands of separate files could be created on boot.
11473        if (!isSystemApp || needsFlush) {
11474            new Thread("Error dump: " + dropboxTag) {
11475                @Override
11476                public void run() {
11477                    String report;
11478                    synchronized (sb) {
11479                        report = sb.toString();
11480                        sb.delete(0, sb.length());
11481                        sb.trimToSize();
11482                    }
11483                    if (report.length() != 0) {
11484                        dbox.addText(dropboxTag, report);
11485                    }
11486                }
11487            }.start();
11488            return;
11489        }
11490
11491        // System app batching:
11492        if (!bufferWasEmpty) {
11493            // An existing dropbox-writing thread is outstanding, so
11494            // we don't need to start it up.  The existing thread will
11495            // catch the buffer appends we just did.
11496            return;
11497        }
11498
11499        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11500        // (After this point, we shouldn't access AMS internal data structures.)
11501        new Thread("Error dump: " + dropboxTag) {
11502            @Override
11503            public void run() {
11504                // 5 second sleep to let stacks arrive and be batched together
11505                try {
11506                    Thread.sleep(5000);  // 5 seconds
11507                } catch (InterruptedException e) {}
11508
11509                String errorReport;
11510                synchronized (mStrictModeBuffer) {
11511                    errorReport = mStrictModeBuffer.toString();
11512                    if (errorReport.length() == 0) {
11513                        return;
11514                    }
11515                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11516                    mStrictModeBuffer.trimToSize();
11517                }
11518                dbox.addText(dropboxTag, errorReport);
11519            }
11520        }.start();
11521    }
11522
11523    /**
11524     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11525     * @param app object of the crashing app, null for the system server
11526     * @param tag reported by the caller
11527     * @param system whether this wtf is coming from the system
11528     * @param crashInfo describing the context of the error
11529     * @return true if the process should exit immediately (WTF is fatal)
11530     */
11531    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11532            final ApplicationErrorReport.CrashInfo crashInfo) {
11533        final ProcessRecord r = findAppProcess(app, "WTF");
11534        final String processName = app == null ? "system_server"
11535                : (r == null ? "unknown" : r.processName);
11536
11537        EventLog.writeEvent(EventLogTags.AM_WTF,
11538                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11539                processName,
11540                r == null ? -1 : r.info.flags,
11541                tag, crashInfo.exceptionMessage);
11542
11543        if (system) {
11544            // If this is coming from the system, we could very well have low-level
11545            // system locks held, so we want to do this all asynchronously.  And we
11546            // never want this to become fatal, so there is that too.
11547            mHandler.post(new Runnable() {
11548                @Override public void run() {
11549                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11550                            crashInfo);
11551                }
11552            });
11553            return false;
11554        }
11555
11556        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11557
11558        if (r != null && r.pid != Process.myPid() &&
11559                Settings.Global.getInt(mContext.getContentResolver(),
11560                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11561            crashApplication(r, crashInfo);
11562            return true;
11563        } else {
11564            return false;
11565        }
11566    }
11567
11568    /**
11569     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11570     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11571     */
11572    private ProcessRecord findAppProcess(IBinder app, String reason) {
11573        if (app == null) {
11574            return null;
11575        }
11576
11577        synchronized (this) {
11578            final int NP = mProcessNames.getMap().size();
11579            for (int ip=0; ip<NP; ip++) {
11580                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11581                final int NA = apps.size();
11582                for (int ia=0; ia<NA; ia++) {
11583                    ProcessRecord p = apps.valueAt(ia);
11584                    if (p.thread != null && p.thread.asBinder() == app) {
11585                        return p;
11586                    }
11587                }
11588            }
11589
11590            Slog.w(TAG, "Can't find mystery application for " + reason
11591                    + " from pid=" + Binder.getCallingPid()
11592                    + " uid=" + Binder.getCallingUid() + ": " + app);
11593            return null;
11594        }
11595    }
11596
11597    /**
11598     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11599     * to append various headers to the dropbox log text.
11600     */
11601    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11602            StringBuilder sb) {
11603        // Watchdog thread ends up invoking this function (with
11604        // a null ProcessRecord) to add the stack file to dropbox.
11605        // Do not acquire a lock on this (am) in such cases, as it
11606        // could cause a potential deadlock, if and when watchdog
11607        // is invoked due to unavailability of lock on am and it
11608        // would prevent watchdog from killing system_server.
11609        if (process == null) {
11610            sb.append("Process: ").append(processName).append("\n");
11611            return;
11612        }
11613        // Note: ProcessRecord 'process' is guarded by the service
11614        // instance.  (notably process.pkgList, which could otherwise change
11615        // concurrently during execution of this method)
11616        synchronized (this) {
11617            sb.append("Process: ").append(processName).append("\n");
11618            int flags = process.info.flags;
11619            IPackageManager pm = AppGlobals.getPackageManager();
11620            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11621            for (int ip=0; ip<process.pkgList.size(); ip++) {
11622                String pkg = process.pkgList.keyAt(ip);
11623                sb.append("Package: ").append(pkg);
11624                try {
11625                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11626                    if (pi != null) {
11627                        sb.append(" v").append(pi.versionCode);
11628                        if (pi.versionName != null) {
11629                            sb.append(" (").append(pi.versionName).append(")");
11630                        }
11631                    }
11632                } catch (RemoteException e) {
11633                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11634                }
11635                sb.append("\n");
11636            }
11637        }
11638    }
11639
11640    private static String processClass(ProcessRecord process) {
11641        if (process == null || process.pid == MY_PID) {
11642            return "system_server";
11643        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11644            return "system_app";
11645        } else {
11646            return "data_app";
11647        }
11648    }
11649
11650    /**
11651     * Write a description of an error (crash, WTF, ANR) to the drop box.
11652     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11653     * @param process which caused the error, null means the system server
11654     * @param activity which triggered the error, null if unknown
11655     * @param parent activity related to the error, null if unknown
11656     * @param subject line related to the error, null if absent
11657     * @param report in long form describing the error, null if absent
11658     * @param logFile to include in the report, null if none
11659     * @param crashInfo giving an application stack trace, null if absent
11660     */
11661    public void addErrorToDropBox(String eventType,
11662            ProcessRecord process, String processName, ActivityRecord activity,
11663            ActivityRecord parent, String subject,
11664            final String report, final File logFile,
11665            final ApplicationErrorReport.CrashInfo crashInfo) {
11666        // NOTE -- this must never acquire the ActivityManagerService lock,
11667        // otherwise the watchdog may be prevented from resetting the system.
11668
11669        final String dropboxTag = processClass(process) + "_" + eventType;
11670        final DropBoxManager dbox = (DropBoxManager)
11671                mContext.getSystemService(Context.DROPBOX_SERVICE);
11672
11673        // Exit early if the dropbox isn't configured to accept this report type.
11674        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11675
11676        final StringBuilder sb = new StringBuilder(1024);
11677        appendDropBoxProcessHeaders(process, processName, sb);
11678        if (activity != null) {
11679            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11680        }
11681        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11682            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11683        }
11684        if (parent != null && parent != activity) {
11685            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11686        }
11687        if (subject != null) {
11688            sb.append("Subject: ").append(subject).append("\n");
11689        }
11690        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11691        if (Debug.isDebuggerConnected()) {
11692            sb.append("Debugger: Connected\n");
11693        }
11694        sb.append("\n");
11695
11696        // Do the rest in a worker thread to avoid blocking the caller on I/O
11697        // (After this point, we shouldn't access AMS internal data structures.)
11698        Thread worker = new Thread("Error dump: " + dropboxTag) {
11699            @Override
11700            public void run() {
11701                if (report != null) {
11702                    sb.append(report);
11703                }
11704                if (logFile != null) {
11705                    try {
11706                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11707                                    "\n\n[[TRUNCATED]]"));
11708                    } catch (IOException e) {
11709                        Slog.e(TAG, "Error reading " + logFile, e);
11710                    }
11711                }
11712                if (crashInfo != null && crashInfo.stackTrace != null) {
11713                    sb.append(crashInfo.stackTrace);
11714                }
11715
11716                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11717                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11718                if (lines > 0) {
11719                    sb.append("\n");
11720
11721                    // Merge several logcat streams, and take the last N lines
11722                    InputStreamReader input = null;
11723                    try {
11724                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11725                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11726                                "-b", "crash",
11727                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11728
11729                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11730                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11731                        input = new InputStreamReader(logcat.getInputStream());
11732
11733                        int num;
11734                        char[] buf = new char[8192];
11735                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11736                    } catch (IOException e) {
11737                        Slog.e(TAG, "Error running logcat", e);
11738                    } finally {
11739                        if (input != null) try { input.close(); } catch (IOException e) {}
11740                    }
11741                }
11742
11743                dbox.addText(dropboxTag, sb.toString());
11744            }
11745        };
11746
11747        if (process == null) {
11748            // If process is null, we are being called from some internal code
11749            // and may be about to die -- run this synchronously.
11750            worker.run();
11751        } else {
11752            worker.start();
11753        }
11754    }
11755
11756    /**
11757     * Bring up the "unexpected error" dialog box for a crashing app.
11758     * Deal with edge cases (intercepts from instrumented applications,
11759     * ActivityController, error intent receivers, that sort of thing).
11760     * @param r the application crashing
11761     * @param crashInfo describing the failure
11762     */
11763    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11764        long timeMillis = System.currentTimeMillis();
11765        String shortMsg = crashInfo.exceptionClassName;
11766        String longMsg = crashInfo.exceptionMessage;
11767        String stackTrace = crashInfo.stackTrace;
11768        if (shortMsg != null && longMsg != null) {
11769            longMsg = shortMsg + ": " + longMsg;
11770        } else if (shortMsg != null) {
11771            longMsg = shortMsg;
11772        }
11773
11774        AppErrorResult result = new AppErrorResult();
11775        synchronized (this) {
11776            if (mController != null) {
11777                try {
11778                    String name = r != null ? r.processName : null;
11779                    int pid = r != null ? r.pid : Binder.getCallingPid();
11780                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11781                    if (!mController.appCrashed(name, pid,
11782                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11783                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11784                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11785                            Slog.w(TAG, "Skip killing native crashed app " + name
11786                                    + "(" + pid + ") during testing");
11787                        } else {
11788                            Slog.w(TAG, "Force-killing crashed app " + name
11789                                    + " at watcher's request");
11790                            if (r != null) {
11791                                r.kill("crash", true);
11792                            } else {
11793                                // Huh.
11794                                Process.killProcess(pid);
11795                                Process.killProcessGroup(uid, pid);
11796                            }
11797                        }
11798                        return;
11799                    }
11800                } catch (RemoteException e) {
11801                    mController = null;
11802                    Watchdog.getInstance().setActivityController(null);
11803                }
11804            }
11805
11806            final long origId = Binder.clearCallingIdentity();
11807
11808            // If this process is running instrumentation, finish it.
11809            if (r != null && r.instrumentationClass != null) {
11810                Slog.w(TAG, "Error in app " + r.processName
11811                      + " running instrumentation " + r.instrumentationClass + ":");
11812                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11813                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11814                Bundle info = new Bundle();
11815                info.putString("shortMsg", shortMsg);
11816                info.putString("longMsg", longMsg);
11817                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11818                Binder.restoreCallingIdentity(origId);
11819                return;
11820            }
11821
11822            // If we can't identify the process or it's already exceeded its crash quota,
11823            // quit right away without showing a crash dialog.
11824            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11825                Binder.restoreCallingIdentity(origId);
11826                return;
11827            }
11828
11829            Message msg = Message.obtain();
11830            msg.what = SHOW_ERROR_MSG;
11831            HashMap data = new HashMap();
11832            data.put("result", result);
11833            data.put("app", r);
11834            msg.obj = data;
11835            mHandler.sendMessage(msg);
11836
11837            Binder.restoreCallingIdentity(origId);
11838        }
11839
11840        int res = result.get();
11841
11842        Intent appErrorIntent = null;
11843        synchronized (this) {
11844            if (r != null && !r.isolated) {
11845                // XXX Can't keep track of crash time for isolated processes,
11846                // since they don't have a persistent identity.
11847                mProcessCrashTimes.put(r.info.processName, r.uid,
11848                        SystemClock.uptimeMillis());
11849            }
11850            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11851                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11852            }
11853        }
11854
11855        if (appErrorIntent != null) {
11856            try {
11857                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11858            } catch (ActivityNotFoundException e) {
11859                Slog.w(TAG, "bug report receiver dissappeared", e);
11860            }
11861        }
11862    }
11863
11864    Intent createAppErrorIntentLocked(ProcessRecord r,
11865            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11866        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11867        if (report == null) {
11868            return null;
11869        }
11870        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11871        result.setComponent(r.errorReportReceiver);
11872        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11873        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11874        return result;
11875    }
11876
11877    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11878            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11879        if (r.errorReportReceiver == null) {
11880            return null;
11881        }
11882
11883        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11884            return null;
11885        }
11886
11887        ApplicationErrorReport report = new ApplicationErrorReport();
11888        report.packageName = r.info.packageName;
11889        report.installerPackageName = r.errorReportReceiver.getPackageName();
11890        report.processName = r.processName;
11891        report.time = timeMillis;
11892        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11893
11894        if (r.crashing || r.forceCrashReport) {
11895            report.type = ApplicationErrorReport.TYPE_CRASH;
11896            report.crashInfo = crashInfo;
11897        } else if (r.notResponding) {
11898            report.type = ApplicationErrorReport.TYPE_ANR;
11899            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11900
11901            report.anrInfo.activity = r.notRespondingReport.tag;
11902            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11903            report.anrInfo.info = r.notRespondingReport.longMsg;
11904        }
11905
11906        return report;
11907    }
11908
11909    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11910        enforceNotIsolatedCaller("getProcessesInErrorState");
11911        // assume our apps are happy - lazy create the list
11912        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11913
11914        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11915                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11916        int userId = UserHandle.getUserId(Binder.getCallingUid());
11917
11918        synchronized (this) {
11919
11920            // iterate across all processes
11921            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11922                ProcessRecord app = mLruProcesses.get(i);
11923                if (!allUsers && app.userId != userId) {
11924                    continue;
11925                }
11926                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11927                    // This one's in trouble, so we'll generate a report for it
11928                    // crashes are higher priority (in case there's a crash *and* an anr)
11929                    ActivityManager.ProcessErrorStateInfo report = null;
11930                    if (app.crashing) {
11931                        report = app.crashingReport;
11932                    } else if (app.notResponding) {
11933                        report = app.notRespondingReport;
11934                    }
11935
11936                    if (report != null) {
11937                        if (errList == null) {
11938                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11939                        }
11940                        errList.add(report);
11941                    } else {
11942                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11943                                " crashing = " + app.crashing +
11944                                " notResponding = " + app.notResponding);
11945                    }
11946                }
11947            }
11948        }
11949
11950        return errList;
11951    }
11952
11953    static int procStateToImportance(int procState, int memAdj,
11954            ActivityManager.RunningAppProcessInfo currApp) {
11955        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11956        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11957            currApp.lru = memAdj;
11958        } else {
11959            currApp.lru = 0;
11960        }
11961        return imp;
11962    }
11963
11964    private void fillInProcMemInfo(ProcessRecord app,
11965            ActivityManager.RunningAppProcessInfo outInfo) {
11966        outInfo.pid = app.pid;
11967        outInfo.uid = app.info.uid;
11968        if (mHeavyWeightProcess == app) {
11969            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11970        }
11971        if (app.persistent) {
11972            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11973        }
11974        if (app.activities.size() > 0) {
11975            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11976        }
11977        outInfo.lastTrimLevel = app.trimMemoryLevel;
11978        int adj = app.curAdj;
11979        int procState = app.curProcState;
11980        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11981        outInfo.importanceReasonCode = app.adjTypeCode;
11982        outInfo.processState = app.curProcState;
11983    }
11984
11985    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11986        enforceNotIsolatedCaller("getRunningAppProcesses");
11987        // Lazy instantiation of list
11988        List<ActivityManager.RunningAppProcessInfo> runList = null;
11989        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11990                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11991        int userId = UserHandle.getUserId(Binder.getCallingUid());
11992        synchronized (this) {
11993            // Iterate across all processes
11994            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11995                ProcessRecord app = mLruProcesses.get(i);
11996                if (!allUsers && app.userId != userId) {
11997                    continue;
11998                }
11999                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12000                    // Generate process state info for running application
12001                    ActivityManager.RunningAppProcessInfo currApp =
12002                        new ActivityManager.RunningAppProcessInfo(app.processName,
12003                                app.pid, app.getPackageList());
12004                    fillInProcMemInfo(app, currApp);
12005                    if (app.adjSource instanceof ProcessRecord) {
12006                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12007                        currApp.importanceReasonImportance =
12008                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12009                                        app.adjSourceProcState);
12010                    } else if (app.adjSource instanceof ActivityRecord) {
12011                        ActivityRecord r = (ActivityRecord)app.adjSource;
12012                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12013                    }
12014                    if (app.adjTarget instanceof ComponentName) {
12015                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12016                    }
12017                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12018                    //        + " lru=" + currApp.lru);
12019                    if (runList == null) {
12020                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12021                    }
12022                    runList.add(currApp);
12023                }
12024            }
12025        }
12026        return runList;
12027    }
12028
12029    public List<ApplicationInfo> getRunningExternalApplications() {
12030        enforceNotIsolatedCaller("getRunningExternalApplications");
12031        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12032        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12033        if (runningApps != null && runningApps.size() > 0) {
12034            Set<String> extList = new HashSet<String>();
12035            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12036                if (app.pkgList != null) {
12037                    for (String pkg : app.pkgList) {
12038                        extList.add(pkg);
12039                    }
12040                }
12041            }
12042            IPackageManager pm = AppGlobals.getPackageManager();
12043            for (String pkg : extList) {
12044                try {
12045                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12046                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12047                        retList.add(info);
12048                    }
12049                } catch (RemoteException e) {
12050                }
12051            }
12052        }
12053        return retList;
12054    }
12055
12056    @Override
12057    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12058        enforceNotIsolatedCaller("getMyMemoryState");
12059        synchronized (this) {
12060            ProcessRecord proc;
12061            synchronized (mPidsSelfLocked) {
12062                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12063            }
12064            fillInProcMemInfo(proc, outInfo);
12065        }
12066    }
12067
12068    @Override
12069    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12070        if (checkCallingPermission(android.Manifest.permission.DUMP)
12071                != PackageManager.PERMISSION_GRANTED) {
12072            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12073                    + Binder.getCallingPid()
12074                    + ", uid=" + Binder.getCallingUid()
12075                    + " without permission "
12076                    + android.Manifest.permission.DUMP);
12077            return;
12078        }
12079
12080        boolean dumpAll = false;
12081        boolean dumpClient = false;
12082        String dumpPackage = null;
12083
12084        int opti = 0;
12085        while (opti < args.length) {
12086            String opt = args[opti];
12087            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12088                break;
12089            }
12090            opti++;
12091            if ("-a".equals(opt)) {
12092                dumpAll = true;
12093            } else if ("-c".equals(opt)) {
12094                dumpClient = true;
12095            } else if ("-h".equals(opt)) {
12096                pw.println("Activity manager dump options:");
12097                pw.println("  [-a] [-c] [-h] [cmd] ...");
12098                pw.println("  cmd may be one of:");
12099                pw.println("    a[ctivities]: activity stack state");
12100                pw.println("    r[recents]: recent activities state");
12101                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12102                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12103                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12104                pw.println("    o[om]: out of memory management");
12105                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12106                pw.println("    provider [COMP_SPEC]: provider client-side state");
12107                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12108                pw.println("    service [COMP_SPEC]: service client-side state");
12109                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12110                pw.println("    all: dump all activities");
12111                pw.println("    top: dump the top activity");
12112                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12113                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12114                pw.println("    a partial substring in a component name, a");
12115                pw.println("    hex object identifier.");
12116                pw.println("  -a: include all available server state.");
12117                pw.println("  -c: include client state.");
12118                return;
12119            } else {
12120                pw.println("Unknown argument: " + opt + "; use -h for help");
12121            }
12122        }
12123
12124        long origId = Binder.clearCallingIdentity();
12125        boolean more = false;
12126        // Is the caller requesting to dump a particular piece of data?
12127        if (opti < args.length) {
12128            String cmd = args[opti];
12129            opti++;
12130            if ("activities".equals(cmd) || "a".equals(cmd)) {
12131                synchronized (this) {
12132                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12133                }
12134            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12135                synchronized (this) {
12136                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12137                }
12138            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12139                String[] newArgs;
12140                String name;
12141                if (opti >= args.length) {
12142                    name = null;
12143                    newArgs = EMPTY_STRING_ARRAY;
12144                } else {
12145                    name = args[opti];
12146                    opti++;
12147                    newArgs = new String[args.length - opti];
12148                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12149                            args.length - opti);
12150                }
12151                synchronized (this) {
12152                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12153                }
12154            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12155                String[] newArgs;
12156                String name;
12157                if (opti >= args.length) {
12158                    name = null;
12159                    newArgs = EMPTY_STRING_ARRAY;
12160                } else {
12161                    name = args[opti];
12162                    opti++;
12163                    newArgs = new String[args.length - opti];
12164                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12165                            args.length - opti);
12166                }
12167                synchronized (this) {
12168                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12169                }
12170            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12171                String[] newArgs;
12172                String name;
12173                if (opti >= args.length) {
12174                    name = null;
12175                    newArgs = EMPTY_STRING_ARRAY;
12176                } else {
12177                    name = args[opti];
12178                    opti++;
12179                    newArgs = new String[args.length - opti];
12180                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12181                            args.length - opti);
12182                }
12183                synchronized (this) {
12184                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12185                }
12186            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12187                synchronized (this) {
12188                    dumpOomLocked(fd, pw, args, opti, true);
12189                }
12190            } else if ("provider".equals(cmd)) {
12191                String[] newArgs;
12192                String name;
12193                if (opti >= args.length) {
12194                    name = null;
12195                    newArgs = EMPTY_STRING_ARRAY;
12196                } else {
12197                    name = args[opti];
12198                    opti++;
12199                    newArgs = new String[args.length - opti];
12200                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12201                }
12202                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12203                    pw.println("No providers match: " + name);
12204                    pw.println("Use -h for help.");
12205                }
12206            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12207                synchronized (this) {
12208                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12209                }
12210            } else if ("service".equals(cmd)) {
12211                String[] newArgs;
12212                String name;
12213                if (opti >= args.length) {
12214                    name = null;
12215                    newArgs = EMPTY_STRING_ARRAY;
12216                } else {
12217                    name = args[opti];
12218                    opti++;
12219                    newArgs = new String[args.length - opti];
12220                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12221                            args.length - opti);
12222                }
12223                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12224                    pw.println("No services match: " + name);
12225                    pw.println("Use -h for help.");
12226                }
12227            } else if ("package".equals(cmd)) {
12228                String[] newArgs;
12229                if (opti >= args.length) {
12230                    pw.println("package: no package name specified");
12231                    pw.println("Use -h for help.");
12232                } else {
12233                    dumpPackage = args[opti];
12234                    opti++;
12235                    newArgs = new String[args.length - opti];
12236                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12237                            args.length - opti);
12238                    args = newArgs;
12239                    opti = 0;
12240                    more = true;
12241                }
12242            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12243                synchronized (this) {
12244                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12245                }
12246            } else {
12247                // Dumping a single activity?
12248                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12249                    pw.println("Bad activity command, or no activities match: " + cmd);
12250                    pw.println("Use -h for help.");
12251                }
12252            }
12253            if (!more) {
12254                Binder.restoreCallingIdentity(origId);
12255                return;
12256            }
12257        }
12258
12259        // No piece of data specified, dump everything.
12260        synchronized (this) {
12261            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12262            pw.println();
12263            if (dumpAll) {
12264                pw.println("-------------------------------------------------------------------------------");
12265            }
12266            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12267            pw.println();
12268            if (dumpAll) {
12269                pw.println("-------------------------------------------------------------------------------");
12270            }
12271            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12272            pw.println();
12273            if (dumpAll) {
12274                pw.println("-------------------------------------------------------------------------------");
12275            }
12276            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12277            pw.println();
12278            if (dumpAll) {
12279                pw.println("-------------------------------------------------------------------------------");
12280            }
12281            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12282            pw.println();
12283            if (dumpAll) {
12284                pw.println("-------------------------------------------------------------------------------");
12285            }
12286            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12287            pw.println();
12288            if (dumpAll) {
12289                pw.println("-------------------------------------------------------------------------------");
12290            }
12291            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12292        }
12293        Binder.restoreCallingIdentity(origId);
12294    }
12295
12296    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12297            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12298        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12299
12300        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12301                dumpPackage);
12302        boolean needSep = printedAnything;
12303
12304        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12305                dumpPackage, needSep, "  mFocusedActivity: ");
12306        if (printed) {
12307            printedAnything = true;
12308            needSep = false;
12309        }
12310
12311        if (dumpPackage == null) {
12312            if (needSep) {
12313                pw.println();
12314            }
12315            needSep = true;
12316            printedAnything = true;
12317            mStackSupervisor.dump(pw, "  ");
12318        }
12319
12320        if (!printedAnything) {
12321            pw.println("  (nothing)");
12322        }
12323    }
12324
12325    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12326            int opti, boolean dumpAll, String dumpPackage) {
12327        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12328
12329        boolean printedAnything = false;
12330
12331        if (mRecentTasks.size() > 0) {
12332            boolean printedHeader = false;
12333
12334            final int N = mRecentTasks.size();
12335            for (int i=0; i<N; i++) {
12336                TaskRecord tr = mRecentTasks.get(i);
12337                if (dumpPackage != null) {
12338                    if (tr.realActivity == null ||
12339                            !dumpPackage.equals(tr.realActivity)) {
12340                        continue;
12341                    }
12342                }
12343                if (!printedHeader) {
12344                    pw.println("  Recent tasks:");
12345                    printedHeader = true;
12346                    printedAnything = true;
12347                }
12348                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12349                        pw.println(tr);
12350                if (dumpAll) {
12351                    mRecentTasks.get(i).dump(pw, "    ");
12352                }
12353            }
12354        }
12355
12356        if (!printedAnything) {
12357            pw.println("  (nothing)");
12358        }
12359    }
12360
12361    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12362            int opti, boolean dumpAll, String dumpPackage) {
12363        boolean needSep = false;
12364        boolean printedAnything = false;
12365        int numPers = 0;
12366
12367        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12368
12369        if (dumpAll) {
12370            final int NP = mProcessNames.getMap().size();
12371            for (int ip=0; ip<NP; ip++) {
12372                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12373                final int NA = procs.size();
12374                for (int ia=0; ia<NA; ia++) {
12375                    ProcessRecord r = procs.valueAt(ia);
12376                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12377                        continue;
12378                    }
12379                    if (!needSep) {
12380                        pw.println("  All known processes:");
12381                        needSep = true;
12382                        printedAnything = true;
12383                    }
12384                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12385                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12386                        pw.print(" "); pw.println(r);
12387                    r.dump(pw, "    ");
12388                    if (r.persistent) {
12389                        numPers++;
12390                    }
12391                }
12392            }
12393        }
12394
12395        if (mIsolatedProcesses.size() > 0) {
12396            boolean printed = false;
12397            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12398                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12399                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12400                    continue;
12401                }
12402                if (!printed) {
12403                    if (needSep) {
12404                        pw.println();
12405                    }
12406                    pw.println("  Isolated process list (sorted by uid):");
12407                    printedAnything = true;
12408                    printed = true;
12409                    needSep = true;
12410                }
12411                pw.println(String.format("%sIsolated #%2d: %s",
12412                        "    ", i, r.toString()));
12413            }
12414        }
12415
12416        if (mLruProcesses.size() > 0) {
12417            if (needSep) {
12418                pw.println();
12419            }
12420            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12421                    pw.print(" total, non-act at ");
12422                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12423                    pw.print(", non-svc at ");
12424                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12425                    pw.println("):");
12426            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12427            needSep = true;
12428            printedAnything = true;
12429        }
12430
12431        if (dumpAll || dumpPackage != null) {
12432            synchronized (mPidsSelfLocked) {
12433                boolean printed = false;
12434                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12435                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12436                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12437                        continue;
12438                    }
12439                    if (!printed) {
12440                        if (needSep) pw.println();
12441                        needSep = true;
12442                        pw.println("  PID mappings:");
12443                        printed = true;
12444                        printedAnything = true;
12445                    }
12446                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12447                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12448                }
12449            }
12450        }
12451
12452        if (mForegroundProcesses.size() > 0) {
12453            synchronized (mPidsSelfLocked) {
12454                boolean printed = false;
12455                for (int i=0; i<mForegroundProcesses.size(); i++) {
12456                    ProcessRecord r = mPidsSelfLocked.get(
12457                            mForegroundProcesses.valueAt(i).pid);
12458                    if (dumpPackage != null && (r == null
12459                            || !r.pkgList.containsKey(dumpPackage))) {
12460                        continue;
12461                    }
12462                    if (!printed) {
12463                        if (needSep) pw.println();
12464                        needSep = true;
12465                        pw.println("  Foreground Processes:");
12466                        printed = true;
12467                        printedAnything = true;
12468                    }
12469                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12470                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12471                }
12472            }
12473        }
12474
12475        if (mPersistentStartingProcesses.size() > 0) {
12476            if (needSep) pw.println();
12477            needSep = true;
12478            printedAnything = true;
12479            pw.println("  Persisent processes that are starting:");
12480            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12481                    "Starting Norm", "Restarting PERS", dumpPackage);
12482        }
12483
12484        if (mRemovedProcesses.size() > 0) {
12485            if (needSep) pw.println();
12486            needSep = true;
12487            printedAnything = true;
12488            pw.println("  Processes that are being removed:");
12489            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12490                    "Removed Norm", "Removed PERS", dumpPackage);
12491        }
12492
12493        if (mProcessesOnHold.size() > 0) {
12494            if (needSep) pw.println();
12495            needSep = true;
12496            printedAnything = true;
12497            pw.println("  Processes that are on old until the system is ready:");
12498            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12499                    "OnHold Norm", "OnHold PERS", dumpPackage);
12500        }
12501
12502        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12503
12504        if (mProcessCrashTimes.getMap().size() > 0) {
12505            boolean printed = false;
12506            long now = SystemClock.uptimeMillis();
12507            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12508            final int NP = pmap.size();
12509            for (int ip=0; ip<NP; ip++) {
12510                String pname = pmap.keyAt(ip);
12511                SparseArray<Long> uids = pmap.valueAt(ip);
12512                final int N = uids.size();
12513                for (int i=0; i<N; i++) {
12514                    int puid = uids.keyAt(i);
12515                    ProcessRecord r = mProcessNames.get(pname, puid);
12516                    if (dumpPackage != null && (r == null
12517                            || !r.pkgList.containsKey(dumpPackage))) {
12518                        continue;
12519                    }
12520                    if (!printed) {
12521                        if (needSep) pw.println();
12522                        needSep = true;
12523                        pw.println("  Time since processes crashed:");
12524                        printed = true;
12525                        printedAnything = true;
12526                    }
12527                    pw.print("    Process "); pw.print(pname);
12528                            pw.print(" uid "); pw.print(puid);
12529                            pw.print(": last crashed ");
12530                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12531                            pw.println(" ago");
12532                }
12533            }
12534        }
12535
12536        if (mBadProcesses.getMap().size() > 0) {
12537            boolean printed = false;
12538            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12539            final int NP = pmap.size();
12540            for (int ip=0; ip<NP; ip++) {
12541                String pname = pmap.keyAt(ip);
12542                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12543                final int N = uids.size();
12544                for (int i=0; i<N; i++) {
12545                    int puid = uids.keyAt(i);
12546                    ProcessRecord r = mProcessNames.get(pname, puid);
12547                    if (dumpPackage != null && (r == null
12548                            || !r.pkgList.containsKey(dumpPackage))) {
12549                        continue;
12550                    }
12551                    if (!printed) {
12552                        if (needSep) pw.println();
12553                        needSep = true;
12554                        pw.println("  Bad processes:");
12555                        printedAnything = true;
12556                    }
12557                    BadProcessInfo info = uids.valueAt(i);
12558                    pw.print("    Bad process "); pw.print(pname);
12559                            pw.print(" uid "); pw.print(puid);
12560                            pw.print(": crashed at time "); pw.println(info.time);
12561                    if (info.shortMsg != null) {
12562                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12563                    }
12564                    if (info.longMsg != null) {
12565                        pw.print("      Long msg: "); pw.println(info.longMsg);
12566                    }
12567                    if (info.stack != null) {
12568                        pw.println("      Stack:");
12569                        int lastPos = 0;
12570                        for (int pos=0; pos<info.stack.length(); pos++) {
12571                            if (info.stack.charAt(pos) == '\n') {
12572                                pw.print("        ");
12573                                pw.write(info.stack, lastPos, pos-lastPos);
12574                                pw.println();
12575                                lastPos = pos+1;
12576                            }
12577                        }
12578                        if (lastPos < info.stack.length()) {
12579                            pw.print("        ");
12580                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12581                            pw.println();
12582                        }
12583                    }
12584                }
12585            }
12586        }
12587
12588        if (dumpPackage == null) {
12589            pw.println();
12590            needSep = false;
12591            pw.println("  mStartedUsers:");
12592            for (int i=0; i<mStartedUsers.size(); i++) {
12593                UserStartedState uss = mStartedUsers.valueAt(i);
12594                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12595                        pw.print(": "); uss.dump("", pw);
12596            }
12597            pw.print("  mStartedUserArray: [");
12598            for (int i=0; i<mStartedUserArray.length; i++) {
12599                if (i > 0) pw.print(", ");
12600                pw.print(mStartedUserArray[i]);
12601            }
12602            pw.println("]");
12603            pw.print("  mUserLru: [");
12604            for (int i=0; i<mUserLru.size(); i++) {
12605                if (i > 0) pw.print(", ");
12606                pw.print(mUserLru.get(i));
12607            }
12608            pw.println("]");
12609            if (dumpAll) {
12610                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12611            }
12612            synchronized (mUserProfileGroupIdsSelfLocked) {
12613                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12614                    pw.println("  mUserProfileGroupIds:");
12615                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12616                        pw.print("    User #");
12617                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12618                        pw.print(" -> profile #");
12619                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12620                    }
12621                }
12622            }
12623        }
12624        if (mHomeProcess != null && (dumpPackage == null
12625                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12626            if (needSep) {
12627                pw.println();
12628                needSep = false;
12629            }
12630            pw.println("  mHomeProcess: " + mHomeProcess);
12631        }
12632        if (mPreviousProcess != null && (dumpPackage == null
12633                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12634            if (needSep) {
12635                pw.println();
12636                needSep = false;
12637            }
12638            pw.println("  mPreviousProcess: " + mPreviousProcess);
12639        }
12640        if (dumpAll) {
12641            StringBuilder sb = new StringBuilder(128);
12642            sb.append("  mPreviousProcessVisibleTime: ");
12643            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12644            pw.println(sb);
12645        }
12646        if (mHeavyWeightProcess != null && (dumpPackage == null
12647                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12648            if (needSep) {
12649                pw.println();
12650                needSep = false;
12651            }
12652            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12653        }
12654        if (dumpPackage == null) {
12655            pw.println("  mConfiguration: " + mConfiguration);
12656        }
12657        if (dumpAll) {
12658            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12659            if (mCompatModePackages.getPackages().size() > 0) {
12660                boolean printed = false;
12661                for (Map.Entry<String, Integer> entry
12662                        : mCompatModePackages.getPackages().entrySet()) {
12663                    String pkg = entry.getKey();
12664                    int mode = entry.getValue();
12665                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12666                        continue;
12667                    }
12668                    if (!printed) {
12669                        pw.println("  mScreenCompatPackages:");
12670                        printed = true;
12671                    }
12672                    pw.print("    "); pw.print(pkg); pw.print(": ");
12673                            pw.print(mode); pw.println();
12674                }
12675            }
12676        }
12677        if (dumpPackage == null) {
12678            if (mSleeping || mWentToSleep || mLockScreenShown) {
12679                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12680                        + " mLockScreenShown " + mLockScreenShown);
12681            }
12682            if (mShuttingDown || mRunningVoice) {
12683                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12684            }
12685        }
12686        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12687                || mOrigWaitForDebugger) {
12688            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12689                    || dumpPackage.equals(mOrigDebugApp)) {
12690                if (needSep) {
12691                    pw.println();
12692                    needSep = false;
12693                }
12694                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12695                        + " mDebugTransient=" + mDebugTransient
12696                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12697            }
12698        }
12699        if (mOpenGlTraceApp != null) {
12700            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12701                if (needSep) {
12702                    pw.println();
12703                    needSep = false;
12704                }
12705                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12706            }
12707        }
12708        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12709                || mProfileFd != null) {
12710            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12711                if (needSep) {
12712                    pw.println();
12713                    needSep = false;
12714                }
12715                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12716                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12717                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12718                        + mAutoStopProfiler);
12719                pw.println("  mProfileType=" + mProfileType);
12720            }
12721        }
12722        if (dumpPackage == null) {
12723            if (mAlwaysFinishActivities || mController != null) {
12724                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12725                        + " mController=" + mController);
12726            }
12727            if (dumpAll) {
12728                pw.println("  Total persistent processes: " + numPers);
12729                pw.println("  mProcessesReady=" + mProcessesReady
12730                        + " mSystemReady=" + mSystemReady);
12731                pw.println("  mBooting=" + mBooting
12732                        + " mBooted=" + mBooted
12733                        + " mFactoryTest=" + mFactoryTest);
12734                pw.print("  mLastPowerCheckRealtime=");
12735                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12736                        pw.println("");
12737                pw.print("  mLastPowerCheckUptime=");
12738                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12739                        pw.println("");
12740                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12741                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12742                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12743                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12744                        + " (" + mLruProcesses.size() + " total)"
12745                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12746                        + " mNumServiceProcs=" + mNumServiceProcs
12747                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12748                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12749                        + " mLastMemoryLevel" + mLastMemoryLevel
12750                        + " mLastNumProcesses" + mLastNumProcesses);
12751                long now = SystemClock.uptimeMillis();
12752                pw.print("  mLastIdleTime=");
12753                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12754                        pw.print(" mLowRamSinceLastIdle=");
12755                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12756                        pw.println();
12757            }
12758        }
12759
12760        if (!printedAnything) {
12761            pw.println("  (nothing)");
12762        }
12763    }
12764
12765    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12766            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12767        if (mProcessesToGc.size() > 0) {
12768            boolean printed = false;
12769            long now = SystemClock.uptimeMillis();
12770            for (int i=0; i<mProcessesToGc.size(); i++) {
12771                ProcessRecord proc = mProcessesToGc.get(i);
12772                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12773                    continue;
12774                }
12775                if (!printed) {
12776                    if (needSep) pw.println();
12777                    needSep = true;
12778                    pw.println("  Processes that are waiting to GC:");
12779                    printed = true;
12780                }
12781                pw.print("    Process "); pw.println(proc);
12782                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12783                        pw.print(", last gced=");
12784                        pw.print(now-proc.lastRequestedGc);
12785                        pw.print(" ms ago, last lowMem=");
12786                        pw.print(now-proc.lastLowMemory);
12787                        pw.println(" ms ago");
12788
12789            }
12790        }
12791        return needSep;
12792    }
12793
12794    void printOomLevel(PrintWriter pw, String name, int adj) {
12795        pw.print("    ");
12796        if (adj >= 0) {
12797            pw.print(' ');
12798            if (adj < 10) pw.print(' ');
12799        } else {
12800            if (adj > -10) pw.print(' ');
12801        }
12802        pw.print(adj);
12803        pw.print(": ");
12804        pw.print(name);
12805        pw.print(" (");
12806        pw.print(mProcessList.getMemLevel(adj)/1024);
12807        pw.println(" kB)");
12808    }
12809
12810    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12811            int opti, boolean dumpAll) {
12812        boolean needSep = false;
12813
12814        if (mLruProcesses.size() > 0) {
12815            if (needSep) pw.println();
12816            needSep = true;
12817            pw.println("  OOM levels:");
12818            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12819            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12820            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12821            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12822            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12823            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12824            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12825            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12826            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12827            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12828            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12829            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12830            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12831
12832            if (needSep) pw.println();
12833            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12834                    pw.print(" total, non-act at ");
12835                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12836                    pw.print(", non-svc at ");
12837                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12838                    pw.println("):");
12839            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12840            needSep = true;
12841        }
12842
12843        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12844
12845        pw.println();
12846        pw.println("  mHomeProcess: " + mHomeProcess);
12847        pw.println("  mPreviousProcess: " + mPreviousProcess);
12848        if (mHeavyWeightProcess != null) {
12849            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12850        }
12851
12852        return true;
12853    }
12854
12855    /**
12856     * There are three ways to call this:
12857     *  - no provider specified: dump all the providers
12858     *  - a flattened component name that matched an existing provider was specified as the
12859     *    first arg: dump that one provider
12860     *  - the first arg isn't the flattened component name of an existing provider:
12861     *    dump all providers whose component contains the first arg as a substring
12862     */
12863    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12864            int opti, boolean dumpAll) {
12865        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12866    }
12867
12868    static class ItemMatcher {
12869        ArrayList<ComponentName> components;
12870        ArrayList<String> strings;
12871        ArrayList<Integer> objects;
12872        boolean all;
12873
12874        ItemMatcher() {
12875            all = true;
12876        }
12877
12878        void build(String name) {
12879            ComponentName componentName = ComponentName.unflattenFromString(name);
12880            if (componentName != null) {
12881                if (components == null) {
12882                    components = new ArrayList<ComponentName>();
12883                }
12884                components.add(componentName);
12885                all = false;
12886            } else {
12887                int objectId = 0;
12888                // Not a '/' separated full component name; maybe an object ID?
12889                try {
12890                    objectId = Integer.parseInt(name, 16);
12891                    if (objects == null) {
12892                        objects = new ArrayList<Integer>();
12893                    }
12894                    objects.add(objectId);
12895                    all = false;
12896                } catch (RuntimeException e) {
12897                    // Not an integer; just do string match.
12898                    if (strings == null) {
12899                        strings = new ArrayList<String>();
12900                    }
12901                    strings.add(name);
12902                    all = false;
12903                }
12904            }
12905        }
12906
12907        int build(String[] args, int opti) {
12908            for (; opti<args.length; opti++) {
12909                String name = args[opti];
12910                if ("--".equals(name)) {
12911                    return opti+1;
12912                }
12913                build(name);
12914            }
12915            return opti;
12916        }
12917
12918        boolean match(Object object, ComponentName comp) {
12919            if (all) {
12920                return true;
12921            }
12922            if (components != null) {
12923                for (int i=0; i<components.size(); i++) {
12924                    if (components.get(i).equals(comp)) {
12925                        return true;
12926                    }
12927                }
12928            }
12929            if (objects != null) {
12930                for (int i=0; i<objects.size(); i++) {
12931                    if (System.identityHashCode(object) == objects.get(i)) {
12932                        return true;
12933                    }
12934                }
12935            }
12936            if (strings != null) {
12937                String flat = comp.flattenToString();
12938                for (int i=0; i<strings.size(); i++) {
12939                    if (flat.contains(strings.get(i))) {
12940                        return true;
12941                    }
12942                }
12943            }
12944            return false;
12945        }
12946    }
12947
12948    /**
12949     * There are three things that cmd can be:
12950     *  - a flattened component name that matches an existing activity
12951     *  - the cmd arg isn't the flattened component name of an existing activity:
12952     *    dump all activity whose component contains the cmd as a substring
12953     *  - A hex number of the ActivityRecord object instance.
12954     */
12955    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12956            int opti, boolean dumpAll) {
12957        ArrayList<ActivityRecord> activities;
12958
12959        synchronized (this) {
12960            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12961        }
12962
12963        if (activities.size() <= 0) {
12964            return false;
12965        }
12966
12967        String[] newArgs = new String[args.length - opti];
12968        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12969
12970        TaskRecord lastTask = null;
12971        boolean needSep = false;
12972        for (int i=activities.size()-1; i>=0; i--) {
12973            ActivityRecord r = activities.get(i);
12974            if (needSep) {
12975                pw.println();
12976            }
12977            needSep = true;
12978            synchronized (this) {
12979                if (lastTask != r.task) {
12980                    lastTask = r.task;
12981                    pw.print("TASK "); pw.print(lastTask.affinity);
12982                            pw.print(" id="); pw.println(lastTask.taskId);
12983                    if (dumpAll) {
12984                        lastTask.dump(pw, "  ");
12985                    }
12986                }
12987            }
12988            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12989        }
12990        return true;
12991    }
12992
12993    /**
12994     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12995     * there is a thread associated with the activity.
12996     */
12997    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12998            final ActivityRecord r, String[] args, boolean dumpAll) {
12999        String innerPrefix = prefix + "  ";
13000        synchronized (this) {
13001            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13002                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13003                    pw.print(" pid=");
13004                    if (r.app != null) pw.println(r.app.pid);
13005                    else pw.println("(not running)");
13006            if (dumpAll) {
13007                r.dump(pw, innerPrefix);
13008            }
13009        }
13010        if (r.app != null && r.app.thread != null) {
13011            // flush anything that is already in the PrintWriter since the thread is going
13012            // to write to the file descriptor directly
13013            pw.flush();
13014            try {
13015                TransferPipe tp = new TransferPipe();
13016                try {
13017                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13018                            r.appToken, innerPrefix, args);
13019                    tp.go(fd);
13020                } finally {
13021                    tp.kill();
13022                }
13023            } catch (IOException e) {
13024                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13025            } catch (RemoteException e) {
13026                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13027            }
13028        }
13029    }
13030
13031    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13032            int opti, boolean dumpAll, String dumpPackage) {
13033        boolean needSep = false;
13034        boolean onlyHistory = false;
13035        boolean printedAnything = false;
13036
13037        if ("history".equals(dumpPackage)) {
13038            if (opti < args.length && "-s".equals(args[opti])) {
13039                dumpAll = false;
13040            }
13041            onlyHistory = true;
13042            dumpPackage = null;
13043        }
13044
13045        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13046        if (!onlyHistory && dumpAll) {
13047            if (mRegisteredReceivers.size() > 0) {
13048                boolean printed = false;
13049                Iterator it = mRegisteredReceivers.values().iterator();
13050                while (it.hasNext()) {
13051                    ReceiverList r = (ReceiverList)it.next();
13052                    if (dumpPackage != null && (r.app == null ||
13053                            !dumpPackage.equals(r.app.info.packageName))) {
13054                        continue;
13055                    }
13056                    if (!printed) {
13057                        pw.println("  Registered Receivers:");
13058                        needSep = true;
13059                        printed = true;
13060                        printedAnything = true;
13061                    }
13062                    pw.print("  * "); pw.println(r);
13063                    r.dump(pw, "    ");
13064                }
13065            }
13066
13067            if (mReceiverResolver.dump(pw, needSep ?
13068                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13069                    "    ", dumpPackage, false)) {
13070                needSep = true;
13071                printedAnything = true;
13072            }
13073        }
13074
13075        for (BroadcastQueue q : mBroadcastQueues) {
13076            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13077            printedAnything |= needSep;
13078        }
13079
13080        needSep = true;
13081
13082        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13083            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13084                if (needSep) {
13085                    pw.println();
13086                }
13087                needSep = true;
13088                printedAnything = true;
13089                pw.print("  Sticky broadcasts for user ");
13090                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13091                StringBuilder sb = new StringBuilder(128);
13092                for (Map.Entry<String, ArrayList<Intent>> ent
13093                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13094                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13095                    if (dumpAll) {
13096                        pw.println(":");
13097                        ArrayList<Intent> intents = ent.getValue();
13098                        final int N = intents.size();
13099                        for (int i=0; i<N; i++) {
13100                            sb.setLength(0);
13101                            sb.append("    Intent: ");
13102                            intents.get(i).toShortString(sb, false, true, false, false);
13103                            pw.println(sb.toString());
13104                            Bundle bundle = intents.get(i).getExtras();
13105                            if (bundle != null) {
13106                                pw.print("      ");
13107                                pw.println(bundle.toString());
13108                            }
13109                        }
13110                    } else {
13111                        pw.println("");
13112                    }
13113                }
13114            }
13115        }
13116
13117        if (!onlyHistory && dumpAll) {
13118            pw.println();
13119            for (BroadcastQueue queue : mBroadcastQueues) {
13120                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13121                        + queue.mBroadcastsScheduled);
13122            }
13123            pw.println("  mHandler:");
13124            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13125            needSep = true;
13126            printedAnything = true;
13127        }
13128
13129        if (!printedAnything) {
13130            pw.println("  (nothing)");
13131        }
13132    }
13133
13134    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13135            int opti, boolean dumpAll, String dumpPackage) {
13136        boolean needSep;
13137        boolean printedAnything = false;
13138
13139        ItemMatcher matcher = new ItemMatcher();
13140        matcher.build(args, opti);
13141
13142        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13143
13144        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13145        printedAnything |= needSep;
13146
13147        if (mLaunchingProviders.size() > 0) {
13148            boolean printed = false;
13149            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13150                ContentProviderRecord r = mLaunchingProviders.get(i);
13151                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13152                    continue;
13153                }
13154                if (!printed) {
13155                    if (needSep) pw.println();
13156                    needSep = true;
13157                    pw.println("  Launching content providers:");
13158                    printed = true;
13159                    printedAnything = true;
13160                }
13161                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13162                        pw.println(r);
13163            }
13164        }
13165
13166        if (mGrantedUriPermissions.size() > 0) {
13167            boolean printed = false;
13168            int dumpUid = -2;
13169            if (dumpPackage != null) {
13170                try {
13171                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13172                } catch (NameNotFoundException e) {
13173                    dumpUid = -1;
13174                }
13175            }
13176            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13177                int uid = mGrantedUriPermissions.keyAt(i);
13178                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13179                    continue;
13180                }
13181                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13182                if (!printed) {
13183                    if (needSep) pw.println();
13184                    needSep = true;
13185                    pw.println("  Granted Uri Permissions:");
13186                    printed = true;
13187                    printedAnything = true;
13188                }
13189                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13190                for (UriPermission perm : perms.values()) {
13191                    pw.print("    "); pw.println(perm);
13192                    if (dumpAll) {
13193                        perm.dump(pw, "      ");
13194                    }
13195                }
13196            }
13197        }
13198
13199        if (!printedAnything) {
13200            pw.println("  (nothing)");
13201        }
13202    }
13203
13204    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13205            int opti, boolean dumpAll, String dumpPackage) {
13206        boolean printed = false;
13207
13208        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13209
13210        if (mIntentSenderRecords.size() > 0) {
13211            Iterator<WeakReference<PendingIntentRecord>> it
13212                    = mIntentSenderRecords.values().iterator();
13213            while (it.hasNext()) {
13214                WeakReference<PendingIntentRecord> ref = it.next();
13215                PendingIntentRecord rec = ref != null ? ref.get(): null;
13216                if (dumpPackage != null && (rec == null
13217                        || !dumpPackage.equals(rec.key.packageName))) {
13218                    continue;
13219                }
13220                printed = true;
13221                if (rec != null) {
13222                    pw.print("  * "); pw.println(rec);
13223                    if (dumpAll) {
13224                        rec.dump(pw, "    ");
13225                    }
13226                } else {
13227                    pw.print("  * "); pw.println(ref);
13228                }
13229            }
13230        }
13231
13232        if (!printed) {
13233            pw.println("  (nothing)");
13234        }
13235    }
13236
13237    private static final int dumpProcessList(PrintWriter pw,
13238            ActivityManagerService service, List list,
13239            String prefix, String normalLabel, String persistentLabel,
13240            String dumpPackage) {
13241        int numPers = 0;
13242        final int N = list.size()-1;
13243        for (int i=N; i>=0; i--) {
13244            ProcessRecord r = (ProcessRecord)list.get(i);
13245            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13246                continue;
13247            }
13248            pw.println(String.format("%s%s #%2d: %s",
13249                    prefix, (r.persistent ? persistentLabel : normalLabel),
13250                    i, r.toString()));
13251            if (r.persistent) {
13252                numPers++;
13253            }
13254        }
13255        return numPers;
13256    }
13257
13258    private static final boolean dumpProcessOomList(PrintWriter pw,
13259            ActivityManagerService service, List<ProcessRecord> origList,
13260            String prefix, String normalLabel, String persistentLabel,
13261            boolean inclDetails, String dumpPackage) {
13262
13263        ArrayList<Pair<ProcessRecord, Integer>> list
13264                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13265        for (int i=0; i<origList.size(); i++) {
13266            ProcessRecord r = origList.get(i);
13267            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13268                continue;
13269            }
13270            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13271        }
13272
13273        if (list.size() <= 0) {
13274            return false;
13275        }
13276
13277        Comparator<Pair<ProcessRecord, Integer>> comparator
13278                = new Comparator<Pair<ProcessRecord, Integer>>() {
13279            @Override
13280            public int compare(Pair<ProcessRecord, Integer> object1,
13281                    Pair<ProcessRecord, Integer> object2) {
13282                if (object1.first.setAdj != object2.first.setAdj) {
13283                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13284                }
13285                if (object1.second.intValue() != object2.second.intValue()) {
13286                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13287                }
13288                return 0;
13289            }
13290        };
13291
13292        Collections.sort(list, comparator);
13293
13294        final long curRealtime = SystemClock.elapsedRealtime();
13295        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13296        final long curUptime = SystemClock.uptimeMillis();
13297        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13298
13299        for (int i=list.size()-1; i>=0; i--) {
13300            ProcessRecord r = list.get(i).first;
13301            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13302            char schedGroup;
13303            switch (r.setSchedGroup) {
13304                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13305                    schedGroup = 'B';
13306                    break;
13307                case Process.THREAD_GROUP_DEFAULT:
13308                    schedGroup = 'F';
13309                    break;
13310                default:
13311                    schedGroup = '?';
13312                    break;
13313            }
13314            char foreground;
13315            if (r.foregroundActivities) {
13316                foreground = 'A';
13317            } else if (r.foregroundServices) {
13318                foreground = 'S';
13319            } else {
13320                foreground = ' ';
13321            }
13322            String procState = ProcessList.makeProcStateString(r.curProcState);
13323            pw.print(prefix);
13324            pw.print(r.persistent ? persistentLabel : normalLabel);
13325            pw.print(" #");
13326            int num = (origList.size()-1)-list.get(i).second;
13327            if (num < 10) pw.print(' ');
13328            pw.print(num);
13329            pw.print(": ");
13330            pw.print(oomAdj);
13331            pw.print(' ');
13332            pw.print(schedGroup);
13333            pw.print('/');
13334            pw.print(foreground);
13335            pw.print('/');
13336            pw.print(procState);
13337            pw.print(" trm:");
13338            if (r.trimMemoryLevel < 10) pw.print(' ');
13339            pw.print(r.trimMemoryLevel);
13340            pw.print(' ');
13341            pw.print(r.toShortString());
13342            pw.print(" (");
13343            pw.print(r.adjType);
13344            pw.println(')');
13345            if (r.adjSource != null || r.adjTarget != null) {
13346                pw.print(prefix);
13347                pw.print("    ");
13348                if (r.adjTarget instanceof ComponentName) {
13349                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13350                } else if (r.adjTarget != null) {
13351                    pw.print(r.adjTarget.toString());
13352                } else {
13353                    pw.print("{null}");
13354                }
13355                pw.print("<=");
13356                if (r.adjSource instanceof ProcessRecord) {
13357                    pw.print("Proc{");
13358                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13359                    pw.println("}");
13360                } else if (r.adjSource != null) {
13361                    pw.println(r.adjSource.toString());
13362                } else {
13363                    pw.println("{null}");
13364                }
13365            }
13366            if (inclDetails) {
13367                pw.print(prefix);
13368                pw.print("    ");
13369                pw.print("oom: max="); pw.print(r.maxAdj);
13370                pw.print(" curRaw="); pw.print(r.curRawAdj);
13371                pw.print(" setRaw="); pw.print(r.setRawAdj);
13372                pw.print(" cur="); pw.print(r.curAdj);
13373                pw.print(" set="); pw.println(r.setAdj);
13374                pw.print(prefix);
13375                pw.print("    ");
13376                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13377                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13378                pw.print(" lastPss="); pw.print(r.lastPss);
13379                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13380                pw.print(prefix);
13381                pw.print("    ");
13382                pw.print("cached="); pw.print(r.cached);
13383                pw.print(" empty="); pw.print(r.empty);
13384                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13385
13386                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13387                    if (r.lastWakeTime != 0) {
13388                        long wtime;
13389                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13390                        synchronized (stats) {
13391                            wtime = stats.getProcessWakeTime(r.info.uid,
13392                                    r.pid, curRealtime);
13393                        }
13394                        long timeUsed = wtime - r.lastWakeTime;
13395                        pw.print(prefix);
13396                        pw.print("    ");
13397                        pw.print("keep awake over ");
13398                        TimeUtils.formatDuration(realtimeSince, pw);
13399                        pw.print(" used ");
13400                        TimeUtils.formatDuration(timeUsed, pw);
13401                        pw.print(" (");
13402                        pw.print((timeUsed*100)/realtimeSince);
13403                        pw.println("%)");
13404                    }
13405                    if (r.lastCpuTime != 0) {
13406                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13407                        pw.print(prefix);
13408                        pw.print("    ");
13409                        pw.print("run cpu over ");
13410                        TimeUtils.formatDuration(uptimeSince, pw);
13411                        pw.print(" used ");
13412                        TimeUtils.formatDuration(timeUsed, pw);
13413                        pw.print(" (");
13414                        pw.print((timeUsed*100)/uptimeSince);
13415                        pw.println("%)");
13416                    }
13417                }
13418            }
13419        }
13420        return true;
13421    }
13422
13423    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13424        ArrayList<ProcessRecord> procs;
13425        synchronized (this) {
13426            if (args != null && args.length > start
13427                    && args[start].charAt(0) != '-') {
13428                procs = new ArrayList<ProcessRecord>();
13429                int pid = -1;
13430                try {
13431                    pid = Integer.parseInt(args[start]);
13432                } catch (NumberFormatException e) {
13433                }
13434                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13435                    ProcessRecord proc = mLruProcesses.get(i);
13436                    if (proc.pid == pid) {
13437                        procs.add(proc);
13438                    } else if (proc.processName.equals(args[start])) {
13439                        procs.add(proc);
13440                    }
13441                }
13442                if (procs.size() <= 0) {
13443                    return null;
13444                }
13445            } else {
13446                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13447            }
13448        }
13449        return procs;
13450    }
13451
13452    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13453            PrintWriter pw, String[] args) {
13454        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13455        if (procs == null) {
13456            pw.println("No process found for: " + args[0]);
13457            return;
13458        }
13459
13460        long uptime = SystemClock.uptimeMillis();
13461        long realtime = SystemClock.elapsedRealtime();
13462        pw.println("Applications Graphics Acceleration Info:");
13463        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13464
13465        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13466            ProcessRecord r = procs.get(i);
13467            if (r.thread != null) {
13468                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13469                pw.flush();
13470                try {
13471                    TransferPipe tp = new TransferPipe();
13472                    try {
13473                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13474                        tp.go(fd);
13475                    } finally {
13476                        tp.kill();
13477                    }
13478                } catch (IOException e) {
13479                    pw.println("Failure while dumping the app: " + r);
13480                    pw.flush();
13481                } catch (RemoteException e) {
13482                    pw.println("Got a RemoteException while dumping the app " + r);
13483                    pw.flush();
13484                }
13485            }
13486        }
13487    }
13488
13489    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13490        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13491        if (procs == null) {
13492            pw.println("No process found for: " + args[0]);
13493            return;
13494        }
13495
13496        pw.println("Applications Database Info:");
13497
13498        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13499            ProcessRecord r = procs.get(i);
13500            if (r.thread != null) {
13501                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13502                pw.flush();
13503                try {
13504                    TransferPipe tp = new TransferPipe();
13505                    try {
13506                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13507                        tp.go(fd);
13508                    } finally {
13509                        tp.kill();
13510                    }
13511                } catch (IOException e) {
13512                    pw.println("Failure while dumping the app: " + r);
13513                    pw.flush();
13514                } catch (RemoteException e) {
13515                    pw.println("Got a RemoteException while dumping the app " + r);
13516                    pw.flush();
13517                }
13518            }
13519        }
13520    }
13521
13522    final static class MemItem {
13523        final boolean isProc;
13524        final String label;
13525        final String shortLabel;
13526        final long pss;
13527        final int id;
13528        final boolean hasActivities;
13529        ArrayList<MemItem> subitems;
13530
13531        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13532                boolean _hasActivities) {
13533            isProc = true;
13534            label = _label;
13535            shortLabel = _shortLabel;
13536            pss = _pss;
13537            id = _id;
13538            hasActivities = _hasActivities;
13539        }
13540
13541        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13542            isProc = false;
13543            label = _label;
13544            shortLabel = _shortLabel;
13545            pss = _pss;
13546            id = _id;
13547            hasActivities = false;
13548        }
13549    }
13550
13551    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13552            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13553        if (sort && !isCompact) {
13554            Collections.sort(items, new Comparator<MemItem>() {
13555                @Override
13556                public int compare(MemItem lhs, MemItem rhs) {
13557                    if (lhs.pss < rhs.pss) {
13558                        return 1;
13559                    } else if (lhs.pss > rhs.pss) {
13560                        return -1;
13561                    }
13562                    return 0;
13563                }
13564            });
13565        }
13566
13567        for (int i=0; i<items.size(); i++) {
13568            MemItem mi = items.get(i);
13569            if (!isCompact) {
13570                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13571            } else if (mi.isProc) {
13572                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13573                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13574                pw.println(mi.hasActivities ? ",a" : ",e");
13575            } else {
13576                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13577                pw.println(mi.pss);
13578            }
13579            if (mi.subitems != null) {
13580                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13581                        true, isCompact);
13582            }
13583        }
13584    }
13585
13586    // These are in KB.
13587    static final long[] DUMP_MEM_BUCKETS = new long[] {
13588        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13589        120*1024, 160*1024, 200*1024,
13590        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13591        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13592    };
13593
13594    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13595            boolean stackLike) {
13596        int start = label.lastIndexOf('.');
13597        if (start >= 0) start++;
13598        else start = 0;
13599        int end = label.length();
13600        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13601            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13602                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13603                out.append(bucket);
13604                out.append(stackLike ? "MB." : "MB ");
13605                out.append(label, start, end);
13606                return;
13607            }
13608        }
13609        out.append(memKB/1024);
13610        out.append(stackLike ? "MB." : "MB ");
13611        out.append(label, start, end);
13612    }
13613
13614    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13615            ProcessList.NATIVE_ADJ,
13616            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13617            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13618            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13619            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13620            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13621    };
13622    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13623            "Native",
13624            "System", "Persistent", "Foreground",
13625            "Visible", "Perceptible",
13626            "Heavy Weight", "Backup",
13627            "A Services", "Home",
13628            "Previous", "B Services", "Cached"
13629    };
13630    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13631            "native",
13632            "sys", "pers", "fore",
13633            "vis", "percept",
13634            "heavy", "backup",
13635            "servicea", "home",
13636            "prev", "serviceb", "cached"
13637    };
13638
13639    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13640            long realtime, boolean isCheckinRequest, boolean isCompact) {
13641        if (isCheckinRequest || isCompact) {
13642            // short checkin version
13643            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13644        } else {
13645            pw.println("Applications Memory Usage (kB):");
13646            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13647        }
13648    }
13649
13650    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13651            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13652        boolean dumpDetails = false;
13653        boolean dumpFullDetails = false;
13654        boolean dumpDalvik = false;
13655        boolean oomOnly = false;
13656        boolean isCompact = false;
13657        boolean localOnly = false;
13658
13659        int opti = 0;
13660        while (opti < args.length) {
13661            String opt = args[opti];
13662            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13663                break;
13664            }
13665            opti++;
13666            if ("-a".equals(opt)) {
13667                dumpDetails = true;
13668                dumpFullDetails = true;
13669                dumpDalvik = true;
13670            } else if ("-d".equals(opt)) {
13671                dumpDalvik = true;
13672            } else if ("-c".equals(opt)) {
13673                isCompact = true;
13674            } else if ("--oom".equals(opt)) {
13675                oomOnly = true;
13676            } else if ("--local".equals(opt)) {
13677                localOnly = true;
13678            } else if ("-h".equals(opt)) {
13679                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13680                pw.println("  -a: include all available information for each process.");
13681                pw.println("  -d: include dalvik details when dumping process details.");
13682                pw.println("  -c: dump in a compact machine-parseable representation.");
13683                pw.println("  --oom: only show processes organized by oom adj.");
13684                pw.println("  --local: only collect details locally, don't call process.");
13685                pw.println("If [process] is specified it can be the name or ");
13686                pw.println("pid of a specific process to dump.");
13687                return;
13688            } else {
13689                pw.println("Unknown argument: " + opt + "; use -h for help");
13690            }
13691        }
13692
13693        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13694        long uptime = SystemClock.uptimeMillis();
13695        long realtime = SystemClock.elapsedRealtime();
13696        final long[] tmpLong = new long[1];
13697
13698        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13699        if (procs == null) {
13700            // No Java processes.  Maybe they want to print a native process.
13701            if (args != null && args.length > opti
13702                    && args[opti].charAt(0) != '-') {
13703                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13704                        = new ArrayList<ProcessCpuTracker.Stats>();
13705                updateCpuStatsNow();
13706                int findPid = -1;
13707                try {
13708                    findPid = Integer.parseInt(args[opti]);
13709                } catch (NumberFormatException e) {
13710                }
13711                synchronized (mProcessCpuThread) {
13712                    final int N = mProcessCpuTracker.countStats();
13713                    for (int i=0; i<N; i++) {
13714                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13715                        if (st.pid == findPid || (st.baseName != null
13716                                && st.baseName.equals(args[opti]))) {
13717                            nativeProcs.add(st);
13718                        }
13719                    }
13720                }
13721                if (nativeProcs.size() > 0) {
13722                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13723                            isCompact);
13724                    Debug.MemoryInfo mi = null;
13725                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13726                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13727                        final int pid = r.pid;
13728                        if (!isCheckinRequest && dumpDetails) {
13729                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13730                        }
13731                        if (mi == null) {
13732                            mi = new Debug.MemoryInfo();
13733                        }
13734                        if (dumpDetails || (!brief && !oomOnly)) {
13735                            Debug.getMemoryInfo(pid, mi);
13736                        } else {
13737                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13738                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13739                        }
13740                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13741                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13742                        if (isCheckinRequest) {
13743                            pw.println();
13744                        }
13745                    }
13746                    return;
13747                }
13748            }
13749            pw.println("No process found for: " + args[opti]);
13750            return;
13751        }
13752
13753        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13754            dumpDetails = true;
13755        }
13756
13757        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13758
13759        String[] innerArgs = new String[args.length-opti];
13760        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13761
13762        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13763        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13764        long nativePss=0, dalvikPss=0, otherPss=0;
13765        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13766
13767        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13768        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13769                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13770
13771        long totalPss = 0;
13772        long cachedPss = 0;
13773
13774        Debug.MemoryInfo mi = null;
13775        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13776            final ProcessRecord r = procs.get(i);
13777            final IApplicationThread thread;
13778            final int pid;
13779            final int oomAdj;
13780            final boolean hasActivities;
13781            synchronized (this) {
13782                thread = r.thread;
13783                pid = r.pid;
13784                oomAdj = r.getSetAdjWithServices();
13785                hasActivities = r.activities.size() > 0;
13786            }
13787            if (thread != null) {
13788                if (!isCheckinRequest && dumpDetails) {
13789                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13790                }
13791                if (mi == null) {
13792                    mi = new Debug.MemoryInfo();
13793                }
13794                if (dumpDetails || (!brief && !oomOnly)) {
13795                    Debug.getMemoryInfo(pid, mi);
13796                } else {
13797                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13798                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13799                }
13800                if (dumpDetails) {
13801                    if (localOnly) {
13802                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13803                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13804                        if (isCheckinRequest) {
13805                            pw.println();
13806                        }
13807                    } else {
13808                        try {
13809                            pw.flush();
13810                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13811                                    dumpDalvik, innerArgs);
13812                        } catch (RemoteException e) {
13813                            if (!isCheckinRequest) {
13814                                pw.println("Got RemoteException!");
13815                                pw.flush();
13816                            }
13817                        }
13818                    }
13819                }
13820
13821                final long myTotalPss = mi.getTotalPss();
13822                final long myTotalUss = mi.getTotalUss();
13823
13824                synchronized (this) {
13825                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13826                        // Record this for posterity if the process has been stable.
13827                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13828                    }
13829                }
13830
13831                if (!isCheckinRequest && mi != null) {
13832                    totalPss += myTotalPss;
13833                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13834                            (hasActivities ? " / activities)" : ")"),
13835                            r.processName, myTotalPss, pid, hasActivities);
13836                    procMems.add(pssItem);
13837                    procMemsMap.put(pid, pssItem);
13838
13839                    nativePss += mi.nativePss;
13840                    dalvikPss += mi.dalvikPss;
13841                    otherPss += mi.otherPss;
13842                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13843                        long mem = mi.getOtherPss(j);
13844                        miscPss[j] += mem;
13845                        otherPss -= mem;
13846                    }
13847
13848                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13849                        cachedPss += myTotalPss;
13850                    }
13851
13852                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13853                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13854                                || oomIndex == (oomPss.length-1)) {
13855                            oomPss[oomIndex] += myTotalPss;
13856                            if (oomProcs[oomIndex] == null) {
13857                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13858                            }
13859                            oomProcs[oomIndex].add(pssItem);
13860                            break;
13861                        }
13862                    }
13863                }
13864            }
13865        }
13866
13867        long nativeProcTotalPss = 0;
13868
13869        if (!isCheckinRequest && procs.size() > 1) {
13870            // If we are showing aggregations, also look for native processes to
13871            // include so that our aggregations are more accurate.
13872            updateCpuStatsNow();
13873            synchronized (mProcessCpuThread) {
13874                final int N = mProcessCpuTracker.countStats();
13875                for (int i=0; i<N; i++) {
13876                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13877                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13878                        if (mi == null) {
13879                            mi = new Debug.MemoryInfo();
13880                        }
13881                        if (!brief && !oomOnly) {
13882                            Debug.getMemoryInfo(st.pid, mi);
13883                        } else {
13884                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13885                            mi.nativePrivateDirty = (int)tmpLong[0];
13886                        }
13887
13888                        final long myTotalPss = mi.getTotalPss();
13889                        totalPss += myTotalPss;
13890                        nativeProcTotalPss += myTotalPss;
13891
13892                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13893                                st.name, myTotalPss, st.pid, false);
13894                        procMems.add(pssItem);
13895
13896                        nativePss += mi.nativePss;
13897                        dalvikPss += mi.dalvikPss;
13898                        otherPss += mi.otherPss;
13899                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13900                            long mem = mi.getOtherPss(j);
13901                            miscPss[j] += mem;
13902                            otherPss -= mem;
13903                        }
13904                        oomPss[0] += myTotalPss;
13905                        if (oomProcs[0] == null) {
13906                            oomProcs[0] = new ArrayList<MemItem>();
13907                        }
13908                        oomProcs[0].add(pssItem);
13909                    }
13910                }
13911            }
13912
13913            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13914
13915            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13916            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13917            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13918            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13919                String label = Debug.MemoryInfo.getOtherLabel(j);
13920                catMems.add(new MemItem(label, label, miscPss[j], j));
13921            }
13922
13923            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13924            for (int j=0; j<oomPss.length; j++) {
13925                if (oomPss[j] != 0) {
13926                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13927                            : DUMP_MEM_OOM_LABEL[j];
13928                    MemItem item = new MemItem(label, label, oomPss[j],
13929                            DUMP_MEM_OOM_ADJ[j]);
13930                    item.subitems = oomProcs[j];
13931                    oomMems.add(item);
13932                }
13933            }
13934
13935            if (!brief && !oomOnly && !isCompact) {
13936                pw.println();
13937                pw.println("Total PSS by process:");
13938                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13939                pw.println();
13940            }
13941            if (!isCompact) {
13942                pw.println("Total PSS by OOM adjustment:");
13943            }
13944            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13945            if (!brief && !oomOnly) {
13946                PrintWriter out = categoryPw != null ? categoryPw : pw;
13947                if (!isCompact) {
13948                    out.println();
13949                    out.println("Total PSS by category:");
13950                }
13951                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13952            }
13953            if (!isCompact) {
13954                pw.println();
13955            }
13956            MemInfoReader memInfo = new MemInfoReader();
13957            memInfo.readMemInfo();
13958            if (nativeProcTotalPss > 0) {
13959                synchronized (this) {
13960                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13961                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13962                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13963                            nativeProcTotalPss);
13964                }
13965            }
13966            if (!brief) {
13967                if (!isCompact) {
13968                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13969                    pw.print(" kB (status ");
13970                    switch (mLastMemoryLevel) {
13971                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13972                            pw.println("normal)");
13973                            break;
13974                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13975                            pw.println("moderate)");
13976                            break;
13977                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13978                            pw.println("low)");
13979                            break;
13980                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13981                            pw.println("critical)");
13982                            break;
13983                        default:
13984                            pw.print(mLastMemoryLevel);
13985                            pw.println(")");
13986                            break;
13987                    }
13988                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13989                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13990                            pw.print(cachedPss); pw.print(" cached pss + ");
13991                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13992                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13993                } else {
13994                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13995                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13996                            + memInfo.getFreeSizeKb()); pw.print(",");
13997                    pw.println(totalPss - cachedPss);
13998                }
13999            }
14000            if (!isCompact) {
14001                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14002                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14003                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14004                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14005                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14006                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14007                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14008                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14009                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14010                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14011                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14012            }
14013            if (!brief) {
14014                if (memInfo.getZramTotalSizeKb() != 0) {
14015                    if (!isCompact) {
14016                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14017                                pw.print(" kB physical used for ");
14018                                pw.print(memInfo.getSwapTotalSizeKb()
14019                                        - memInfo.getSwapFreeSizeKb());
14020                                pw.print(" kB in swap (");
14021                                pw.print(memInfo.getSwapTotalSizeKb());
14022                                pw.println(" kB total swap)");
14023                    } else {
14024                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14025                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14026                                pw.println(memInfo.getSwapFreeSizeKb());
14027                    }
14028                }
14029                final int[] SINGLE_LONG_FORMAT = new int[] {
14030                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14031                };
14032                long[] longOut = new long[1];
14033                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14034                        SINGLE_LONG_FORMAT, null, longOut, null);
14035                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14036                longOut[0] = 0;
14037                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14038                        SINGLE_LONG_FORMAT, null, longOut, null);
14039                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14040                longOut[0] = 0;
14041                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14042                        SINGLE_LONG_FORMAT, null, longOut, null);
14043                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14044                longOut[0] = 0;
14045                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14046                        SINGLE_LONG_FORMAT, null, longOut, null);
14047                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14048                if (!isCompact) {
14049                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14050                        pw.print("      KSM: "); pw.print(sharing);
14051                                pw.print(" kB saved from shared ");
14052                                pw.print(shared); pw.println(" kB");
14053                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14054                                pw.print(voltile); pw.println(" kB volatile");
14055                    }
14056                    pw.print("   Tuning: ");
14057                    pw.print(ActivityManager.staticGetMemoryClass());
14058                    pw.print(" (large ");
14059                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14060                    pw.print("), oom ");
14061                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14062                    pw.print(" kB");
14063                    pw.print(", restore limit ");
14064                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14065                    pw.print(" kB");
14066                    if (ActivityManager.isLowRamDeviceStatic()) {
14067                        pw.print(" (low-ram)");
14068                    }
14069                    if (ActivityManager.isHighEndGfx()) {
14070                        pw.print(" (high-end-gfx)");
14071                    }
14072                    pw.println();
14073                } else {
14074                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14075                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14076                    pw.println(voltile);
14077                    pw.print("tuning,");
14078                    pw.print(ActivityManager.staticGetMemoryClass());
14079                    pw.print(',');
14080                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14081                    pw.print(',');
14082                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14083                    if (ActivityManager.isLowRamDeviceStatic()) {
14084                        pw.print(",low-ram");
14085                    }
14086                    if (ActivityManager.isHighEndGfx()) {
14087                        pw.print(",high-end-gfx");
14088                    }
14089                    pw.println();
14090                }
14091            }
14092        }
14093    }
14094
14095    /**
14096     * Searches array of arguments for the specified string
14097     * @param args array of argument strings
14098     * @param value value to search for
14099     * @return true if the value is contained in the array
14100     */
14101    private static boolean scanArgs(String[] args, String value) {
14102        if (args != null) {
14103            for (String arg : args) {
14104                if (value.equals(arg)) {
14105                    return true;
14106                }
14107            }
14108        }
14109        return false;
14110    }
14111
14112    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14113            ContentProviderRecord cpr, boolean always) {
14114        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14115
14116        if (!inLaunching || always) {
14117            synchronized (cpr) {
14118                cpr.launchingApp = null;
14119                cpr.notifyAll();
14120            }
14121            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14122            String names[] = cpr.info.authority.split(";");
14123            for (int j = 0; j < names.length; j++) {
14124                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14125            }
14126        }
14127
14128        for (int i=0; i<cpr.connections.size(); i++) {
14129            ContentProviderConnection conn = cpr.connections.get(i);
14130            if (conn.waiting) {
14131                // If this connection is waiting for the provider, then we don't
14132                // need to mess with its process unless we are always removing
14133                // or for some reason the provider is not currently launching.
14134                if (inLaunching && !always) {
14135                    continue;
14136                }
14137            }
14138            ProcessRecord capp = conn.client;
14139            conn.dead = true;
14140            if (conn.stableCount > 0) {
14141                if (!capp.persistent && capp.thread != null
14142                        && capp.pid != 0
14143                        && capp.pid != MY_PID) {
14144                    capp.kill("depends on provider "
14145                            + cpr.name.flattenToShortString()
14146                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14147                }
14148            } else if (capp.thread != null && conn.provider.provider != null) {
14149                try {
14150                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14151                } catch (RemoteException e) {
14152                }
14153                // In the protocol here, we don't expect the client to correctly
14154                // clean up this connection, we'll just remove it.
14155                cpr.connections.remove(i);
14156                conn.client.conProviders.remove(conn);
14157            }
14158        }
14159
14160        if (inLaunching && always) {
14161            mLaunchingProviders.remove(cpr);
14162        }
14163        return inLaunching;
14164    }
14165
14166    /**
14167     * Main code for cleaning up a process when it has gone away.  This is
14168     * called both as a result of the process dying, or directly when stopping
14169     * a process when running in single process mode.
14170     */
14171    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14172            boolean restarting, boolean allowRestart, int index) {
14173        if (index >= 0) {
14174            removeLruProcessLocked(app);
14175            ProcessList.remove(app.pid);
14176        }
14177
14178        mProcessesToGc.remove(app);
14179        mPendingPssProcesses.remove(app);
14180
14181        // Dismiss any open dialogs.
14182        if (app.crashDialog != null && !app.forceCrashReport) {
14183            app.crashDialog.dismiss();
14184            app.crashDialog = null;
14185        }
14186        if (app.anrDialog != null) {
14187            app.anrDialog.dismiss();
14188            app.anrDialog = null;
14189        }
14190        if (app.waitDialog != null) {
14191            app.waitDialog.dismiss();
14192            app.waitDialog = null;
14193        }
14194
14195        app.crashing = false;
14196        app.notResponding = false;
14197
14198        app.resetPackageList(mProcessStats);
14199        app.unlinkDeathRecipient();
14200        app.makeInactive(mProcessStats);
14201        app.waitingToKill = null;
14202        app.forcingToForeground = null;
14203        updateProcessForegroundLocked(app, false, false);
14204        app.foregroundActivities = false;
14205        app.hasShownUi = false;
14206        app.treatLikeActivity = false;
14207        app.hasAboveClient = false;
14208        app.hasClientActivities = false;
14209
14210        mServices.killServicesLocked(app, allowRestart);
14211
14212        boolean restart = false;
14213
14214        // Remove published content providers.
14215        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14216            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14217            final boolean always = app.bad || !allowRestart;
14218            if (removeDyingProviderLocked(app, cpr, always) || always) {
14219                // We left the provider in the launching list, need to
14220                // restart it.
14221                restart = true;
14222            }
14223
14224            cpr.provider = null;
14225            cpr.proc = null;
14226        }
14227        app.pubProviders.clear();
14228
14229        // Take care of any launching providers waiting for this process.
14230        if (checkAppInLaunchingProvidersLocked(app, false)) {
14231            restart = true;
14232        }
14233
14234        // Unregister from connected content providers.
14235        if (!app.conProviders.isEmpty()) {
14236            for (int i=0; i<app.conProviders.size(); i++) {
14237                ContentProviderConnection conn = app.conProviders.get(i);
14238                conn.provider.connections.remove(conn);
14239            }
14240            app.conProviders.clear();
14241        }
14242
14243        // At this point there may be remaining entries in mLaunchingProviders
14244        // where we were the only one waiting, so they are no longer of use.
14245        // Look for these and clean up if found.
14246        // XXX Commented out for now.  Trying to figure out a way to reproduce
14247        // the actual situation to identify what is actually going on.
14248        if (false) {
14249            for (int i=0; i<mLaunchingProviders.size(); i++) {
14250                ContentProviderRecord cpr = (ContentProviderRecord)
14251                        mLaunchingProviders.get(i);
14252                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14253                    synchronized (cpr) {
14254                        cpr.launchingApp = null;
14255                        cpr.notifyAll();
14256                    }
14257                }
14258            }
14259        }
14260
14261        skipCurrentReceiverLocked(app);
14262
14263        // Unregister any receivers.
14264        for (int i=app.receivers.size()-1; i>=0; i--) {
14265            removeReceiverLocked(app.receivers.valueAt(i));
14266        }
14267        app.receivers.clear();
14268
14269        // If the app is undergoing backup, tell the backup manager about it
14270        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14271            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14272                    + mBackupTarget.appInfo + " died during backup");
14273            try {
14274                IBackupManager bm = IBackupManager.Stub.asInterface(
14275                        ServiceManager.getService(Context.BACKUP_SERVICE));
14276                bm.agentDisconnected(app.info.packageName);
14277            } catch (RemoteException e) {
14278                // can't happen; backup manager is local
14279            }
14280        }
14281
14282        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14283            ProcessChangeItem item = mPendingProcessChanges.get(i);
14284            if (item.pid == app.pid) {
14285                mPendingProcessChanges.remove(i);
14286                mAvailProcessChanges.add(item);
14287            }
14288        }
14289        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14290
14291        // If the caller is restarting this app, then leave it in its
14292        // current lists and let the caller take care of it.
14293        if (restarting) {
14294            return;
14295        }
14296
14297        if (!app.persistent || app.isolated) {
14298            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14299                    "Removing non-persistent process during cleanup: " + app);
14300            mProcessNames.remove(app.processName, app.uid);
14301            mIsolatedProcesses.remove(app.uid);
14302            if (mHeavyWeightProcess == app) {
14303                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14304                        mHeavyWeightProcess.userId, 0));
14305                mHeavyWeightProcess = null;
14306            }
14307        } else if (!app.removed) {
14308            // This app is persistent, so we need to keep its record around.
14309            // If it is not already on the pending app list, add it there
14310            // and start a new process for it.
14311            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14312                mPersistentStartingProcesses.add(app);
14313                restart = true;
14314            }
14315        }
14316        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14317                "Clean-up removing on hold: " + app);
14318        mProcessesOnHold.remove(app);
14319
14320        if (app == mHomeProcess) {
14321            mHomeProcess = null;
14322        }
14323        if (app == mPreviousProcess) {
14324            mPreviousProcess = null;
14325        }
14326
14327        if (restart && !app.isolated) {
14328            // We have components that still need to be running in the
14329            // process, so re-launch it.
14330            mProcessNames.put(app.processName, app.uid, app);
14331            startProcessLocked(app, "restart", app.processName);
14332        } else if (app.pid > 0 && app.pid != MY_PID) {
14333            // Goodbye!
14334            boolean removed;
14335            synchronized (mPidsSelfLocked) {
14336                mPidsSelfLocked.remove(app.pid);
14337                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14338            }
14339            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14340            if (app.isolated) {
14341                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14342            }
14343            app.setPid(0);
14344        }
14345    }
14346
14347    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14348        // Look through the content providers we are waiting to have launched,
14349        // and if any run in this process then either schedule a restart of
14350        // the process or kill the client waiting for it if this process has
14351        // gone bad.
14352        int NL = mLaunchingProviders.size();
14353        boolean restart = false;
14354        for (int i=0; i<NL; i++) {
14355            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14356            if (cpr.launchingApp == app) {
14357                if (!alwaysBad && !app.bad) {
14358                    restart = true;
14359                } else {
14360                    removeDyingProviderLocked(app, cpr, true);
14361                    // cpr should have been removed from mLaunchingProviders
14362                    NL = mLaunchingProviders.size();
14363                    i--;
14364                }
14365            }
14366        }
14367        return restart;
14368    }
14369
14370    // =========================================================
14371    // SERVICES
14372    // =========================================================
14373
14374    @Override
14375    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14376            int flags) {
14377        enforceNotIsolatedCaller("getServices");
14378        synchronized (this) {
14379            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14380        }
14381    }
14382
14383    @Override
14384    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14385        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14386        synchronized (this) {
14387            return mServices.getRunningServiceControlPanelLocked(name);
14388        }
14389    }
14390
14391    @Override
14392    public ComponentName startService(IApplicationThread caller, Intent service,
14393            String resolvedType, int userId) {
14394        enforceNotIsolatedCaller("startService");
14395        // Refuse possible leaked file descriptors
14396        if (service != null && service.hasFileDescriptors() == true) {
14397            throw new IllegalArgumentException("File descriptors passed in Intent");
14398        }
14399
14400        if (DEBUG_SERVICE)
14401            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14402        synchronized(this) {
14403            final int callingPid = Binder.getCallingPid();
14404            final int callingUid = Binder.getCallingUid();
14405            final long origId = Binder.clearCallingIdentity();
14406            ComponentName res = mServices.startServiceLocked(caller, service,
14407                    resolvedType, callingPid, callingUid, userId);
14408            Binder.restoreCallingIdentity(origId);
14409            return res;
14410        }
14411    }
14412
14413    ComponentName startServiceInPackage(int uid,
14414            Intent service, String resolvedType, int userId) {
14415        synchronized(this) {
14416            if (DEBUG_SERVICE)
14417                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14418            final long origId = Binder.clearCallingIdentity();
14419            ComponentName res = mServices.startServiceLocked(null, service,
14420                    resolvedType, -1, uid, userId);
14421            Binder.restoreCallingIdentity(origId);
14422            return res;
14423        }
14424    }
14425
14426    @Override
14427    public int stopService(IApplicationThread caller, Intent service,
14428            String resolvedType, int userId) {
14429        enforceNotIsolatedCaller("stopService");
14430        // Refuse possible leaked file descriptors
14431        if (service != null && service.hasFileDescriptors() == true) {
14432            throw new IllegalArgumentException("File descriptors passed in Intent");
14433        }
14434
14435        synchronized(this) {
14436            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14437        }
14438    }
14439
14440    @Override
14441    public IBinder peekService(Intent service, String resolvedType) {
14442        enforceNotIsolatedCaller("peekService");
14443        // Refuse possible leaked file descriptors
14444        if (service != null && service.hasFileDescriptors() == true) {
14445            throw new IllegalArgumentException("File descriptors passed in Intent");
14446        }
14447        synchronized(this) {
14448            return mServices.peekServiceLocked(service, resolvedType);
14449        }
14450    }
14451
14452    @Override
14453    public boolean stopServiceToken(ComponentName className, IBinder token,
14454            int startId) {
14455        synchronized(this) {
14456            return mServices.stopServiceTokenLocked(className, token, startId);
14457        }
14458    }
14459
14460    @Override
14461    public void setServiceForeground(ComponentName className, IBinder token,
14462            int id, Notification notification, boolean removeNotification) {
14463        synchronized(this) {
14464            mServices.setServiceForegroundLocked(className, token, id, notification,
14465                    removeNotification);
14466        }
14467    }
14468
14469    @Override
14470    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14471            boolean requireFull, String name, String callerPackage) {
14472        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14473                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14474    }
14475
14476    int unsafeConvertIncomingUser(int userId) {
14477        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14478                ? mCurrentUserId : userId;
14479    }
14480
14481    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14482            int allowMode, String name, String callerPackage) {
14483        final int callingUserId = UserHandle.getUserId(callingUid);
14484        if (callingUserId == userId) {
14485            return userId;
14486        }
14487
14488        // Note that we may be accessing mCurrentUserId outside of a lock...
14489        // shouldn't be a big deal, if this is being called outside
14490        // of a locked context there is intrinsically a race with
14491        // the value the caller will receive and someone else changing it.
14492        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14493        // we will switch to the calling user if access to the current user fails.
14494        int targetUserId = unsafeConvertIncomingUser(userId);
14495
14496        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14497            final boolean allow;
14498            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14499                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14500                // If the caller has this permission, they always pass go.  And collect $200.
14501                allow = true;
14502            } else if (allowMode == ALLOW_FULL_ONLY) {
14503                // We require full access, sucks to be you.
14504                allow = false;
14505            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14506                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14507                // If the caller does not have either permission, they are always doomed.
14508                allow = false;
14509            } else if (allowMode == ALLOW_NON_FULL) {
14510                // We are blanket allowing non-full access, you lucky caller!
14511                allow = true;
14512            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14513                // We may or may not allow this depending on whether the two users are
14514                // in the same profile.
14515                synchronized (mUserProfileGroupIdsSelfLocked) {
14516                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14517                            UserInfo.NO_PROFILE_GROUP_ID);
14518                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14519                            UserInfo.NO_PROFILE_GROUP_ID);
14520                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14521                            && callingProfile == targetProfile;
14522                }
14523            } else {
14524                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14525            }
14526            if (!allow) {
14527                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14528                    // In this case, they would like to just execute as their
14529                    // owner user instead of failing.
14530                    targetUserId = callingUserId;
14531                } else {
14532                    StringBuilder builder = new StringBuilder(128);
14533                    builder.append("Permission Denial: ");
14534                    builder.append(name);
14535                    if (callerPackage != null) {
14536                        builder.append(" from ");
14537                        builder.append(callerPackage);
14538                    }
14539                    builder.append(" asks to run as user ");
14540                    builder.append(userId);
14541                    builder.append(" but is calling from user ");
14542                    builder.append(UserHandle.getUserId(callingUid));
14543                    builder.append("; this requires ");
14544                    builder.append(INTERACT_ACROSS_USERS_FULL);
14545                    if (allowMode != ALLOW_FULL_ONLY) {
14546                        builder.append(" or ");
14547                        builder.append(INTERACT_ACROSS_USERS);
14548                    }
14549                    String msg = builder.toString();
14550                    Slog.w(TAG, msg);
14551                    throw new SecurityException(msg);
14552                }
14553            }
14554        }
14555        if (!allowAll && targetUserId < 0) {
14556            throw new IllegalArgumentException(
14557                    "Call does not support special user #" + targetUserId);
14558        }
14559        return targetUserId;
14560    }
14561
14562    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14563            String className, int flags) {
14564        boolean result = false;
14565        // For apps that don't have pre-defined UIDs, check for permission
14566        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14567            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14568                if (ActivityManager.checkUidPermission(
14569                        INTERACT_ACROSS_USERS,
14570                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14571                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14572                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14573                            + " requests FLAG_SINGLE_USER, but app does not hold "
14574                            + INTERACT_ACROSS_USERS;
14575                    Slog.w(TAG, msg);
14576                    throw new SecurityException(msg);
14577                }
14578                // Permission passed
14579                result = true;
14580            }
14581        } else if ("system".equals(componentProcessName)) {
14582            result = true;
14583        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14584                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14585            // Phone app is allowed to export singleuser providers.
14586            result = true;
14587        } else {
14588            // App with pre-defined UID, check if it's a persistent app
14589            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14590        }
14591        if (DEBUG_MU) {
14592            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14593                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14594        }
14595        return result;
14596    }
14597
14598    /**
14599     * Checks to see if the caller is in the same app as the singleton
14600     * component, or the component is in a special app. It allows special apps
14601     * to export singleton components but prevents exporting singleton
14602     * components for regular apps.
14603     */
14604    boolean isValidSingletonCall(int callingUid, int componentUid) {
14605        int componentAppId = UserHandle.getAppId(componentUid);
14606        return UserHandle.isSameApp(callingUid, componentUid)
14607                || componentAppId == Process.SYSTEM_UID
14608                || componentAppId == Process.PHONE_UID
14609                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14610                        == PackageManager.PERMISSION_GRANTED;
14611    }
14612
14613    public int bindService(IApplicationThread caller, IBinder token,
14614            Intent service, String resolvedType,
14615            IServiceConnection connection, int flags, int userId) {
14616        enforceNotIsolatedCaller("bindService");
14617        // Refuse possible leaked file descriptors
14618        if (service != null && service.hasFileDescriptors() == true) {
14619            throw new IllegalArgumentException("File descriptors passed in Intent");
14620        }
14621
14622        synchronized(this) {
14623            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14624                    connection, flags, userId);
14625        }
14626    }
14627
14628    public boolean unbindService(IServiceConnection connection) {
14629        synchronized (this) {
14630            return mServices.unbindServiceLocked(connection);
14631        }
14632    }
14633
14634    public void publishService(IBinder token, Intent intent, IBinder service) {
14635        // Refuse possible leaked file descriptors
14636        if (intent != null && intent.hasFileDescriptors() == true) {
14637            throw new IllegalArgumentException("File descriptors passed in Intent");
14638        }
14639
14640        synchronized(this) {
14641            if (!(token instanceof ServiceRecord)) {
14642                throw new IllegalArgumentException("Invalid service token");
14643            }
14644            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14645        }
14646    }
14647
14648    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14649        // Refuse possible leaked file descriptors
14650        if (intent != null && intent.hasFileDescriptors() == true) {
14651            throw new IllegalArgumentException("File descriptors passed in Intent");
14652        }
14653
14654        synchronized(this) {
14655            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14656        }
14657    }
14658
14659    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14660        synchronized(this) {
14661            if (!(token instanceof ServiceRecord)) {
14662                throw new IllegalArgumentException("Invalid service token");
14663            }
14664            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14665        }
14666    }
14667
14668    // =========================================================
14669    // BACKUP AND RESTORE
14670    // =========================================================
14671
14672    // Cause the target app to be launched if necessary and its backup agent
14673    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14674    // activity manager to announce its creation.
14675    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14676        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14677        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14678
14679        synchronized(this) {
14680            // !!! TODO: currently no check here that we're already bound
14681            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14682            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14683            synchronized (stats) {
14684                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14685            }
14686
14687            // Backup agent is now in use, its package can't be stopped.
14688            try {
14689                AppGlobals.getPackageManager().setPackageStoppedState(
14690                        app.packageName, false, UserHandle.getUserId(app.uid));
14691            } catch (RemoteException e) {
14692            } catch (IllegalArgumentException e) {
14693                Slog.w(TAG, "Failed trying to unstop package "
14694                        + app.packageName + ": " + e);
14695            }
14696
14697            BackupRecord r = new BackupRecord(ss, app, backupMode);
14698            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14699                    ? new ComponentName(app.packageName, app.backupAgentName)
14700                    : new ComponentName("android", "FullBackupAgent");
14701            // startProcessLocked() returns existing proc's record if it's already running
14702            ProcessRecord proc = startProcessLocked(app.processName, app,
14703                    false, 0, "backup", hostingName, false, false, false);
14704            if (proc == null) {
14705                Slog.e(TAG, "Unable to start backup agent process " + r);
14706                return false;
14707            }
14708
14709            r.app = proc;
14710            mBackupTarget = r;
14711            mBackupAppName = app.packageName;
14712
14713            // Try not to kill the process during backup
14714            updateOomAdjLocked(proc);
14715
14716            // If the process is already attached, schedule the creation of the backup agent now.
14717            // If it is not yet live, this will be done when it attaches to the framework.
14718            if (proc.thread != null) {
14719                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14720                try {
14721                    proc.thread.scheduleCreateBackupAgent(app,
14722                            compatibilityInfoForPackageLocked(app), backupMode);
14723                } catch (RemoteException e) {
14724                    // Will time out on the backup manager side
14725                }
14726            } else {
14727                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14728            }
14729            // Invariants: at this point, the target app process exists and the application
14730            // is either already running or in the process of coming up.  mBackupTarget and
14731            // mBackupAppName describe the app, so that when it binds back to the AM we
14732            // know that it's scheduled for a backup-agent operation.
14733        }
14734
14735        return true;
14736    }
14737
14738    @Override
14739    public void clearPendingBackup() {
14740        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14741        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14742
14743        synchronized (this) {
14744            mBackupTarget = null;
14745            mBackupAppName = null;
14746        }
14747    }
14748
14749    // A backup agent has just come up
14750    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14751        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14752                + " = " + agent);
14753
14754        synchronized(this) {
14755            if (!agentPackageName.equals(mBackupAppName)) {
14756                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14757                return;
14758            }
14759        }
14760
14761        long oldIdent = Binder.clearCallingIdentity();
14762        try {
14763            IBackupManager bm = IBackupManager.Stub.asInterface(
14764                    ServiceManager.getService(Context.BACKUP_SERVICE));
14765            bm.agentConnected(agentPackageName, agent);
14766        } catch (RemoteException e) {
14767            // can't happen; the backup manager service is local
14768        } catch (Exception e) {
14769            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14770            e.printStackTrace();
14771        } finally {
14772            Binder.restoreCallingIdentity(oldIdent);
14773        }
14774    }
14775
14776    // done with this agent
14777    public void unbindBackupAgent(ApplicationInfo appInfo) {
14778        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14779        if (appInfo == null) {
14780            Slog.w(TAG, "unbind backup agent for null app");
14781            return;
14782        }
14783
14784        synchronized(this) {
14785            try {
14786                if (mBackupAppName == null) {
14787                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14788                    return;
14789                }
14790
14791                if (!mBackupAppName.equals(appInfo.packageName)) {
14792                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14793                    return;
14794                }
14795
14796                // Not backing this app up any more; reset its OOM adjustment
14797                final ProcessRecord proc = mBackupTarget.app;
14798                updateOomAdjLocked(proc);
14799
14800                // If the app crashed during backup, 'thread' will be null here
14801                if (proc.thread != null) {
14802                    try {
14803                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14804                                compatibilityInfoForPackageLocked(appInfo));
14805                    } catch (Exception e) {
14806                        Slog.e(TAG, "Exception when unbinding backup agent:");
14807                        e.printStackTrace();
14808                    }
14809                }
14810            } finally {
14811                mBackupTarget = null;
14812                mBackupAppName = null;
14813            }
14814        }
14815    }
14816    // =========================================================
14817    // BROADCASTS
14818    // =========================================================
14819
14820    private final List getStickiesLocked(String action, IntentFilter filter,
14821            List cur, int userId) {
14822        final ContentResolver resolver = mContext.getContentResolver();
14823        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14824        if (stickies == null) {
14825            return cur;
14826        }
14827        final ArrayList<Intent> list = stickies.get(action);
14828        if (list == null) {
14829            return cur;
14830        }
14831        int N = list.size();
14832        for (int i=0; i<N; i++) {
14833            Intent intent = list.get(i);
14834            if (filter.match(resolver, intent, true, TAG) >= 0) {
14835                if (cur == null) {
14836                    cur = new ArrayList<Intent>();
14837                }
14838                cur.add(intent);
14839            }
14840        }
14841        return cur;
14842    }
14843
14844    boolean isPendingBroadcastProcessLocked(int pid) {
14845        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14846                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14847    }
14848
14849    void skipPendingBroadcastLocked(int pid) {
14850            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14851            for (BroadcastQueue queue : mBroadcastQueues) {
14852                queue.skipPendingBroadcastLocked(pid);
14853            }
14854    }
14855
14856    // The app just attached; send any pending broadcasts that it should receive
14857    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14858        boolean didSomething = false;
14859        for (BroadcastQueue queue : mBroadcastQueues) {
14860            didSomething |= queue.sendPendingBroadcastsLocked(app);
14861        }
14862        return didSomething;
14863    }
14864
14865    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14866            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14867        enforceNotIsolatedCaller("registerReceiver");
14868        int callingUid;
14869        int callingPid;
14870        synchronized(this) {
14871            ProcessRecord callerApp = null;
14872            if (caller != null) {
14873                callerApp = getRecordForAppLocked(caller);
14874                if (callerApp == null) {
14875                    throw new SecurityException(
14876                            "Unable to find app for caller " + caller
14877                            + " (pid=" + Binder.getCallingPid()
14878                            + ") when registering receiver " + receiver);
14879                }
14880                if (callerApp.info.uid != Process.SYSTEM_UID &&
14881                        !callerApp.pkgList.containsKey(callerPackage) &&
14882                        !"android".equals(callerPackage)) {
14883                    throw new SecurityException("Given caller package " + callerPackage
14884                            + " is not running in process " + callerApp);
14885                }
14886                callingUid = callerApp.info.uid;
14887                callingPid = callerApp.pid;
14888            } else {
14889                callerPackage = null;
14890                callingUid = Binder.getCallingUid();
14891                callingPid = Binder.getCallingPid();
14892            }
14893
14894            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14895                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14896
14897            List allSticky = null;
14898
14899            // Look for any matching sticky broadcasts...
14900            Iterator actions = filter.actionsIterator();
14901            if (actions != null) {
14902                while (actions.hasNext()) {
14903                    String action = (String)actions.next();
14904                    allSticky = getStickiesLocked(action, filter, allSticky,
14905                            UserHandle.USER_ALL);
14906                    allSticky = getStickiesLocked(action, filter, allSticky,
14907                            UserHandle.getUserId(callingUid));
14908                }
14909            } else {
14910                allSticky = getStickiesLocked(null, filter, allSticky,
14911                        UserHandle.USER_ALL);
14912                allSticky = getStickiesLocked(null, filter, allSticky,
14913                        UserHandle.getUserId(callingUid));
14914            }
14915
14916            // The first sticky in the list is returned directly back to
14917            // the client.
14918            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14919
14920            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14921                    + ": " + sticky);
14922
14923            if (receiver == null) {
14924                return sticky;
14925            }
14926
14927            ReceiverList rl
14928                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14929            if (rl == null) {
14930                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14931                        userId, receiver);
14932                if (rl.app != null) {
14933                    rl.app.receivers.add(rl);
14934                } else {
14935                    try {
14936                        receiver.asBinder().linkToDeath(rl, 0);
14937                    } catch (RemoteException e) {
14938                        return sticky;
14939                    }
14940                    rl.linkedToDeath = true;
14941                }
14942                mRegisteredReceivers.put(receiver.asBinder(), rl);
14943            } else if (rl.uid != callingUid) {
14944                throw new IllegalArgumentException(
14945                        "Receiver requested to register for uid " + callingUid
14946                        + " was previously registered for uid " + rl.uid);
14947            } else if (rl.pid != callingPid) {
14948                throw new IllegalArgumentException(
14949                        "Receiver requested to register for pid " + callingPid
14950                        + " was previously registered for pid " + rl.pid);
14951            } else if (rl.userId != userId) {
14952                throw new IllegalArgumentException(
14953                        "Receiver requested to register for user " + userId
14954                        + " was previously registered for user " + rl.userId);
14955            }
14956            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14957                    permission, callingUid, userId);
14958            rl.add(bf);
14959            if (!bf.debugCheck()) {
14960                Slog.w(TAG, "==> For Dynamic broadast");
14961            }
14962            mReceiverResolver.addFilter(bf);
14963
14964            // Enqueue broadcasts for all existing stickies that match
14965            // this filter.
14966            if (allSticky != null) {
14967                ArrayList receivers = new ArrayList();
14968                receivers.add(bf);
14969
14970                int N = allSticky.size();
14971                for (int i=0; i<N; i++) {
14972                    Intent intent = (Intent)allSticky.get(i);
14973                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14974                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14975                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14976                            null, null, false, true, true, -1);
14977                    queue.enqueueParallelBroadcastLocked(r);
14978                    queue.scheduleBroadcastsLocked();
14979                }
14980            }
14981
14982            return sticky;
14983        }
14984    }
14985
14986    public void unregisterReceiver(IIntentReceiver receiver) {
14987        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14988
14989        final long origId = Binder.clearCallingIdentity();
14990        try {
14991            boolean doTrim = false;
14992
14993            synchronized(this) {
14994                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14995                if (rl != null) {
14996                    if (rl.curBroadcast != null) {
14997                        BroadcastRecord r = rl.curBroadcast;
14998                        final boolean doNext = finishReceiverLocked(
14999                                receiver.asBinder(), r.resultCode, r.resultData,
15000                                r.resultExtras, r.resultAbort);
15001                        if (doNext) {
15002                            doTrim = true;
15003                            r.queue.processNextBroadcast(false);
15004                        }
15005                    }
15006
15007                    if (rl.app != null) {
15008                        rl.app.receivers.remove(rl);
15009                    }
15010                    removeReceiverLocked(rl);
15011                    if (rl.linkedToDeath) {
15012                        rl.linkedToDeath = false;
15013                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15014                    }
15015                }
15016            }
15017
15018            // If we actually concluded any broadcasts, we might now be able
15019            // to trim the recipients' apps from our working set
15020            if (doTrim) {
15021                trimApplications();
15022                return;
15023            }
15024
15025        } finally {
15026            Binder.restoreCallingIdentity(origId);
15027        }
15028    }
15029
15030    void removeReceiverLocked(ReceiverList rl) {
15031        mRegisteredReceivers.remove(rl.receiver.asBinder());
15032        int N = rl.size();
15033        for (int i=0; i<N; i++) {
15034            mReceiverResolver.removeFilter(rl.get(i));
15035        }
15036    }
15037
15038    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15039        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15040            ProcessRecord r = mLruProcesses.get(i);
15041            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15042                try {
15043                    r.thread.dispatchPackageBroadcast(cmd, packages);
15044                } catch (RemoteException ex) {
15045                }
15046            }
15047        }
15048    }
15049
15050    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15051            int[] users) {
15052        List<ResolveInfo> receivers = null;
15053        try {
15054            HashSet<ComponentName> singleUserReceivers = null;
15055            boolean scannedFirstReceivers = false;
15056            for (int user : users) {
15057                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15058                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15059                if (user != 0 && newReceivers != null) {
15060                    // If this is not the primary user, we need to check for
15061                    // any receivers that should be filtered out.
15062                    for (int i=0; i<newReceivers.size(); i++) {
15063                        ResolveInfo ri = newReceivers.get(i);
15064                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15065                            newReceivers.remove(i);
15066                            i--;
15067                        }
15068                    }
15069                }
15070                if (newReceivers != null && newReceivers.size() == 0) {
15071                    newReceivers = null;
15072                }
15073                if (receivers == null) {
15074                    receivers = newReceivers;
15075                } else if (newReceivers != null) {
15076                    // We need to concatenate the additional receivers
15077                    // found with what we have do far.  This would be easy,
15078                    // but we also need to de-dup any receivers that are
15079                    // singleUser.
15080                    if (!scannedFirstReceivers) {
15081                        // Collect any single user receivers we had already retrieved.
15082                        scannedFirstReceivers = true;
15083                        for (int i=0; i<receivers.size(); i++) {
15084                            ResolveInfo ri = receivers.get(i);
15085                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15086                                ComponentName cn = new ComponentName(
15087                                        ri.activityInfo.packageName, ri.activityInfo.name);
15088                                if (singleUserReceivers == null) {
15089                                    singleUserReceivers = new HashSet<ComponentName>();
15090                                }
15091                                singleUserReceivers.add(cn);
15092                            }
15093                        }
15094                    }
15095                    // Add the new results to the existing results, tracking
15096                    // and de-dupping single user receivers.
15097                    for (int i=0; i<newReceivers.size(); i++) {
15098                        ResolveInfo ri = newReceivers.get(i);
15099                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15100                            ComponentName cn = new ComponentName(
15101                                    ri.activityInfo.packageName, ri.activityInfo.name);
15102                            if (singleUserReceivers == null) {
15103                                singleUserReceivers = new HashSet<ComponentName>();
15104                            }
15105                            if (!singleUserReceivers.contains(cn)) {
15106                                singleUserReceivers.add(cn);
15107                                receivers.add(ri);
15108                            }
15109                        } else {
15110                            receivers.add(ri);
15111                        }
15112                    }
15113                }
15114            }
15115        } catch (RemoteException ex) {
15116            // pm is in same process, this will never happen.
15117        }
15118        return receivers;
15119    }
15120
15121    private final int broadcastIntentLocked(ProcessRecord callerApp,
15122            String callerPackage, Intent intent, String resolvedType,
15123            IIntentReceiver resultTo, int resultCode, String resultData,
15124            Bundle map, String requiredPermission, int appOp,
15125            boolean ordered, boolean sticky, int callingPid, int callingUid,
15126            int userId) {
15127        intent = new Intent(intent);
15128
15129        // By default broadcasts do not go to stopped apps.
15130        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15131
15132        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15133            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15134            + " ordered=" + ordered + " userid=" + userId);
15135        if ((resultTo != null) && !ordered) {
15136            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15137        }
15138
15139        userId = handleIncomingUser(callingPid, callingUid, userId,
15140                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15141
15142        // Make sure that the user who is receiving this broadcast is started.
15143        // If not, we will just skip it.
15144
15145
15146        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15147            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15148                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15149                Slog.w(TAG, "Skipping broadcast of " + intent
15150                        + ": user " + userId + " is stopped");
15151                return ActivityManager.BROADCAST_SUCCESS;
15152            }
15153        }
15154
15155        /*
15156         * Prevent non-system code (defined here to be non-persistent
15157         * processes) from sending protected broadcasts.
15158         */
15159        int callingAppId = UserHandle.getAppId(callingUid);
15160        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15161            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15162            || callingAppId == Process.NFC_UID || callingUid == 0) {
15163            // Always okay.
15164        } else if (callerApp == null || !callerApp.persistent) {
15165            try {
15166                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15167                        intent.getAction())) {
15168                    String msg = "Permission Denial: not allowed to send broadcast "
15169                            + intent.getAction() + " from pid="
15170                            + callingPid + ", uid=" + callingUid;
15171                    Slog.w(TAG, msg);
15172                    throw new SecurityException(msg);
15173                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15174                    // Special case for compatibility: we don't want apps to send this,
15175                    // but historically it has not been protected and apps may be using it
15176                    // to poke their own app widget.  So, instead of making it protected,
15177                    // just limit it to the caller.
15178                    if (callerApp == null) {
15179                        String msg = "Permission Denial: not allowed to send broadcast "
15180                                + intent.getAction() + " from unknown caller.";
15181                        Slog.w(TAG, msg);
15182                        throw new SecurityException(msg);
15183                    } else if (intent.getComponent() != null) {
15184                        // They are good enough to send to an explicit component...  verify
15185                        // it is being sent to the calling app.
15186                        if (!intent.getComponent().getPackageName().equals(
15187                                callerApp.info.packageName)) {
15188                            String msg = "Permission Denial: not allowed to send broadcast "
15189                                    + intent.getAction() + " to "
15190                                    + intent.getComponent().getPackageName() + " from "
15191                                    + callerApp.info.packageName;
15192                            Slog.w(TAG, msg);
15193                            throw new SecurityException(msg);
15194                        }
15195                    } else {
15196                        // Limit broadcast to their own package.
15197                        intent.setPackage(callerApp.info.packageName);
15198                    }
15199                }
15200            } catch (RemoteException e) {
15201                Slog.w(TAG, "Remote exception", e);
15202                return ActivityManager.BROADCAST_SUCCESS;
15203            }
15204        }
15205
15206        // Handle special intents: if this broadcast is from the package
15207        // manager about a package being removed, we need to remove all of
15208        // its activities from the history stack.
15209        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15210                intent.getAction());
15211        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15212                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15213                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15214                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15215                || uidRemoved) {
15216            if (checkComponentPermission(
15217                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15218                    callingPid, callingUid, -1, true)
15219                    == PackageManager.PERMISSION_GRANTED) {
15220                if (uidRemoved) {
15221                    final Bundle intentExtras = intent.getExtras();
15222                    final int uid = intentExtras != null
15223                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15224                    if (uid >= 0) {
15225                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15226                        synchronized (bs) {
15227                            bs.removeUidStatsLocked(uid);
15228                        }
15229                        mAppOpsService.uidRemoved(uid);
15230                    }
15231                } else {
15232                    // If resources are unavailable just force stop all
15233                    // those packages and flush the attribute cache as well.
15234                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15235                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15236                        if (list != null && (list.length > 0)) {
15237                            for (String pkg : list) {
15238                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15239                                        "storage unmount");
15240                            }
15241                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15242                            sendPackageBroadcastLocked(
15243                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15244                        }
15245                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15246                            intent.getAction())) {
15247                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15248                    } else {
15249                        Uri data = intent.getData();
15250                        String ssp;
15251                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15252                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15253                                    intent.getAction());
15254                            boolean fullUninstall = removed &&
15255                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15256                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15257                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15258                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15259                                        false, fullUninstall, userId,
15260                                        removed ? "pkg removed" : "pkg changed");
15261                            }
15262                            if (removed) {
15263                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15264                                        new String[] {ssp}, userId);
15265                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15266                                    mAppOpsService.packageRemoved(
15267                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15268
15269                                    // Remove all permissions granted from/to this package
15270                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15271                                }
15272                            }
15273                        }
15274                    }
15275                }
15276            } else {
15277                String msg = "Permission Denial: " + intent.getAction()
15278                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15279                        + ", uid=" + callingUid + ")"
15280                        + " requires "
15281                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15282                Slog.w(TAG, msg);
15283                throw new SecurityException(msg);
15284            }
15285
15286        // Special case for adding a package: by default turn on compatibility
15287        // mode.
15288        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15289            Uri data = intent.getData();
15290            String ssp;
15291            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15292                mCompatModePackages.handlePackageAddedLocked(ssp,
15293                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15294            }
15295        }
15296
15297        /*
15298         * If this is the time zone changed action, queue up a message that will reset the timezone
15299         * of all currently running processes. This message will get queued up before the broadcast
15300         * happens.
15301         */
15302        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15303            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15304        }
15305
15306        /*
15307         * If the user set the time, let all running processes know.
15308         */
15309        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15310            final int is24Hour = intent.getBooleanExtra(
15311                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15312            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15313            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15314            synchronized (stats) {
15315                stats.noteCurrentTimeChangedLocked();
15316            }
15317        }
15318
15319        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15320            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15321        }
15322
15323        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15324            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15325            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15326        }
15327
15328        // Add to the sticky list if requested.
15329        if (sticky) {
15330            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15331                    callingPid, callingUid)
15332                    != PackageManager.PERMISSION_GRANTED) {
15333                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15334                        + callingPid + ", uid=" + callingUid
15335                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15336                Slog.w(TAG, msg);
15337                throw new SecurityException(msg);
15338            }
15339            if (requiredPermission != null) {
15340                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15341                        + " and enforce permission " + requiredPermission);
15342                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15343            }
15344            if (intent.getComponent() != null) {
15345                throw new SecurityException(
15346                        "Sticky broadcasts can't target a specific component");
15347            }
15348            // We use userId directly here, since the "all" target is maintained
15349            // as a separate set of sticky broadcasts.
15350            if (userId != UserHandle.USER_ALL) {
15351                // But first, if this is not a broadcast to all users, then
15352                // make sure it doesn't conflict with an existing broadcast to
15353                // all users.
15354                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15355                        UserHandle.USER_ALL);
15356                if (stickies != null) {
15357                    ArrayList<Intent> list = stickies.get(intent.getAction());
15358                    if (list != null) {
15359                        int N = list.size();
15360                        int i;
15361                        for (i=0; i<N; i++) {
15362                            if (intent.filterEquals(list.get(i))) {
15363                                throw new IllegalArgumentException(
15364                                        "Sticky broadcast " + intent + " for user "
15365                                        + userId + " conflicts with existing global broadcast");
15366                            }
15367                        }
15368                    }
15369                }
15370            }
15371            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15372            if (stickies == null) {
15373                stickies = new ArrayMap<String, ArrayList<Intent>>();
15374                mStickyBroadcasts.put(userId, stickies);
15375            }
15376            ArrayList<Intent> list = stickies.get(intent.getAction());
15377            if (list == null) {
15378                list = new ArrayList<Intent>();
15379                stickies.put(intent.getAction(), list);
15380            }
15381            int N = list.size();
15382            int i;
15383            for (i=0; i<N; i++) {
15384                if (intent.filterEquals(list.get(i))) {
15385                    // This sticky already exists, replace it.
15386                    list.set(i, new Intent(intent));
15387                    break;
15388                }
15389            }
15390            if (i >= N) {
15391                list.add(new Intent(intent));
15392            }
15393        }
15394
15395        int[] users;
15396        if (userId == UserHandle.USER_ALL) {
15397            // Caller wants broadcast to go to all started users.
15398            users = mStartedUserArray;
15399        } else {
15400            // Caller wants broadcast to go to one specific user.
15401            users = new int[] {userId};
15402        }
15403
15404        // Figure out who all will receive this broadcast.
15405        List receivers = null;
15406        List<BroadcastFilter> registeredReceivers = null;
15407        // Need to resolve the intent to interested receivers...
15408        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15409                 == 0) {
15410            receivers = collectReceiverComponents(intent, resolvedType, users);
15411        }
15412        if (intent.getComponent() == null) {
15413            registeredReceivers = mReceiverResolver.queryIntent(intent,
15414                    resolvedType, false, userId);
15415        }
15416
15417        final boolean replacePending =
15418                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15419
15420        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15421                + " replacePending=" + replacePending);
15422
15423        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15424        if (!ordered && NR > 0) {
15425            // If we are not serializing this broadcast, then send the
15426            // registered receivers separately so they don't wait for the
15427            // components to be launched.
15428            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15429            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15430                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15431                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15432                    ordered, sticky, false, userId);
15433            if (DEBUG_BROADCAST) Slog.v(
15434                    TAG, "Enqueueing parallel broadcast " + r);
15435            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15436            if (!replaced) {
15437                queue.enqueueParallelBroadcastLocked(r);
15438                queue.scheduleBroadcastsLocked();
15439            }
15440            registeredReceivers = null;
15441            NR = 0;
15442        }
15443
15444        // Merge into one list.
15445        int ir = 0;
15446        if (receivers != null) {
15447            // A special case for PACKAGE_ADDED: do not allow the package
15448            // being added to see this broadcast.  This prevents them from
15449            // using this as a back door to get run as soon as they are
15450            // installed.  Maybe in the future we want to have a special install
15451            // broadcast or such for apps, but we'd like to deliberately make
15452            // this decision.
15453            String skipPackages[] = null;
15454            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15455                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15456                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15457                Uri data = intent.getData();
15458                if (data != null) {
15459                    String pkgName = data.getSchemeSpecificPart();
15460                    if (pkgName != null) {
15461                        skipPackages = new String[] { pkgName };
15462                    }
15463                }
15464            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15465                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15466            }
15467            if (skipPackages != null && (skipPackages.length > 0)) {
15468                for (String skipPackage : skipPackages) {
15469                    if (skipPackage != null) {
15470                        int NT = receivers.size();
15471                        for (int it=0; it<NT; it++) {
15472                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15473                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15474                                receivers.remove(it);
15475                                it--;
15476                                NT--;
15477                            }
15478                        }
15479                    }
15480                }
15481            }
15482
15483            int NT = receivers != null ? receivers.size() : 0;
15484            int it = 0;
15485            ResolveInfo curt = null;
15486            BroadcastFilter curr = null;
15487            while (it < NT && ir < NR) {
15488                if (curt == null) {
15489                    curt = (ResolveInfo)receivers.get(it);
15490                }
15491                if (curr == null) {
15492                    curr = registeredReceivers.get(ir);
15493                }
15494                if (curr.getPriority() >= curt.priority) {
15495                    // Insert this broadcast record into the final list.
15496                    receivers.add(it, curr);
15497                    ir++;
15498                    curr = null;
15499                    it++;
15500                    NT++;
15501                } else {
15502                    // Skip to the next ResolveInfo in the final list.
15503                    it++;
15504                    curt = null;
15505                }
15506            }
15507        }
15508        while (ir < NR) {
15509            if (receivers == null) {
15510                receivers = new ArrayList();
15511            }
15512            receivers.add(registeredReceivers.get(ir));
15513            ir++;
15514        }
15515
15516        if ((receivers != null && receivers.size() > 0)
15517                || resultTo != null) {
15518            BroadcastQueue queue = broadcastQueueForIntent(intent);
15519            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15520                    callerPackage, callingPid, callingUid, resolvedType,
15521                    requiredPermission, appOp, receivers, resultTo, resultCode,
15522                    resultData, map, ordered, sticky, false, userId);
15523            if (DEBUG_BROADCAST) Slog.v(
15524                    TAG, "Enqueueing ordered broadcast " + r
15525                    + ": prev had " + queue.mOrderedBroadcasts.size());
15526            if (DEBUG_BROADCAST) {
15527                int seq = r.intent.getIntExtra("seq", -1);
15528                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15529            }
15530            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15531            if (!replaced) {
15532                queue.enqueueOrderedBroadcastLocked(r);
15533                queue.scheduleBroadcastsLocked();
15534            }
15535        }
15536
15537        return ActivityManager.BROADCAST_SUCCESS;
15538    }
15539
15540    final Intent verifyBroadcastLocked(Intent intent) {
15541        // Refuse possible leaked file descriptors
15542        if (intent != null && intent.hasFileDescriptors() == true) {
15543            throw new IllegalArgumentException("File descriptors passed in Intent");
15544        }
15545
15546        int flags = intent.getFlags();
15547
15548        if (!mProcessesReady) {
15549            // if the caller really truly claims to know what they're doing, go
15550            // ahead and allow the broadcast without launching any receivers
15551            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15552                intent = new Intent(intent);
15553                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15554            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15555                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15556                        + " before boot completion");
15557                throw new IllegalStateException("Cannot broadcast before boot completed");
15558            }
15559        }
15560
15561        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15562            throw new IllegalArgumentException(
15563                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15564        }
15565
15566        return intent;
15567    }
15568
15569    public final int broadcastIntent(IApplicationThread caller,
15570            Intent intent, String resolvedType, IIntentReceiver resultTo,
15571            int resultCode, String resultData, Bundle map,
15572            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15573        enforceNotIsolatedCaller("broadcastIntent");
15574        synchronized(this) {
15575            intent = verifyBroadcastLocked(intent);
15576
15577            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15578            final int callingPid = Binder.getCallingPid();
15579            final int callingUid = Binder.getCallingUid();
15580            final long origId = Binder.clearCallingIdentity();
15581            int res = broadcastIntentLocked(callerApp,
15582                    callerApp != null ? callerApp.info.packageName : null,
15583                    intent, resolvedType, resultTo,
15584                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15585                    callingPid, callingUid, userId);
15586            Binder.restoreCallingIdentity(origId);
15587            return res;
15588        }
15589    }
15590
15591    int broadcastIntentInPackage(String packageName, int uid,
15592            Intent intent, String resolvedType, IIntentReceiver resultTo,
15593            int resultCode, String resultData, Bundle map,
15594            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15595        synchronized(this) {
15596            intent = verifyBroadcastLocked(intent);
15597
15598            final long origId = Binder.clearCallingIdentity();
15599            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15600                    resultTo, resultCode, resultData, map, requiredPermission,
15601                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15602            Binder.restoreCallingIdentity(origId);
15603            return res;
15604        }
15605    }
15606
15607    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15608        // Refuse possible leaked file descriptors
15609        if (intent != null && intent.hasFileDescriptors() == true) {
15610            throw new IllegalArgumentException("File descriptors passed in Intent");
15611        }
15612
15613        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15614                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15615
15616        synchronized(this) {
15617            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15618                    != PackageManager.PERMISSION_GRANTED) {
15619                String msg = "Permission Denial: unbroadcastIntent() from pid="
15620                        + Binder.getCallingPid()
15621                        + ", uid=" + Binder.getCallingUid()
15622                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15623                Slog.w(TAG, msg);
15624                throw new SecurityException(msg);
15625            }
15626            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15627            if (stickies != null) {
15628                ArrayList<Intent> list = stickies.get(intent.getAction());
15629                if (list != null) {
15630                    int N = list.size();
15631                    int i;
15632                    for (i=0; i<N; i++) {
15633                        if (intent.filterEquals(list.get(i))) {
15634                            list.remove(i);
15635                            break;
15636                        }
15637                    }
15638                    if (list.size() <= 0) {
15639                        stickies.remove(intent.getAction());
15640                    }
15641                }
15642                if (stickies.size() <= 0) {
15643                    mStickyBroadcasts.remove(userId);
15644                }
15645            }
15646        }
15647    }
15648
15649    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15650            String resultData, Bundle resultExtras, boolean resultAbort) {
15651        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15652        if (r == null) {
15653            Slog.w(TAG, "finishReceiver called but not found on queue");
15654            return false;
15655        }
15656
15657        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15658    }
15659
15660    void backgroundServicesFinishedLocked(int userId) {
15661        for (BroadcastQueue queue : mBroadcastQueues) {
15662            queue.backgroundServicesFinishedLocked(userId);
15663        }
15664    }
15665
15666    public void finishReceiver(IBinder who, int resultCode, String resultData,
15667            Bundle resultExtras, boolean resultAbort) {
15668        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15669
15670        // Refuse possible leaked file descriptors
15671        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15672            throw new IllegalArgumentException("File descriptors passed in Bundle");
15673        }
15674
15675        final long origId = Binder.clearCallingIdentity();
15676        try {
15677            boolean doNext = false;
15678            BroadcastRecord r;
15679
15680            synchronized(this) {
15681                r = broadcastRecordForReceiverLocked(who);
15682                if (r != null) {
15683                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15684                        resultData, resultExtras, resultAbort, true);
15685                }
15686            }
15687
15688            if (doNext) {
15689                r.queue.processNextBroadcast(false);
15690            }
15691            trimApplications();
15692        } finally {
15693            Binder.restoreCallingIdentity(origId);
15694        }
15695    }
15696
15697    // =========================================================
15698    // INSTRUMENTATION
15699    // =========================================================
15700
15701    public boolean startInstrumentation(ComponentName className,
15702            String profileFile, int flags, Bundle arguments,
15703            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15704            int userId, String abiOverride) {
15705        enforceNotIsolatedCaller("startInstrumentation");
15706        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15707                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15708        // Refuse possible leaked file descriptors
15709        if (arguments != null && arguments.hasFileDescriptors()) {
15710            throw new IllegalArgumentException("File descriptors passed in Bundle");
15711        }
15712
15713        synchronized(this) {
15714            InstrumentationInfo ii = null;
15715            ApplicationInfo ai = null;
15716            try {
15717                ii = mContext.getPackageManager().getInstrumentationInfo(
15718                    className, STOCK_PM_FLAGS);
15719                ai = AppGlobals.getPackageManager().getApplicationInfo(
15720                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15721            } catch (PackageManager.NameNotFoundException e) {
15722            } catch (RemoteException e) {
15723            }
15724            if (ii == null) {
15725                reportStartInstrumentationFailure(watcher, className,
15726                        "Unable to find instrumentation info for: " + className);
15727                return false;
15728            }
15729            if (ai == null) {
15730                reportStartInstrumentationFailure(watcher, className,
15731                        "Unable to find instrumentation target package: " + ii.targetPackage);
15732                return false;
15733            }
15734
15735            int match = mContext.getPackageManager().checkSignatures(
15736                    ii.targetPackage, ii.packageName);
15737            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15738                String msg = "Permission Denial: starting instrumentation "
15739                        + className + " from pid="
15740                        + Binder.getCallingPid()
15741                        + ", uid=" + Binder.getCallingPid()
15742                        + " not allowed because package " + ii.packageName
15743                        + " does not have a signature matching the target "
15744                        + ii.targetPackage;
15745                reportStartInstrumentationFailure(watcher, className, msg);
15746                throw new SecurityException(msg);
15747            }
15748
15749            final long origId = Binder.clearCallingIdentity();
15750            // Instrumentation can kill and relaunch even persistent processes
15751            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15752                    "start instr");
15753            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15754            app.instrumentationClass = className;
15755            app.instrumentationInfo = ai;
15756            app.instrumentationProfileFile = profileFile;
15757            app.instrumentationArguments = arguments;
15758            app.instrumentationWatcher = watcher;
15759            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15760            app.instrumentationResultClass = className;
15761            Binder.restoreCallingIdentity(origId);
15762        }
15763
15764        return true;
15765    }
15766
15767    /**
15768     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15769     * error to the logs, but if somebody is watching, send the report there too.  This enables
15770     * the "am" command to report errors with more information.
15771     *
15772     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15773     * @param cn The component name of the instrumentation.
15774     * @param report The error report.
15775     */
15776    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15777            ComponentName cn, String report) {
15778        Slog.w(TAG, report);
15779        try {
15780            if (watcher != null) {
15781                Bundle results = new Bundle();
15782                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15783                results.putString("Error", report);
15784                watcher.instrumentationStatus(cn, -1, results);
15785            }
15786        } catch (RemoteException e) {
15787            Slog.w(TAG, e);
15788        }
15789    }
15790
15791    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15792        if (app.instrumentationWatcher != null) {
15793            try {
15794                // NOTE:  IInstrumentationWatcher *must* be oneway here
15795                app.instrumentationWatcher.instrumentationFinished(
15796                    app.instrumentationClass,
15797                    resultCode,
15798                    results);
15799            } catch (RemoteException e) {
15800            }
15801        }
15802        if (app.instrumentationUiAutomationConnection != null) {
15803            try {
15804                app.instrumentationUiAutomationConnection.shutdown();
15805            } catch (RemoteException re) {
15806                /* ignore */
15807            }
15808            // Only a UiAutomation can set this flag and now that
15809            // it is finished we make sure it is reset to its default.
15810            mUserIsMonkey = false;
15811        }
15812        app.instrumentationWatcher = null;
15813        app.instrumentationUiAutomationConnection = null;
15814        app.instrumentationClass = null;
15815        app.instrumentationInfo = null;
15816        app.instrumentationProfileFile = null;
15817        app.instrumentationArguments = null;
15818
15819        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15820                "finished inst");
15821    }
15822
15823    public void finishInstrumentation(IApplicationThread target,
15824            int resultCode, Bundle results) {
15825        int userId = UserHandle.getCallingUserId();
15826        // Refuse possible leaked file descriptors
15827        if (results != null && results.hasFileDescriptors()) {
15828            throw new IllegalArgumentException("File descriptors passed in Intent");
15829        }
15830
15831        synchronized(this) {
15832            ProcessRecord app = getRecordForAppLocked(target);
15833            if (app == null) {
15834                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15835                return;
15836            }
15837            final long origId = Binder.clearCallingIdentity();
15838            finishInstrumentationLocked(app, resultCode, results);
15839            Binder.restoreCallingIdentity(origId);
15840        }
15841    }
15842
15843    // =========================================================
15844    // CONFIGURATION
15845    // =========================================================
15846
15847    public ConfigurationInfo getDeviceConfigurationInfo() {
15848        ConfigurationInfo config = new ConfigurationInfo();
15849        synchronized (this) {
15850            config.reqTouchScreen = mConfiguration.touchscreen;
15851            config.reqKeyboardType = mConfiguration.keyboard;
15852            config.reqNavigation = mConfiguration.navigation;
15853            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15854                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15855                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15856            }
15857            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15858                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15859                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15860            }
15861            config.reqGlEsVersion = GL_ES_VERSION;
15862        }
15863        return config;
15864    }
15865
15866    ActivityStack getFocusedStack() {
15867        return mStackSupervisor.getFocusedStack();
15868    }
15869
15870    public Configuration getConfiguration() {
15871        Configuration ci;
15872        synchronized(this) {
15873            ci = new Configuration(mConfiguration);
15874        }
15875        return ci;
15876    }
15877
15878    public void updatePersistentConfiguration(Configuration values) {
15879        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15880                "updateConfiguration()");
15881        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15882                "updateConfiguration()");
15883        if (values == null) {
15884            throw new NullPointerException("Configuration must not be null");
15885        }
15886
15887        synchronized(this) {
15888            final long origId = Binder.clearCallingIdentity();
15889            updateConfigurationLocked(values, null, true, false);
15890            Binder.restoreCallingIdentity(origId);
15891        }
15892    }
15893
15894    public void updateConfiguration(Configuration values) {
15895        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15896                "updateConfiguration()");
15897
15898        synchronized(this) {
15899            if (values == null && mWindowManager != null) {
15900                // sentinel: fetch the current configuration from the window manager
15901                values = mWindowManager.computeNewConfiguration();
15902            }
15903
15904            if (mWindowManager != null) {
15905                mProcessList.applyDisplaySize(mWindowManager);
15906            }
15907
15908            final long origId = Binder.clearCallingIdentity();
15909            if (values != null) {
15910                Settings.System.clearConfiguration(values);
15911            }
15912            updateConfigurationLocked(values, null, false, false);
15913            Binder.restoreCallingIdentity(origId);
15914        }
15915    }
15916
15917    /**
15918     * Do either or both things: (1) change the current configuration, and (2)
15919     * make sure the given activity is running with the (now) current
15920     * configuration.  Returns true if the activity has been left running, or
15921     * false if <var>starting</var> is being destroyed to match the new
15922     * configuration.
15923     * @param persistent TODO
15924     */
15925    boolean updateConfigurationLocked(Configuration values,
15926            ActivityRecord starting, boolean persistent, boolean initLocale) {
15927        int changes = 0;
15928
15929        if (values != null) {
15930            Configuration newConfig = new Configuration(mConfiguration);
15931            changes = newConfig.updateFrom(values);
15932            if (changes != 0) {
15933                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15934                    Slog.i(TAG, "Updating configuration to: " + values);
15935                }
15936
15937                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15938
15939                if (values.locale != null && !initLocale) {
15940                    saveLocaleLocked(values.locale,
15941                                     !values.locale.equals(mConfiguration.locale),
15942                                     values.userSetLocale);
15943                }
15944
15945                mConfigurationSeq++;
15946                if (mConfigurationSeq <= 0) {
15947                    mConfigurationSeq = 1;
15948                }
15949                newConfig.seq = mConfigurationSeq;
15950                mConfiguration = newConfig;
15951                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15952                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15953                //mUsageStatsService.noteStartConfig(newConfig);
15954
15955                final Configuration configCopy = new Configuration(mConfiguration);
15956
15957                // TODO: If our config changes, should we auto dismiss any currently
15958                // showing dialogs?
15959                mShowDialogs = shouldShowDialogs(newConfig);
15960
15961                AttributeCache ac = AttributeCache.instance();
15962                if (ac != null) {
15963                    ac.updateConfiguration(configCopy);
15964                }
15965
15966                // Make sure all resources in our process are updated
15967                // right now, so that anyone who is going to retrieve
15968                // resource values after we return will be sure to get
15969                // the new ones.  This is especially important during
15970                // boot, where the first config change needs to guarantee
15971                // all resources have that config before following boot
15972                // code is executed.
15973                mSystemThread.applyConfigurationToResources(configCopy);
15974
15975                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15976                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15977                    msg.obj = new Configuration(configCopy);
15978                    mHandler.sendMessage(msg);
15979                }
15980
15981                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15982                    ProcessRecord app = mLruProcesses.get(i);
15983                    try {
15984                        if (app.thread != null) {
15985                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15986                                    + app.processName + " new config " + mConfiguration);
15987                            app.thread.scheduleConfigurationChanged(configCopy);
15988                        }
15989                    } catch (Exception e) {
15990                    }
15991                }
15992                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15993                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15994                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15995                        | Intent.FLAG_RECEIVER_FOREGROUND);
15996                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15997                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15998                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15999                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16000                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16001                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16002                    broadcastIntentLocked(null, null, intent,
16003                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16004                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16005                }
16006            }
16007        }
16008
16009        boolean kept = true;
16010        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16011        // mainStack is null during startup.
16012        if (mainStack != null) {
16013            if (changes != 0 && starting == null) {
16014                // If the configuration changed, and the caller is not already
16015                // in the process of starting an activity, then find the top
16016                // activity to check if its configuration needs to change.
16017                starting = mainStack.topRunningActivityLocked(null);
16018            }
16019
16020            if (starting != null) {
16021                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16022                // And we need to make sure at this point that all other activities
16023                // are made visible with the correct configuration.
16024                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16025            }
16026        }
16027
16028        if (values != null && mWindowManager != null) {
16029            mWindowManager.setNewConfiguration(mConfiguration);
16030        }
16031
16032        return kept;
16033    }
16034
16035    /**
16036     * Decide based on the configuration whether we should shouw the ANR,
16037     * crash, etc dialogs.  The idea is that if there is no affordnace to
16038     * press the on-screen buttons, we shouldn't show the dialog.
16039     *
16040     * A thought: SystemUI might also want to get told about this, the Power
16041     * dialog / global actions also might want different behaviors.
16042     */
16043    private static final boolean shouldShowDialogs(Configuration config) {
16044        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16045                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16046    }
16047
16048    /**
16049     * Save the locale.  You must be inside a synchronized (this) block.
16050     */
16051    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16052        if(isDiff) {
16053            SystemProperties.set("user.language", l.getLanguage());
16054            SystemProperties.set("user.region", l.getCountry());
16055        }
16056
16057        if(isPersist) {
16058            SystemProperties.set("persist.sys.language", l.getLanguage());
16059            SystemProperties.set("persist.sys.country", l.getCountry());
16060            SystemProperties.set("persist.sys.localevar", l.getVariant());
16061        }
16062    }
16063
16064    @Override
16065    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16066        synchronized (this) {
16067            ActivityRecord srec = ActivityRecord.forToken(token);
16068            if (srec.task != null && srec.task.stack != null) {
16069                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16070            }
16071        }
16072        return false;
16073    }
16074
16075    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16076            Intent resultData) {
16077
16078        synchronized (this) {
16079            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16080            if (stack != null) {
16081                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16082            }
16083            return false;
16084        }
16085    }
16086
16087    public int getLaunchedFromUid(IBinder activityToken) {
16088        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16089        if (srec == null) {
16090            return -1;
16091        }
16092        return srec.launchedFromUid;
16093    }
16094
16095    public String getLaunchedFromPackage(IBinder activityToken) {
16096        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16097        if (srec == null) {
16098            return null;
16099        }
16100        return srec.launchedFromPackage;
16101    }
16102
16103    // =========================================================
16104    // LIFETIME MANAGEMENT
16105    // =========================================================
16106
16107    // Returns which broadcast queue the app is the current [or imminent] receiver
16108    // on, or 'null' if the app is not an active broadcast recipient.
16109    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16110        BroadcastRecord r = app.curReceiver;
16111        if (r != null) {
16112            return r.queue;
16113        }
16114
16115        // It's not the current receiver, but it might be starting up to become one
16116        synchronized (this) {
16117            for (BroadcastQueue queue : mBroadcastQueues) {
16118                r = queue.mPendingBroadcast;
16119                if (r != null && r.curApp == app) {
16120                    // found it; report which queue it's in
16121                    return queue;
16122                }
16123            }
16124        }
16125
16126        return null;
16127    }
16128
16129    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16130            boolean doingAll, long now) {
16131        if (mAdjSeq == app.adjSeq) {
16132            // This adjustment has already been computed.
16133            return app.curRawAdj;
16134        }
16135
16136        if (app.thread == null) {
16137            app.adjSeq = mAdjSeq;
16138            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16139            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16140            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16141        }
16142
16143        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16144        app.adjSource = null;
16145        app.adjTarget = null;
16146        app.empty = false;
16147        app.cached = false;
16148
16149        final int activitiesSize = app.activities.size();
16150
16151        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16152            // The max adjustment doesn't allow this app to be anything
16153            // below foreground, so it is not worth doing work for it.
16154            app.adjType = "fixed";
16155            app.adjSeq = mAdjSeq;
16156            app.curRawAdj = app.maxAdj;
16157            app.foregroundActivities = false;
16158            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16159            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16160            // System processes can do UI, and when they do we want to have
16161            // them trim their memory after the user leaves the UI.  To
16162            // facilitate this, here we need to determine whether or not it
16163            // is currently showing UI.
16164            app.systemNoUi = true;
16165            if (app == TOP_APP) {
16166                app.systemNoUi = false;
16167            } else if (activitiesSize > 0) {
16168                for (int j = 0; j < activitiesSize; j++) {
16169                    final ActivityRecord r = app.activities.get(j);
16170                    if (r.visible) {
16171                        app.systemNoUi = false;
16172                    }
16173                }
16174            }
16175            if (!app.systemNoUi) {
16176                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16177            }
16178            return (app.curAdj=app.maxAdj);
16179        }
16180
16181        app.systemNoUi = false;
16182
16183        // Determine the importance of the process, starting with most
16184        // important to least, and assign an appropriate OOM adjustment.
16185        int adj;
16186        int schedGroup;
16187        int procState;
16188        boolean foregroundActivities = false;
16189        BroadcastQueue queue;
16190        if (app == TOP_APP) {
16191            // The last app on the list is the foreground app.
16192            adj = ProcessList.FOREGROUND_APP_ADJ;
16193            schedGroup = Process.THREAD_GROUP_DEFAULT;
16194            app.adjType = "top-activity";
16195            foregroundActivities = true;
16196            procState = ActivityManager.PROCESS_STATE_TOP;
16197        } else if (app.instrumentationClass != null) {
16198            // Don't want to kill running instrumentation.
16199            adj = ProcessList.FOREGROUND_APP_ADJ;
16200            schedGroup = Process.THREAD_GROUP_DEFAULT;
16201            app.adjType = "instrumentation";
16202            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16203        } else if ((queue = isReceivingBroadcast(app)) != null) {
16204            // An app that is currently receiving a broadcast also
16205            // counts as being in the foreground for OOM killer purposes.
16206            // It's placed in a sched group based on the nature of the
16207            // broadcast as reflected by which queue it's active in.
16208            adj = ProcessList.FOREGROUND_APP_ADJ;
16209            schedGroup = (queue == mFgBroadcastQueue)
16210                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16211            app.adjType = "broadcast";
16212            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16213        } else if (app.executingServices.size() > 0) {
16214            // An app that is currently executing a service callback also
16215            // counts as being in the foreground.
16216            adj = ProcessList.FOREGROUND_APP_ADJ;
16217            schedGroup = app.execServicesFg ?
16218                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16219            app.adjType = "exec-service";
16220            procState = ActivityManager.PROCESS_STATE_SERVICE;
16221            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16222        } else {
16223            // As far as we know the process is empty.  We may change our mind later.
16224            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16225            // At this point we don't actually know the adjustment.  Use the cached adj
16226            // value that the caller wants us to.
16227            adj = cachedAdj;
16228            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16229            app.cached = true;
16230            app.empty = true;
16231            app.adjType = "cch-empty";
16232        }
16233
16234        // Examine all activities if not already foreground.
16235        if (!foregroundActivities && activitiesSize > 0) {
16236            for (int j = 0; j < activitiesSize; j++) {
16237                final ActivityRecord r = app.activities.get(j);
16238                if (r.app != app) {
16239                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16240                            + app + "?!?");
16241                    continue;
16242                }
16243                if (r.visible) {
16244                    // App has a visible activity; only upgrade adjustment.
16245                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16246                        adj = ProcessList.VISIBLE_APP_ADJ;
16247                        app.adjType = "visible";
16248                    }
16249                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16250                        procState = ActivityManager.PROCESS_STATE_TOP;
16251                    }
16252                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16253                    app.cached = false;
16254                    app.empty = false;
16255                    foregroundActivities = true;
16256                    break;
16257                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16258                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16259                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16260                        app.adjType = "pausing";
16261                    }
16262                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16263                        procState = ActivityManager.PROCESS_STATE_TOP;
16264                    }
16265                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16266                    app.cached = false;
16267                    app.empty = false;
16268                    foregroundActivities = true;
16269                } else if (r.state == ActivityState.STOPPING) {
16270                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16271                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16272                        app.adjType = "stopping";
16273                    }
16274                    // For the process state, we will at this point consider the
16275                    // process to be cached.  It will be cached either as an activity
16276                    // or empty depending on whether the activity is finishing.  We do
16277                    // this so that we can treat the process as cached for purposes of
16278                    // memory trimming (determing current memory level, trim command to
16279                    // send to process) since there can be an arbitrary number of stopping
16280                    // processes and they should soon all go into the cached state.
16281                    if (!r.finishing) {
16282                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16283                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16284                        }
16285                    }
16286                    app.cached = false;
16287                    app.empty = false;
16288                    foregroundActivities = true;
16289                } else {
16290                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16291                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16292                        app.adjType = "cch-act";
16293                    }
16294                }
16295            }
16296        }
16297
16298        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16299            if (app.foregroundServices) {
16300                // The user is aware of this app, so make it visible.
16301                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16302                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16303                app.cached = false;
16304                app.adjType = "fg-service";
16305                schedGroup = Process.THREAD_GROUP_DEFAULT;
16306            } else if (app.forcingToForeground != null) {
16307                // The user is aware of this app, so make it visible.
16308                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16309                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16310                app.cached = false;
16311                app.adjType = "force-fg";
16312                app.adjSource = app.forcingToForeground;
16313                schedGroup = Process.THREAD_GROUP_DEFAULT;
16314            }
16315        }
16316
16317        if (app == mHeavyWeightProcess) {
16318            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16319                // We don't want to kill the current heavy-weight process.
16320                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16321                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16322                app.cached = false;
16323                app.adjType = "heavy";
16324            }
16325            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16326                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16327            }
16328        }
16329
16330        if (app == mHomeProcess) {
16331            if (adj > ProcessList.HOME_APP_ADJ) {
16332                // This process is hosting what we currently consider to be the
16333                // home app, so we don't want to let it go into the background.
16334                adj = ProcessList.HOME_APP_ADJ;
16335                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16336                app.cached = false;
16337                app.adjType = "home";
16338            }
16339            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16340                procState = ActivityManager.PROCESS_STATE_HOME;
16341            }
16342        }
16343
16344        if (app == mPreviousProcess && app.activities.size() > 0) {
16345            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16346                // This was the previous process that showed UI to the user.
16347                // We want to try to keep it around more aggressively, to give
16348                // a good experience around switching between two apps.
16349                adj = ProcessList.PREVIOUS_APP_ADJ;
16350                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16351                app.cached = false;
16352                app.adjType = "previous";
16353            }
16354            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16355                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16356            }
16357        }
16358
16359        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16360                + " reason=" + app.adjType);
16361
16362        // By default, we use the computed adjustment.  It may be changed if
16363        // there are applications dependent on our services or providers, but
16364        // this gives us a baseline and makes sure we don't get into an
16365        // infinite recursion.
16366        app.adjSeq = mAdjSeq;
16367        app.curRawAdj = adj;
16368        app.hasStartedServices = false;
16369
16370        if (mBackupTarget != null && app == mBackupTarget.app) {
16371            // If possible we want to avoid killing apps while they're being backed up
16372            if (adj > ProcessList.BACKUP_APP_ADJ) {
16373                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16374                adj = ProcessList.BACKUP_APP_ADJ;
16375                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16376                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16377                }
16378                app.adjType = "backup";
16379                app.cached = false;
16380            }
16381            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16382                procState = ActivityManager.PROCESS_STATE_BACKUP;
16383            }
16384        }
16385
16386        boolean mayBeTop = false;
16387
16388        for (int is = app.services.size()-1;
16389                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16390                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16391                        || procState > ActivityManager.PROCESS_STATE_TOP);
16392                is--) {
16393            ServiceRecord s = app.services.valueAt(is);
16394            if (s.startRequested) {
16395                app.hasStartedServices = true;
16396                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16397                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16398                }
16399                if (app.hasShownUi && app != mHomeProcess) {
16400                    // If this process has shown some UI, let it immediately
16401                    // go to the LRU list because it may be pretty heavy with
16402                    // UI stuff.  We'll tag it with a label just to help
16403                    // debug and understand what is going on.
16404                    if (adj > ProcessList.SERVICE_ADJ) {
16405                        app.adjType = "cch-started-ui-services";
16406                    }
16407                } else {
16408                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16409                        // This service has seen some activity within
16410                        // recent memory, so we will keep its process ahead
16411                        // of the background processes.
16412                        if (adj > ProcessList.SERVICE_ADJ) {
16413                            adj = ProcessList.SERVICE_ADJ;
16414                            app.adjType = "started-services";
16415                            app.cached = false;
16416                        }
16417                    }
16418                    // If we have let the service slide into the background
16419                    // state, still have some text describing what it is doing
16420                    // even though the service no longer has an impact.
16421                    if (adj > ProcessList.SERVICE_ADJ) {
16422                        app.adjType = "cch-started-services";
16423                    }
16424                }
16425            }
16426            for (int conni = s.connections.size()-1;
16427                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16428                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16429                            || procState > ActivityManager.PROCESS_STATE_TOP);
16430                    conni--) {
16431                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16432                for (int i = 0;
16433                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16434                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16435                                || procState > ActivityManager.PROCESS_STATE_TOP);
16436                        i++) {
16437                    // XXX should compute this based on the max of
16438                    // all connected clients.
16439                    ConnectionRecord cr = clist.get(i);
16440                    if (cr.binding.client == app) {
16441                        // Binding to ourself is not interesting.
16442                        continue;
16443                    }
16444                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16445                        ProcessRecord client = cr.binding.client;
16446                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16447                                TOP_APP, doingAll, now);
16448                        int clientProcState = client.curProcState;
16449                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16450                            // If the other app is cached for any reason, for purposes here
16451                            // we are going to consider it empty.  The specific cached state
16452                            // doesn't propagate except under certain conditions.
16453                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16454                        }
16455                        String adjType = null;
16456                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16457                            // Not doing bind OOM management, so treat
16458                            // this guy more like a started service.
16459                            if (app.hasShownUi && app != mHomeProcess) {
16460                                // If this process has shown some UI, let it immediately
16461                                // go to the LRU list because it may be pretty heavy with
16462                                // UI stuff.  We'll tag it with a label just to help
16463                                // debug and understand what is going on.
16464                                if (adj > clientAdj) {
16465                                    adjType = "cch-bound-ui-services";
16466                                }
16467                                app.cached = false;
16468                                clientAdj = adj;
16469                                clientProcState = procState;
16470                            } else {
16471                                if (now >= (s.lastActivity
16472                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16473                                    // This service has not seen activity within
16474                                    // recent memory, so allow it to drop to the
16475                                    // LRU list if there is no other reason to keep
16476                                    // it around.  We'll also tag it with a label just
16477                                    // to help debug and undertand what is going on.
16478                                    if (adj > clientAdj) {
16479                                        adjType = "cch-bound-services";
16480                                    }
16481                                    clientAdj = adj;
16482                                }
16483                            }
16484                        }
16485                        if (adj > clientAdj) {
16486                            // If this process has recently shown UI, and
16487                            // the process that is binding to it is less
16488                            // important than being visible, then we don't
16489                            // care about the binding as much as we care
16490                            // about letting this process get into the LRU
16491                            // list to be killed and restarted if needed for
16492                            // memory.
16493                            if (app.hasShownUi && app != mHomeProcess
16494                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16495                                adjType = "cch-bound-ui-services";
16496                            } else {
16497                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16498                                        |Context.BIND_IMPORTANT)) != 0) {
16499                                    adj = clientAdj;
16500                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16501                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16502                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16503                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16504                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16505                                    adj = clientAdj;
16506                                } else {
16507                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16508                                        adj = ProcessList.VISIBLE_APP_ADJ;
16509                                    }
16510                                }
16511                                if (!client.cached) {
16512                                    app.cached = false;
16513                                }
16514                                adjType = "service";
16515                            }
16516                        }
16517                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16518                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16519                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16520                            }
16521                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16522                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16523                                    // Special handling of clients who are in the top state.
16524                                    // We *may* want to consider this process to be in the
16525                                    // top state as well, but only if there is not another
16526                                    // reason for it to be running.  Being on the top is a
16527                                    // special state, meaning you are specifically running
16528                                    // for the current top app.  If the process is already
16529                                    // running in the background for some other reason, it
16530                                    // is more important to continue considering it to be
16531                                    // in the background state.
16532                                    mayBeTop = true;
16533                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16534                                } else {
16535                                    // Special handling for above-top states (persistent
16536                                    // processes).  These should not bring the current process
16537                                    // into the top state, since they are not on top.  Instead
16538                                    // give them the best state after that.
16539                                    clientProcState =
16540                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16541                                }
16542                            }
16543                        } else {
16544                            if (clientProcState <
16545                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16546                                clientProcState =
16547                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16548                            }
16549                        }
16550                        if (procState > clientProcState) {
16551                            procState = clientProcState;
16552                        }
16553                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16554                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16555                            app.pendingUiClean = true;
16556                        }
16557                        if (adjType != null) {
16558                            app.adjType = adjType;
16559                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16560                                    .REASON_SERVICE_IN_USE;
16561                            app.adjSource = cr.binding.client;
16562                            app.adjSourceProcState = clientProcState;
16563                            app.adjTarget = s.name;
16564                        }
16565                    }
16566                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16567                        app.treatLikeActivity = true;
16568                    }
16569                    final ActivityRecord a = cr.activity;
16570                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16571                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16572                                (a.visible || a.state == ActivityState.RESUMED
16573                                 || a.state == ActivityState.PAUSING)) {
16574                            adj = ProcessList.FOREGROUND_APP_ADJ;
16575                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16576                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16577                            }
16578                            app.cached = false;
16579                            app.adjType = "service";
16580                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16581                                    .REASON_SERVICE_IN_USE;
16582                            app.adjSource = a;
16583                            app.adjSourceProcState = procState;
16584                            app.adjTarget = s.name;
16585                        }
16586                    }
16587                }
16588            }
16589        }
16590
16591        for (int provi = app.pubProviders.size()-1;
16592                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16593                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16594                        || procState > ActivityManager.PROCESS_STATE_TOP);
16595                provi--) {
16596            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16597            for (int i = cpr.connections.size()-1;
16598                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16599                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16600                            || procState > ActivityManager.PROCESS_STATE_TOP);
16601                    i--) {
16602                ContentProviderConnection conn = cpr.connections.get(i);
16603                ProcessRecord client = conn.client;
16604                if (client == app) {
16605                    // Being our own client is not interesting.
16606                    continue;
16607                }
16608                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16609                int clientProcState = client.curProcState;
16610                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16611                    // If the other app is cached for any reason, for purposes here
16612                    // we are going to consider it empty.
16613                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16614                }
16615                if (adj > clientAdj) {
16616                    if (app.hasShownUi && app != mHomeProcess
16617                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16618                        app.adjType = "cch-ui-provider";
16619                    } else {
16620                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16621                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16622                        app.adjType = "provider";
16623                    }
16624                    app.cached &= client.cached;
16625                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16626                            .REASON_PROVIDER_IN_USE;
16627                    app.adjSource = client;
16628                    app.adjSourceProcState = clientProcState;
16629                    app.adjTarget = cpr.name;
16630                }
16631                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16632                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16633                        // Special handling of clients who are in the top state.
16634                        // We *may* want to consider this process to be in the
16635                        // top state as well, but only if there is not another
16636                        // reason for it to be running.  Being on the top is a
16637                        // special state, meaning you are specifically running
16638                        // for the current top app.  If the process is already
16639                        // running in the background for some other reason, it
16640                        // is more important to continue considering it to be
16641                        // in the background state.
16642                        mayBeTop = true;
16643                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16644                    } else {
16645                        // Special handling for above-top states (persistent
16646                        // processes).  These should not bring the current process
16647                        // into the top state, since they are not on top.  Instead
16648                        // give them the best state after that.
16649                        clientProcState =
16650                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16651                    }
16652                }
16653                if (procState > clientProcState) {
16654                    procState = clientProcState;
16655                }
16656                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16657                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16658                }
16659            }
16660            // If the provider has external (non-framework) process
16661            // dependencies, ensure that its adjustment is at least
16662            // FOREGROUND_APP_ADJ.
16663            if (cpr.hasExternalProcessHandles()) {
16664                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16665                    adj = ProcessList.FOREGROUND_APP_ADJ;
16666                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16667                    app.cached = false;
16668                    app.adjType = "provider";
16669                    app.adjTarget = cpr.name;
16670                }
16671                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16672                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16673                }
16674            }
16675        }
16676
16677        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16678            // A client of one of our services or providers is in the top state.  We
16679            // *may* want to be in the top state, but not if we are already running in
16680            // the background for some other reason.  For the decision here, we are going
16681            // to pick out a few specific states that we want to remain in when a client
16682            // is top (states that tend to be longer-term) and otherwise allow it to go
16683            // to the top state.
16684            switch (procState) {
16685                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16686                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16687                case ActivityManager.PROCESS_STATE_SERVICE:
16688                    // These all are longer-term states, so pull them up to the top
16689                    // of the background states, but not all the way to the top state.
16690                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16691                    break;
16692                default:
16693                    // Otherwise, top is a better choice, so take it.
16694                    procState = ActivityManager.PROCESS_STATE_TOP;
16695                    break;
16696            }
16697        }
16698
16699        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16700            if (app.hasClientActivities) {
16701                // This is a cached process, but with client activities.  Mark it so.
16702                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16703                app.adjType = "cch-client-act";
16704            } else if (app.treatLikeActivity) {
16705                // This is a cached process, but somebody wants us to treat it like it has
16706                // an activity, okay!
16707                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16708                app.adjType = "cch-as-act";
16709            }
16710        }
16711
16712        if (adj == ProcessList.SERVICE_ADJ) {
16713            if (doingAll) {
16714                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16715                mNewNumServiceProcs++;
16716                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16717                if (!app.serviceb) {
16718                    // This service isn't far enough down on the LRU list to
16719                    // normally be a B service, but if we are low on RAM and it
16720                    // is large we want to force it down since we would prefer to
16721                    // keep launcher over it.
16722                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16723                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16724                        app.serviceHighRam = true;
16725                        app.serviceb = true;
16726                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16727                    } else {
16728                        mNewNumAServiceProcs++;
16729                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16730                    }
16731                } else {
16732                    app.serviceHighRam = false;
16733                }
16734            }
16735            if (app.serviceb) {
16736                adj = ProcessList.SERVICE_B_ADJ;
16737            }
16738        }
16739
16740        app.curRawAdj = adj;
16741
16742        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16743        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16744        if (adj > app.maxAdj) {
16745            adj = app.maxAdj;
16746            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16747                schedGroup = Process.THREAD_GROUP_DEFAULT;
16748            }
16749        }
16750
16751        // Do final modification to adj.  Everything we do between here and applying
16752        // the final setAdj must be done in this function, because we will also use
16753        // it when computing the final cached adj later.  Note that we don't need to
16754        // worry about this for max adj above, since max adj will always be used to
16755        // keep it out of the cached vaues.
16756        app.curAdj = app.modifyRawOomAdj(adj);
16757        app.curSchedGroup = schedGroup;
16758        app.curProcState = procState;
16759        app.foregroundActivities = foregroundActivities;
16760
16761        return app.curRawAdj;
16762    }
16763
16764    /**
16765     * Schedule PSS collection of a process.
16766     */
16767    void requestPssLocked(ProcessRecord proc, int procState) {
16768        if (mPendingPssProcesses.contains(proc)) {
16769            return;
16770        }
16771        if (mPendingPssProcesses.size() == 0) {
16772            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16773        }
16774        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16775        proc.pssProcState = procState;
16776        mPendingPssProcesses.add(proc);
16777    }
16778
16779    /**
16780     * Schedule PSS collection of all processes.
16781     */
16782    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16783        if (!always) {
16784            if (now < (mLastFullPssTime +
16785                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16786                return;
16787            }
16788        }
16789        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16790        mLastFullPssTime = now;
16791        mFullPssPending = true;
16792        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16793        mPendingPssProcesses.clear();
16794        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16795            ProcessRecord app = mLruProcesses.get(i);
16796            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16797                app.pssProcState = app.setProcState;
16798                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16799                        isSleeping(), now);
16800                mPendingPssProcesses.add(app);
16801            }
16802        }
16803        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16804    }
16805
16806    /**
16807     * Ask a given process to GC right now.
16808     */
16809    final void performAppGcLocked(ProcessRecord app) {
16810        try {
16811            app.lastRequestedGc = SystemClock.uptimeMillis();
16812            if (app.thread != null) {
16813                if (app.reportLowMemory) {
16814                    app.reportLowMemory = false;
16815                    app.thread.scheduleLowMemory();
16816                } else {
16817                    app.thread.processInBackground();
16818                }
16819            }
16820        } catch (Exception e) {
16821            // whatever.
16822        }
16823    }
16824
16825    /**
16826     * Returns true if things are idle enough to perform GCs.
16827     */
16828    private final boolean canGcNowLocked() {
16829        boolean processingBroadcasts = false;
16830        for (BroadcastQueue q : mBroadcastQueues) {
16831            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16832                processingBroadcasts = true;
16833            }
16834        }
16835        return !processingBroadcasts
16836                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16837    }
16838
16839    /**
16840     * Perform GCs on all processes that are waiting for it, but only
16841     * if things are idle.
16842     */
16843    final void performAppGcsLocked() {
16844        final int N = mProcessesToGc.size();
16845        if (N <= 0) {
16846            return;
16847        }
16848        if (canGcNowLocked()) {
16849            while (mProcessesToGc.size() > 0) {
16850                ProcessRecord proc = mProcessesToGc.remove(0);
16851                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16852                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16853                            <= SystemClock.uptimeMillis()) {
16854                        // To avoid spamming the system, we will GC processes one
16855                        // at a time, waiting a few seconds between each.
16856                        performAppGcLocked(proc);
16857                        scheduleAppGcsLocked();
16858                        return;
16859                    } else {
16860                        // It hasn't been long enough since we last GCed this
16861                        // process...  put it in the list to wait for its time.
16862                        addProcessToGcListLocked(proc);
16863                        break;
16864                    }
16865                }
16866            }
16867
16868            scheduleAppGcsLocked();
16869        }
16870    }
16871
16872    /**
16873     * If all looks good, perform GCs on all processes waiting for them.
16874     */
16875    final void performAppGcsIfAppropriateLocked() {
16876        if (canGcNowLocked()) {
16877            performAppGcsLocked();
16878            return;
16879        }
16880        // Still not idle, wait some more.
16881        scheduleAppGcsLocked();
16882    }
16883
16884    /**
16885     * Schedule the execution of all pending app GCs.
16886     */
16887    final void scheduleAppGcsLocked() {
16888        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16889
16890        if (mProcessesToGc.size() > 0) {
16891            // Schedule a GC for the time to the next process.
16892            ProcessRecord proc = mProcessesToGc.get(0);
16893            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16894
16895            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16896            long now = SystemClock.uptimeMillis();
16897            if (when < (now+GC_TIMEOUT)) {
16898                when = now + GC_TIMEOUT;
16899            }
16900            mHandler.sendMessageAtTime(msg, when);
16901        }
16902    }
16903
16904    /**
16905     * Add a process to the array of processes waiting to be GCed.  Keeps the
16906     * list in sorted order by the last GC time.  The process can't already be
16907     * on the list.
16908     */
16909    final void addProcessToGcListLocked(ProcessRecord proc) {
16910        boolean added = false;
16911        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16912            if (mProcessesToGc.get(i).lastRequestedGc <
16913                    proc.lastRequestedGc) {
16914                added = true;
16915                mProcessesToGc.add(i+1, proc);
16916                break;
16917            }
16918        }
16919        if (!added) {
16920            mProcessesToGc.add(0, proc);
16921        }
16922    }
16923
16924    /**
16925     * Set up to ask a process to GC itself.  This will either do it
16926     * immediately, or put it on the list of processes to gc the next
16927     * time things are idle.
16928     */
16929    final void scheduleAppGcLocked(ProcessRecord app) {
16930        long now = SystemClock.uptimeMillis();
16931        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16932            return;
16933        }
16934        if (!mProcessesToGc.contains(app)) {
16935            addProcessToGcListLocked(app);
16936            scheduleAppGcsLocked();
16937        }
16938    }
16939
16940    final void checkExcessivePowerUsageLocked(boolean doKills) {
16941        updateCpuStatsNow();
16942
16943        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16944        boolean doWakeKills = doKills;
16945        boolean doCpuKills = doKills;
16946        if (mLastPowerCheckRealtime == 0) {
16947            doWakeKills = false;
16948        }
16949        if (mLastPowerCheckUptime == 0) {
16950            doCpuKills = false;
16951        }
16952        if (stats.isScreenOn()) {
16953            doWakeKills = false;
16954        }
16955        final long curRealtime = SystemClock.elapsedRealtime();
16956        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16957        final long curUptime = SystemClock.uptimeMillis();
16958        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16959        mLastPowerCheckRealtime = curRealtime;
16960        mLastPowerCheckUptime = curUptime;
16961        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16962            doWakeKills = false;
16963        }
16964        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16965            doCpuKills = false;
16966        }
16967        int i = mLruProcesses.size();
16968        while (i > 0) {
16969            i--;
16970            ProcessRecord app = mLruProcesses.get(i);
16971            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16972                long wtime;
16973                synchronized (stats) {
16974                    wtime = stats.getProcessWakeTime(app.info.uid,
16975                            app.pid, curRealtime);
16976                }
16977                long wtimeUsed = wtime - app.lastWakeTime;
16978                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16979                if (DEBUG_POWER) {
16980                    StringBuilder sb = new StringBuilder(128);
16981                    sb.append("Wake for ");
16982                    app.toShortString(sb);
16983                    sb.append(": over ");
16984                    TimeUtils.formatDuration(realtimeSince, sb);
16985                    sb.append(" used ");
16986                    TimeUtils.formatDuration(wtimeUsed, sb);
16987                    sb.append(" (");
16988                    sb.append((wtimeUsed*100)/realtimeSince);
16989                    sb.append("%)");
16990                    Slog.i(TAG, sb.toString());
16991                    sb.setLength(0);
16992                    sb.append("CPU for ");
16993                    app.toShortString(sb);
16994                    sb.append(": over ");
16995                    TimeUtils.formatDuration(uptimeSince, sb);
16996                    sb.append(" used ");
16997                    TimeUtils.formatDuration(cputimeUsed, sb);
16998                    sb.append(" (");
16999                    sb.append((cputimeUsed*100)/uptimeSince);
17000                    sb.append("%)");
17001                    Slog.i(TAG, sb.toString());
17002                }
17003                // If a process has held a wake lock for more
17004                // than 50% of the time during this period,
17005                // that sounds bad.  Kill!
17006                if (doWakeKills && realtimeSince > 0
17007                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17008                    synchronized (stats) {
17009                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17010                                realtimeSince, wtimeUsed);
17011                    }
17012                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17013                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17014                } else if (doCpuKills && uptimeSince > 0
17015                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17016                    synchronized (stats) {
17017                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17018                                uptimeSince, cputimeUsed);
17019                    }
17020                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17021                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17022                } else {
17023                    app.lastWakeTime = wtime;
17024                    app.lastCpuTime = app.curCpuTime;
17025                }
17026            }
17027        }
17028    }
17029
17030    private final boolean applyOomAdjLocked(ProcessRecord app,
17031            ProcessRecord TOP_APP, boolean doingAll, long now) {
17032        boolean success = true;
17033
17034        if (app.curRawAdj != app.setRawAdj) {
17035            app.setRawAdj = app.curRawAdj;
17036        }
17037
17038        int changes = 0;
17039
17040        if (app.curAdj != app.setAdj) {
17041            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17042            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17043                TAG, "Set " + app.pid + " " + app.processName +
17044                " adj " + app.curAdj + ": " + app.adjType);
17045            app.setAdj = app.curAdj;
17046        }
17047
17048        if (app.setSchedGroup != app.curSchedGroup) {
17049            app.setSchedGroup = app.curSchedGroup;
17050            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17051                    "Setting process group of " + app.processName
17052                    + " to " + app.curSchedGroup);
17053            if (app.waitingToKill != null &&
17054                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17055                app.kill(app.waitingToKill, true);
17056                success = false;
17057            } else {
17058                if (true) {
17059                    long oldId = Binder.clearCallingIdentity();
17060                    try {
17061                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17062                    } catch (Exception e) {
17063                        Slog.w(TAG, "Failed setting process group of " + app.pid
17064                                + " to " + app.curSchedGroup);
17065                        e.printStackTrace();
17066                    } finally {
17067                        Binder.restoreCallingIdentity(oldId);
17068                    }
17069                } else {
17070                    if (app.thread != null) {
17071                        try {
17072                            app.thread.setSchedulingGroup(app.curSchedGroup);
17073                        } catch (RemoteException e) {
17074                        }
17075                    }
17076                }
17077                Process.setSwappiness(app.pid,
17078                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17079            }
17080        }
17081        if (app.repForegroundActivities != app.foregroundActivities) {
17082            app.repForegroundActivities = app.foregroundActivities;
17083            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17084        }
17085        if (app.repProcState != app.curProcState) {
17086            app.repProcState = app.curProcState;
17087            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17088            if (app.thread != null) {
17089                try {
17090                    if (false) {
17091                        //RuntimeException h = new RuntimeException("here");
17092                        Slog.i(TAG, "Sending new process state " + app.repProcState
17093                                + " to " + app /*, h*/);
17094                    }
17095                    app.thread.setProcessState(app.repProcState);
17096                } catch (RemoteException e) {
17097                }
17098            }
17099        }
17100        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17101                app.setProcState)) {
17102            app.lastStateTime = now;
17103            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17104                    isSleeping(), now);
17105            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17106                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17107                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17108                    + (app.nextPssTime-now) + ": " + app);
17109        } else {
17110            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17111                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17112                requestPssLocked(app, app.setProcState);
17113                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17114                        isSleeping(), now);
17115            } else if (false && DEBUG_PSS) {
17116                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17117            }
17118        }
17119        if (app.setProcState != app.curProcState) {
17120            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17121                    "Proc state change of " + app.processName
17122                    + " to " + app.curProcState);
17123            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17124            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17125            if (setImportant && !curImportant) {
17126                // This app is no longer something we consider important enough to allow to
17127                // use arbitrary amounts of battery power.  Note
17128                // its current wake lock time to later know to kill it if
17129                // it is not behaving well.
17130                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17131                synchronized (stats) {
17132                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17133                            app.pid, SystemClock.elapsedRealtime());
17134                }
17135                app.lastCpuTime = app.curCpuTime;
17136
17137            }
17138            app.setProcState = app.curProcState;
17139            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17140                app.notCachedSinceIdle = false;
17141            }
17142            if (!doingAll) {
17143                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17144            } else {
17145                app.procStateChanged = true;
17146            }
17147        }
17148
17149        if (changes != 0) {
17150            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17151            int i = mPendingProcessChanges.size()-1;
17152            ProcessChangeItem item = null;
17153            while (i >= 0) {
17154                item = mPendingProcessChanges.get(i);
17155                if (item.pid == app.pid) {
17156                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17157                    break;
17158                }
17159                i--;
17160            }
17161            if (i < 0) {
17162                // No existing item in pending changes; need a new one.
17163                final int NA = mAvailProcessChanges.size();
17164                if (NA > 0) {
17165                    item = mAvailProcessChanges.remove(NA-1);
17166                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17167                } else {
17168                    item = new ProcessChangeItem();
17169                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17170                }
17171                item.changes = 0;
17172                item.pid = app.pid;
17173                item.uid = app.info.uid;
17174                if (mPendingProcessChanges.size() == 0) {
17175                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17176                            "*** Enqueueing dispatch processes changed!");
17177                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17178                }
17179                mPendingProcessChanges.add(item);
17180            }
17181            item.changes |= changes;
17182            item.processState = app.repProcState;
17183            item.foregroundActivities = app.repForegroundActivities;
17184            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17185                    + Integer.toHexString(System.identityHashCode(item))
17186                    + " " + app.toShortString() + ": changes=" + item.changes
17187                    + " procState=" + item.processState
17188                    + " foreground=" + item.foregroundActivities
17189                    + " type=" + app.adjType + " source=" + app.adjSource
17190                    + " target=" + app.adjTarget);
17191        }
17192
17193        return success;
17194    }
17195
17196    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17197        if (proc.thread != null) {
17198            if (proc.baseProcessTracker != null) {
17199                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17200            }
17201            if (proc.repProcState >= 0) {
17202                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17203                        proc.repProcState);
17204            }
17205        }
17206    }
17207
17208    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17209            ProcessRecord TOP_APP, boolean doingAll, long now) {
17210        if (app.thread == null) {
17211            return false;
17212        }
17213
17214        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17215
17216        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17217    }
17218
17219    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17220            boolean oomAdj) {
17221        if (isForeground != proc.foregroundServices) {
17222            proc.foregroundServices = isForeground;
17223            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17224                    proc.info.uid);
17225            if (isForeground) {
17226                if (curProcs == null) {
17227                    curProcs = new ArrayList<ProcessRecord>();
17228                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17229                }
17230                if (!curProcs.contains(proc)) {
17231                    curProcs.add(proc);
17232                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17233                            proc.info.packageName, proc.info.uid);
17234                }
17235            } else {
17236                if (curProcs != null) {
17237                    if (curProcs.remove(proc)) {
17238                        mBatteryStatsService.noteEvent(
17239                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17240                                proc.info.packageName, proc.info.uid);
17241                        if (curProcs.size() <= 0) {
17242                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17243                        }
17244                    }
17245                }
17246            }
17247            if (oomAdj) {
17248                updateOomAdjLocked();
17249            }
17250        }
17251    }
17252
17253    private final ActivityRecord resumedAppLocked() {
17254        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17255        String pkg;
17256        int uid;
17257        if (act != null) {
17258            pkg = act.packageName;
17259            uid = act.info.applicationInfo.uid;
17260        } else {
17261            pkg = null;
17262            uid = -1;
17263        }
17264        // Has the UID or resumed package name changed?
17265        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17266                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17267            if (mCurResumedPackage != null) {
17268                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17269                        mCurResumedPackage, mCurResumedUid);
17270            }
17271            mCurResumedPackage = pkg;
17272            mCurResumedUid = uid;
17273            if (mCurResumedPackage != null) {
17274                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17275                        mCurResumedPackage, mCurResumedUid);
17276            }
17277        }
17278        return act;
17279    }
17280
17281    final boolean updateOomAdjLocked(ProcessRecord app) {
17282        final ActivityRecord TOP_ACT = resumedAppLocked();
17283        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17284        final boolean wasCached = app.cached;
17285
17286        mAdjSeq++;
17287
17288        // This is the desired cached adjusment we want to tell it to use.
17289        // If our app is currently cached, we know it, and that is it.  Otherwise,
17290        // we don't know it yet, and it needs to now be cached we will then
17291        // need to do a complete oom adj.
17292        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17293                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17294        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17295                SystemClock.uptimeMillis());
17296        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17297            // Changed to/from cached state, so apps after it in the LRU
17298            // list may also be changed.
17299            updateOomAdjLocked();
17300        }
17301        return success;
17302    }
17303
17304    final void updateOomAdjLocked() {
17305        final ActivityRecord TOP_ACT = resumedAppLocked();
17306        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17307        final long now = SystemClock.uptimeMillis();
17308        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17309        final int N = mLruProcesses.size();
17310
17311        if (false) {
17312            RuntimeException e = new RuntimeException();
17313            e.fillInStackTrace();
17314            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17315        }
17316
17317        mAdjSeq++;
17318        mNewNumServiceProcs = 0;
17319        mNewNumAServiceProcs = 0;
17320
17321        final int emptyProcessLimit;
17322        final int cachedProcessLimit;
17323        if (mProcessLimit <= 0) {
17324            emptyProcessLimit = cachedProcessLimit = 0;
17325        } else if (mProcessLimit == 1) {
17326            emptyProcessLimit = 1;
17327            cachedProcessLimit = 0;
17328        } else {
17329            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17330            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17331        }
17332
17333        // Let's determine how many processes we have running vs.
17334        // how many slots we have for background processes; we may want
17335        // to put multiple processes in a slot of there are enough of
17336        // them.
17337        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17338                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17339        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17340        if (numEmptyProcs > cachedProcessLimit) {
17341            // If there are more empty processes than our limit on cached
17342            // processes, then use the cached process limit for the factor.
17343            // This ensures that the really old empty processes get pushed
17344            // down to the bottom, so if we are running low on memory we will
17345            // have a better chance at keeping around more cached processes
17346            // instead of a gazillion empty processes.
17347            numEmptyProcs = cachedProcessLimit;
17348        }
17349        int emptyFactor = numEmptyProcs/numSlots;
17350        if (emptyFactor < 1) emptyFactor = 1;
17351        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17352        if (cachedFactor < 1) cachedFactor = 1;
17353        int stepCached = 0;
17354        int stepEmpty = 0;
17355        int numCached = 0;
17356        int numEmpty = 0;
17357        int numTrimming = 0;
17358
17359        mNumNonCachedProcs = 0;
17360        mNumCachedHiddenProcs = 0;
17361
17362        // First update the OOM adjustment for each of the
17363        // application processes based on their current state.
17364        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17365        int nextCachedAdj = curCachedAdj+1;
17366        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17367        int nextEmptyAdj = curEmptyAdj+2;
17368        for (int i=N-1; i>=0; i--) {
17369            ProcessRecord app = mLruProcesses.get(i);
17370            if (!app.killedByAm && app.thread != null) {
17371                app.procStateChanged = false;
17372                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17373
17374                // If we haven't yet assigned the final cached adj
17375                // to the process, do that now.
17376                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17377                    switch (app.curProcState) {
17378                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17379                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17380                            // This process is a cached process holding activities...
17381                            // assign it the next cached value for that type, and then
17382                            // step that cached level.
17383                            app.curRawAdj = curCachedAdj;
17384                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17385                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17386                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17387                                    + ")");
17388                            if (curCachedAdj != nextCachedAdj) {
17389                                stepCached++;
17390                                if (stepCached >= cachedFactor) {
17391                                    stepCached = 0;
17392                                    curCachedAdj = nextCachedAdj;
17393                                    nextCachedAdj += 2;
17394                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17395                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17396                                    }
17397                                }
17398                            }
17399                            break;
17400                        default:
17401                            // For everything else, assign next empty cached process
17402                            // level and bump that up.  Note that this means that
17403                            // long-running services that have dropped down to the
17404                            // cached level will be treated as empty (since their process
17405                            // state is still as a service), which is what we want.
17406                            app.curRawAdj = curEmptyAdj;
17407                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17408                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17409                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17410                                    + ")");
17411                            if (curEmptyAdj != nextEmptyAdj) {
17412                                stepEmpty++;
17413                                if (stepEmpty >= emptyFactor) {
17414                                    stepEmpty = 0;
17415                                    curEmptyAdj = nextEmptyAdj;
17416                                    nextEmptyAdj += 2;
17417                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17418                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17419                                    }
17420                                }
17421                            }
17422                            break;
17423                    }
17424                }
17425
17426                applyOomAdjLocked(app, TOP_APP, true, now);
17427
17428                // Count the number of process types.
17429                switch (app.curProcState) {
17430                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17431                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17432                        mNumCachedHiddenProcs++;
17433                        numCached++;
17434                        if (numCached > cachedProcessLimit) {
17435                            app.kill("cached #" + numCached, true);
17436                        }
17437                        break;
17438                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17439                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17440                                && app.lastActivityTime < oldTime) {
17441                            app.kill("empty for "
17442                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17443                                    / 1000) + "s", true);
17444                        } else {
17445                            numEmpty++;
17446                            if (numEmpty > emptyProcessLimit) {
17447                                app.kill("empty #" + numEmpty, true);
17448                            }
17449                        }
17450                        break;
17451                    default:
17452                        mNumNonCachedProcs++;
17453                        break;
17454                }
17455
17456                if (app.isolated && app.services.size() <= 0) {
17457                    // If this is an isolated process, and there are no
17458                    // services running in it, then the process is no longer
17459                    // needed.  We agressively kill these because we can by
17460                    // definition not re-use the same process again, and it is
17461                    // good to avoid having whatever code was running in them
17462                    // left sitting around after no longer needed.
17463                    app.kill("isolated not needed", true);
17464                }
17465
17466                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17467                        && !app.killedByAm) {
17468                    numTrimming++;
17469                }
17470            }
17471        }
17472
17473        mNumServiceProcs = mNewNumServiceProcs;
17474
17475        // Now determine the memory trimming level of background processes.
17476        // Unfortunately we need to start at the back of the list to do this
17477        // properly.  We only do this if the number of background apps we
17478        // are managing to keep around is less than half the maximum we desire;
17479        // if we are keeping a good number around, we'll let them use whatever
17480        // memory they want.
17481        final int numCachedAndEmpty = numCached + numEmpty;
17482        int memFactor;
17483        if (numCached <= ProcessList.TRIM_CACHED_APPS
17484                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17485            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17486                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17487            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17488                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17489            } else {
17490                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17491            }
17492        } else {
17493            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17494        }
17495        // We always allow the memory level to go up (better).  We only allow it to go
17496        // down if we are in a state where that is allowed, *and* the total number of processes
17497        // has gone down since last time.
17498        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17499                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17500                + " last=" + mLastNumProcesses);
17501        if (memFactor > mLastMemoryLevel) {
17502            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17503                memFactor = mLastMemoryLevel;
17504                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17505            }
17506        }
17507        mLastMemoryLevel = memFactor;
17508        mLastNumProcesses = mLruProcesses.size();
17509        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17510        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17511        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17512            if (mLowRamStartTime == 0) {
17513                mLowRamStartTime = now;
17514            }
17515            int step = 0;
17516            int fgTrimLevel;
17517            switch (memFactor) {
17518                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17519                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17520                    break;
17521                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17522                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17523                    break;
17524                default:
17525                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17526                    break;
17527            }
17528            int factor = numTrimming/3;
17529            int minFactor = 2;
17530            if (mHomeProcess != null) minFactor++;
17531            if (mPreviousProcess != null) minFactor++;
17532            if (factor < minFactor) factor = minFactor;
17533            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17534            for (int i=N-1; i>=0; i--) {
17535                ProcessRecord app = mLruProcesses.get(i);
17536                if (allChanged || app.procStateChanged) {
17537                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17538                    app.procStateChanged = false;
17539                }
17540                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17541                        && !app.killedByAm) {
17542                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17543                        try {
17544                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17545                                    "Trimming memory of " + app.processName
17546                                    + " to " + curLevel);
17547                            app.thread.scheduleTrimMemory(curLevel);
17548                        } catch (RemoteException e) {
17549                        }
17550                        if (false) {
17551                            // For now we won't do this; our memory trimming seems
17552                            // to be good enough at this point that destroying
17553                            // activities causes more harm than good.
17554                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17555                                    && app != mHomeProcess && app != mPreviousProcess) {
17556                                // Need to do this on its own message because the stack may not
17557                                // be in a consistent state at this point.
17558                                // For these apps we will also finish their activities
17559                                // to help them free memory.
17560                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17561                            }
17562                        }
17563                    }
17564                    app.trimMemoryLevel = curLevel;
17565                    step++;
17566                    if (step >= factor) {
17567                        step = 0;
17568                        switch (curLevel) {
17569                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17570                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17571                                break;
17572                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17573                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17574                                break;
17575                        }
17576                    }
17577                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17578                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17579                            && app.thread != null) {
17580                        try {
17581                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17582                                    "Trimming memory of heavy-weight " + app.processName
17583                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17584                            app.thread.scheduleTrimMemory(
17585                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17586                        } catch (RemoteException e) {
17587                        }
17588                    }
17589                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17590                } else {
17591                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17592                            || app.systemNoUi) && app.pendingUiClean) {
17593                        // If this application is now in the background and it
17594                        // had done UI, then give it the special trim level to
17595                        // have it free UI resources.
17596                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17597                        if (app.trimMemoryLevel < level && app.thread != null) {
17598                            try {
17599                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17600                                        "Trimming memory of bg-ui " + app.processName
17601                                        + " to " + level);
17602                                app.thread.scheduleTrimMemory(level);
17603                            } catch (RemoteException e) {
17604                            }
17605                        }
17606                        app.pendingUiClean = false;
17607                    }
17608                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17609                        try {
17610                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17611                                    "Trimming memory of fg " + app.processName
17612                                    + " to " + fgTrimLevel);
17613                            app.thread.scheduleTrimMemory(fgTrimLevel);
17614                        } catch (RemoteException e) {
17615                        }
17616                    }
17617                    app.trimMemoryLevel = fgTrimLevel;
17618                }
17619            }
17620        } else {
17621            if (mLowRamStartTime != 0) {
17622                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17623                mLowRamStartTime = 0;
17624            }
17625            for (int i=N-1; i>=0; i--) {
17626                ProcessRecord app = mLruProcesses.get(i);
17627                if (allChanged || app.procStateChanged) {
17628                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17629                    app.procStateChanged = false;
17630                }
17631                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17632                        || app.systemNoUi) && app.pendingUiClean) {
17633                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17634                            && app.thread != null) {
17635                        try {
17636                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17637                                    "Trimming memory of ui hidden " + app.processName
17638                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17639                            app.thread.scheduleTrimMemory(
17640                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17641                        } catch (RemoteException e) {
17642                        }
17643                    }
17644                    app.pendingUiClean = false;
17645                }
17646                app.trimMemoryLevel = 0;
17647            }
17648        }
17649
17650        if (mAlwaysFinishActivities) {
17651            // Need to do this on its own message because the stack may not
17652            // be in a consistent state at this point.
17653            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17654        }
17655
17656        if (allChanged) {
17657            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17658        }
17659
17660        if (mProcessStats.shouldWriteNowLocked(now)) {
17661            mHandler.post(new Runnable() {
17662                @Override public void run() {
17663                    synchronized (ActivityManagerService.this) {
17664                        mProcessStats.writeStateAsyncLocked();
17665                    }
17666                }
17667            });
17668        }
17669
17670        if (DEBUG_OOM_ADJ) {
17671            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17672        }
17673    }
17674
17675    final void trimApplications() {
17676        synchronized (this) {
17677            int i;
17678
17679            // First remove any unused application processes whose package
17680            // has been removed.
17681            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17682                final ProcessRecord app = mRemovedProcesses.get(i);
17683                if (app.activities.size() == 0
17684                        && app.curReceiver == null && app.services.size() == 0) {
17685                    Slog.i(
17686                        TAG, "Exiting empty application process "
17687                        + app.processName + " ("
17688                        + (app.thread != null ? app.thread.asBinder() : null)
17689                        + ")\n");
17690                    if (app.pid > 0 && app.pid != MY_PID) {
17691                        app.kill("empty", false);
17692                    } else {
17693                        try {
17694                            app.thread.scheduleExit();
17695                        } catch (Exception e) {
17696                            // Ignore exceptions.
17697                        }
17698                    }
17699                    cleanUpApplicationRecordLocked(app, false, true, -1);
17700                    mRemovedProcesses.remove(i);
17701
17702                    if (app.persistent) {
17703                        addAppLocked(app.info, false, null /* ABI override */);
17704                    }
17705                }
17706            }
17707
17708            // Now update the oom adj for all processes.
17709            updateOomAdjLocked();
17710        }
17711    }
17712
17713    /** This method sends the specified signal to each of the persistent apps */
17714    public void signalPersistentProcesses(int sig) throws RemoteException {
17715        if (sig != Process.SIGNAL_USR1) {
17716            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17717        }
17718
17719        synchronized (this) {
17720            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17721                    != PackageManager.PERMISSION_GRANTED) {
17722                throw new SecurityException("Requires permission "
17723                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17724            }
17725
17726            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17727                ProcessRecord r = mLruProcesses.get(i);
17728                if (r.thread != null && r.persistent) {
17729                    Process.sendSignal(r.pid, sig);
17730                }
17731            }
17732        }
17733    }
17734
17735    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17736        if (proc == null || proc == mProfileProc) {
17737            proc = mProfileProc;
17738            profileType = mProfileType;
17739            clearProfilerLocked();
17740        }
17741        if (proc == null) {
17742            return;
17743        }
17744        try {
17745            proc.thread.profilerControl(false, null, profileType);
17746        } catch (RemoteException e) {
17747            throw new IllegalStateException("Process disappeared");
17748        }
17749    }
17750
17751    private void clearProfilerLocked() {
17752        if (mProfileFd != null) {
17753            try {
17754                mProfileFd.close();
17755            } catch (IOException e) {
17756            }
17757        }
17758        mProfileApp = null;
17759        mProfileProc = null;
17760        mProfileFile = null;
17761        mProfileType = 0;
17762        mAutoStopProfiler = false;
17763        mSamplingInterval = 0;
17764    }
17765
17766    public boolean profileControl(String process, int userId, boolean start,
17767            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17768
17769        try {
17770            synchronized (this) {
17771                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17772                // its own permission.
17773                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17774                        != PackageManager.PERMISSION_GRANTED) {
17775                    throw new SecurityException("Requires permission "
17776                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17777                }
17778
17779                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17780                    throw new IllegalArgumentException("null profile info or fd");
17781                }
17782
17783                ProcessRecord proc = null;
17784                if (process != null) {
17785                    proc = findProcessLocked(process, userId, "profileControl");
17786                }
17787
17788                if (start && (proc == null || proc.thread == null)) {
17789                    throw new IllegalArgumentException("Unknown process: " + process);
17790                }
17791
17792                if (start) {
17793                    stopProfilerLocked(null, 0);
17794                    setProfileApp(proc.info, proc.processName, profilerInfo);
17795                    mProfileProc = proc;
17796                    mProfileType = profileType;
17797                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17798                    try {
17799                        fd = fd.dup();
17800                    } catch (IOException e) {
17801                        fd = null;
17802                    }
17803                    profilerInfo.profileFd = fd;
17804                    proc.thread.profilerControl(start, profilerInfo, profileType);
17805                    fd = null;
17806                    mProfileFd = null;
17807                } else {
17808                    stopProfilerLocked(proc, profileType);
17809                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17810                        try {
17811                            profilerInfo.profileFd.close();
17812                        } catch (IOException e) {
17813                        }
17814                    }
17815                }
17816
17817                return true;
17818            }
17819        } catch (RemoteException e) {
17820            throw new IllegalStateException("Process disappeared");
17821        } finally {
17822            if (profilerInfo != null && profilerInfo.profileFd != null) {
17823                try {
17824                    profilerInfo.profileFd.close();
17825                } catch (IOException e) {
17826                }
17827            }
17828        }
17829    }
17830
17831    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17832        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17833                userId, true, ALLOW_FULL_ONLY, callName, null);
17834        ProcessRecord proc = null;
17835        try {
17836            int pid = Integer.parseInt(process);
17837            synchronized (mPidsSelfLocked) {
17838                proc = mPidsSelfLocked.get(pid);
17839            }
17840        } catch (NumberFormatException e) {
17841        }
17842
17843        if (proc == null) {
17844            ArrayMap<String, SparseArray<ProcessRecord>> all
17845                    = mProcessNames.getMap();
17846            SparseArray<ProcessRecord> procs = all.get(process);
17847            if (procs != null && procs.size() > 0) {
17848                proc = procs.valueAt(0);
17849                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17850                    for (int i=1; i<procs.size(); i++) {
17851                        ProcessRecord thisProc = procs.valueAt(i);
17852                        if (thisProc.userId == userId) {
17853                            proc = thisProc;
17854                            break;
17855                        }
17856                    }
17857                }
17858            }
17859        }
17860
17861        return proc;
17862    }
17863
17864    public boolean dumpHeap(String process, int userId, boolean managed,
17865            String path, ParcelFileDescriptor fd) throws RemoteException {
17866
17867        try {
17868            synchronized (this) {
17869                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17870                // its own permission (same as profileControl).
17871                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17872                        != PackageManager.PERMISSION_GRANTED) {
17873                    throw new SecurityException("Requires permission "
17874                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17875                }
17876
17877                if (fd == null) {
17878                    throw new IllegalArgumentException("null fd");
17879                }
17880
17881                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17882                if (proc == null || proc.thread == null) {
17883                    throw new IllegalArgumentException("Unknown process: " + process);
17884                }
17885
17886                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17887                if (!isDebuggable) {
17888                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17889                        throw new SecurityException("Process not debuggable: " + proc);
17890                    }
17891                }
17892
17893                proc.thread.dumpHeap(managed, path, fd);
17894                fd = null;
17895                return true;
17896            }
17897        } catch (RemoteException e) {
17898            throw new IllegalStateException("Process disappeared");
17899        } finally {
17900            if (fd != null) {
17901                try {
17902                    fd.close();
17903                } catch (IOException e) {
17904                }
17905            }
17906        }
17907    }
17908
17909    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17910    public void monitor() {
17911        synchronized (this) { }
17912    }
17913
17914    void onCoreSettingsChange(Bundle settings) {
17915        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17916            ProcessRecord processRecord = mLruProcesses.get(i);
17917            try {
17918                if (processRecord.thread != null) {
17919                    processRecord.thread.setCoreSettings(settings);
17920                }
17921            } catch (RemoteException re) {
17922                /* ignore */
17923            }
17924        }
17925    }
17926
17927    // Multi-user methods
17928
17929    /**
17930     * Start user, if its not already running, but don't bring it to foreground.
17931     */
17932    @Override
17933    public boolean startUserInBackground(final int userId) {
17934        return startUser(userId, /* foreground */ false);
17935    }
17936
17937    /**
17938     * Start user, if its not already running, and bring it to foreground.
17939     */
17940    boolean startUserInForeground(final int userId, Dialog dlg) {
17941        boolean result = startUser(userId, /* foreground */ true);
17942        dlg.dismiss();
17943        return result;
17944    }
17945
17946    /**
17947     * Refreshes the list of users related to the current user when either a
17948     * user switch happens or when a new related user is started in the
17949     * background.
17950     */
17951    private void updateCurrentProfileIdsLocked() {
17952        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17953                mCurrentUserId, false /* enabledOnly */);
17954        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17955        for (int i = 0; i < currentProfileIds.length; i++) {
17956            currentProfileIds[i] = profiles.get(i).id;
17957        }
17958        mCurrentProfileIds = currentProfileIds;
17959
17960        synchronized (mUserProfileGroupIdsSelfLocked) {
17961            mUserProfileGroupIdsSelfLocked.clear();
17962            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17963            for (int i = 0; i < users.size(); i++) {
17964                UserInfo user = users.get(i);
17965                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17966                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17967                }
17968            }
17969        }
17970    }
17971
17972    private Set getProfileIdsLocked(int userId) {
17973        Set userIds = new HashSet<Integer>();
17974        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17975                userId, false /* enabledOnly */);
17976        for (UserInfo user : profiles) {
17977            userIds.add(Integer.valueOf(user.id));
17978        }
17979        return userIds;
17980    }
17981
17982    @Override
17983    public boolean switchUser(final int userId) {
17984        String userName;
17985        synchronized (this) {
17986            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17987            if (userInfo == null) {
17988                Slog.w(TAG, "No user info for user #" + userId);
17989                return false;
17990            }
17991            if (userInfo.isManagedProfile()) {
17992                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17993                return false;
17994            }
17995            userName = userInfo.name;
17996            mTargetUserId = userId;
17997        }
17998        mHandler.removeMessages(START_USER_SWITCH_MSG);
17999        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18000        return true;
18001    }
18002
18003    private void showUserSwitchDialog(int userId, String userName) {
18004        // The dialog will show and then initiate the user switch by calling startUserInForeground
18005        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18006                true /* above system */);
18007        d.show();
18008    }
18009
18010    private boolean startUser(final int userId, final boolean foreground) {
18011        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18012                != PackageManager.PERMISSION_GRANTED) {
18013            String msg = "Permission Denial: switchUser() from pid="
18014                    + Binder.getCallingPid()
18015                    + ", uid=" + Binder.getCallingUid()
18016                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18017            Slog.w(TAG, msg);
18018            throw new SecurityException(msg);
18019        }
18020
18021        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18022
18023        final long ident = Binder.clearCallingIdentity();
18024        try {
18025            synchronized (this) {
18026                final int oldUserId = mCurrentUserId;
18027                if (oldUserId == userId) {
18028                    return true;
18029                }
18030
18031                mStackSupervisor.setLockTaskModeLocked(null, false);
18032
18033                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18034                if (userInfo == null) {
18035                    Slog.w(TAG, "No user info for user #" + userId);
18036                    return false;
18037                }
18038                if (foreground && userInfo.isManagedProfile()) {
18039                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18040                    return false;
18041                }
18042
18043                if (foreground) {
18044                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18045                            R.anim.screen_user_enter);
18046                }
18047
18048                boolean needStart = false;
18049
18050                // If the user we are switching to is not currently started, then
18051                // we need to start it now.
18052                if (mStartedUsers.get(userId) == null) {
18053                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18054                    updateStartedUserArrayLocked();
18055                    needStart = true;
18056                }
18057
18058                final Integer userIdInt = Integer.valueOf(userId);
18059                mUserLru.remove(userIdInt);
18060                mUserLru.add(userIdInt);
18061
18062                if (foreground) {
18063                    mCurrentUserId = userId;
18064                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18065                    updateCurrentProfileIdsLocked();
18066                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18067                    // Once the internal notion of the active user has switched, we lock the device
18068                    // with the option to show the user switcher on the keyguard.
18069                    mWindowManager.lockNow(null);
18070                } else {
18071                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18072                    updateCurrentProfileIdsLocked();
18073                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18074                    mUserLru.remove(currentUserIdInt);
18075                    mUserLru.add(currentUserIdInt);
18076                }
18077
18078                final UserStartedState uss = mStartedUsers.get(userId);
18079
18080                // Make sure user is in the started state.  If it is currently
18081                // stopping, we need to knock that off.
18082                if (uss.mState == UserStartedState.STATE_STOPPING) {
18083                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18084                    // so we can just fairly silently bring the user back from
18085                    // the almost-dead.
18086                    uss.mState = UserStartedState.STATE_RUNNING;
18087                    updateStartedUserArrayLocked();
18088                    needStart = true;
18089                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18090                    // This means ACTION_SHUTDOWN has been sent, so we will
18091                    // need to treat this as a new boot of the user.
18092                    uss.mState = UserStartedState.STATE_BOOTING;
18093                    updateStartedUserArrayLocked();
18094                    needStart = true;
18095                }
18096
18097                if (uss.mState == UserStartedState.STATE_BOOTING) {
18098                    // Booting up a new user, need to tell system services about it.
18099                    // Note that this is on the same handler as scheduling of broadcasts,
18100                    // which is important because it needs to go first.
18101                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18102                }
18103
18104                if (foreground) {
18105                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18106                            oldUserId));
18107                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18108                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18109                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18110                            oldUserId, userId, uss));
18111                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18112                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18113                }
18114
18115                if (needStart) {
18116                    // Send USER_STARTED broadcast
18117                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18118                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18119                            | Intent.FLAG_RECEIVER_FOREGROUND);
18120                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18121                    broadcastIntentLocked(null, null, intent,
18122                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18123                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18124                }
18125
18126                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18127                    if (userId != UserHandle.USER_OWNER) {
18128                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18129                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18130                        broadcastIntentLocked(null, null, intent, null,
18131                                new IIntentReceiver.Stub() {
18132                                    public void performReceive(Intent intent, int resultCode,
18133                                            String data, Bundle extras, boolean ordered,
18134                                            boolean sticky, int sendingUser) {
18135                                        onUserInitialized(uss, foreground, oldUserId, userId);
18136                                    }
18137                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18138                                true, false, MY_PID, Process.SYSTEM_UID,
18139                                userId);
18140                        uss.initializing = true;
18141                    } else {
18142                        getUserManagerLocked().makeInitialized(userInfo.id);
18143                    }
18144                }
18145
18146                if (foreground) {
18147                    if (!uss.initializing) {
18148                        moveUserToForeground(uss, oldUserId, userId);
18149                    }
18150                } else {
18151                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18152                }
18153
18154                if (needStart) {
18155                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18156                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18157                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18158                    broadcastIntentLocked(null, null, intent,
18159                            null, new IIntentReceiver.Stub() {
18160                                @Override
18161                                public void performReceive(Intent intent, int resultCode, String data,
18162                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18163                                        throws RemoteException {
18164                                }
18165                            }, 0, null, null,
18166                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18167                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18168                }
18169            }
18170        } finally {
18171            Binder.restoreCallingIdentity(ident);
18172        }
18173
18174        return true;
18175    }
18176
18177    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18178        long ident = Binder.clearCallingIdentity();
18179        try {
18180            Intent intent;
18181            if (oldUserId >= 0) {
18182                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18183                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18184                int count = profiles.size();
18185                for (int i = 0; i < count; i++) {
18186                    int profileUserId = profiles.get(i).id;
18187                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18188                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18189                            | Intent.FLAG_RECEIVER_FOREGROUND);
18190                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18191                    broadcastIntentLocked(null, null, intent,
18192                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18193                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18194                }
18195            }
18196            if (newUserId >= 0) {
18197                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18198                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18199                int count = profiles.size();
18200                for (int i = 0; i < count; i++) {
18201                    int profileUserId = profiles.get(i).id;
18202                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18203                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18204                            | Intent.FLAG_RECEIVER_FOREGROUND);
18205                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18206                    broadcastIntentLocked(null, null, intent,
18207                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18208                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18209                }
18210                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18211                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18212                        | Intent.FLAG_RECEIVER_FOREGROUND);
18213                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18214                broadcastIntentLocked(null, null, intent,
18215                        null, null, 0, null, null,
18216                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18217                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18218            }
18219        } finally {
18220            Binder.restoreCallingIdentity(ident);
18221        }
18222    }
18223
18224    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18225            final int newUserId) {
18226        final int N = mUserSwitchObservers.beginBroadcast();
18227        if (N > 0) {
18228            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18229                int mCount = 0;
18230                @Override
18231                public void sendResult(Bundle data) throws RemoteException {
18232                    synchronized (ActivityManagerService.this) {
18233                        if (mCurUserSwitchCallback == this) {
18234                            mCount++;
18235                            if (mCount == N) {
18236                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18237                            }
18238                        }
18239                    }
18240                }
18241            };
18242            synchronized (this) {
18243                uss.switching = true;
18244                mCurUserSwitchCallback = callback;
18245            }
18246            for (int i=0; i<N; i++) {
18247                try {
18248                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18249                            newUserId, callback);
18250                } catch (RemoteException e) {
18251                }
18252            }
18253        } else {
18254            synchronized (this) {
18255                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18256            }
18257        }
18258        mUserSwitchObservers.finishBroadcast();
18259    }
18260
18261    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18262        synchronized (this) {
18263            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18264            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18265        }
18266    }
18267
18268    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18269        mCurUserSwitchCallback = null;
18270        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18271        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18272                oldUserId, newUserId, uss));
18273    }
18274
18275    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18276        synchronized (this) {
18277            if (foreground) {
18278                moveUserToForeground(uss, oldUserId, newUserId);
18279            }
18280        }
18281
18282        completeSwitchAndInitalize(uss, newUserId, true, false);
18283    }
18284
18285    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18286        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18287        if (homeInFront) {
18288            startHomeActivityLocked(newUserId);
18289        } else {
18290            mStackSupervisor.resumeTopActivitiesLocked();
18291        }
18292        EventLogTags.writeAmSwitchUser(newUserId);
18293        getUserManagerLocked().userForeground(newUserId);
18294        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18295    }
18296
18297    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18298        completeSwitchAndInitalize(uss, newUserId, false, true);
18299    }
18300
18301    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18302            boolean clearInitializing, boolean clearSwitching) {
18303        boolean unfrozen = false;
18304        synchronized (this) {
18305            if (clearInitializing) {
18306                uss.initializing = false;
18307                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18308            }
18309            if (clearSwitching) {
18310                uss.switching = false;
18311            }
18312            if (!uss.switching && !uss.initializing) {
18313                mWindowManager.stopFreezingScreen();
18314                unfrozen = true;
18315            }
18316        }
18317        if (unfrozen) {
18318            final int N = mUserSwitchObservers.beginBroadcast();
18319            for (int i=0; i<N; i++) {
18320                try {
18321                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18322                } catch (RemoteException e) {
18323                }
18324            }
18325            mUserSwitchObservers.finishBroadcast();
18326        }
18327    }
18328
18329    void scheduleStartProfilesLocked() {
18330        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18331            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18332                    DateUtils.SECOND_IN_MILLIS);
18333        }
18334    }
18335
18336    void startProfilesLocked() {
18337        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18338        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18339                mCurrentUserId, false /* enabledOnly */);
18340        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18341        for (UserInfo user : profiles) {
18342            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18343                    && user.id != mCurrentUserId) {
18344                toStart.add(user);
18345            }
18346        }
18347        final int n = toStart.size();
18348        int i = 0;
18349        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18350            startUserInBackground(toStart.get(i).id);
18351        }
18352        if (i < n) {
18353            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18354        }
18355    }
18356
18357    void finishUserBoot(UserStartedState uss) {
18358        synchronized (this) {
18359            if (uss.mState == UserStartedState.STATE_BOOTING
18360                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18361                uss.mState = UserStartedState.STATE_RUNNING;
18362                final int userId = uss.mHandle.getIdentifier();
18363                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18364                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18365                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18366                broadcastIntentLocked(null, null, intent,
18367                        null, null, 0, null, null,
18368                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18369                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18370            }
18371        }
18372    }
18373
18374    void finishUserSwitch(UserStartedState uss) {
18375        synchronized (this) {
18376            finishUserBoot(uss);
18377
18378            startProfilesLocked();
18379
18380            int num = mUserLru.size();
18381            int i = 0;
18382            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18383                Integer oldUserId = mUserLru.get(i);
18384                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18385                if (oldUss == null) {
18386                    // Shouldn't happen, but be sane if it does.
18387                    mUserLru.remove(i);
18388                    num--;
18389                    continue;
18390                }
18391                if (oldUss.mState == UserStartedState.STATE_STOPPING
18392                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18393                    // This user is already stopping, doesn't count.
18394                    num--;
18395                    i++;
18396                    continue;
18397                }
18398                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18399                    // Owner and current can't be stopped, but count as running.
18400                    i++;
18401                    continue;
18402                }
18403                // This is a user to be stopped.
18404                stopUserLocked(oldUserId, null);
18405                num--;
18406                i++;
18407            }
18408        }
18409    }
18410
18411    @Override
18412    public int stopUser(final int userId, final IStopUserCallback callback) {
18413        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18414                != PackageManager.PERMISSION_GRANTED) {
18415            String msg = "Permission Denial: switchUser() from pid="
18416                    + Binder.getCallingPid()
18417                    + ", uid=" + Binder.getCallingUid()
18418                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18419            Slog.w(TAG, msg);
18420            throw new SecurityException(msg);
18421        }
18422        if (userId <= 0) {
18423            throw new IllegalArgumentException("Can't stop primary user " + userId);
18424        }
18425        synchronized (this) {
18426            return stopUserLocked(userId, callback);
18427        }
18428    }
18429
18430    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18431        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18432        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18433            return ActivityManager.USER_OP_IS_CURRENT;
18434        }
18435
18436        final UserStartedState uss = mStartedUsers.get(userId);
18437        if (uss == null) {
18438            // User is not started, nothing to do...  but we do need to
18439            // callback if requested.
18440            if (callback != null) {
18441                mHandler.post(new Runnable() {
18442                    @Override
18443                    public void run() {
18444                        try {
18445                            callback.userStopped(userId);
18446                        } catch (RemoteException e) {
18447                        }
18448                    }
18449                });
18450            }
18451            return ActivityManager.USER_OP_SUCCESS;
18452        }
18453
18454        if (callback != null) {
18455            uss.mStopCallbacks.add(callback);
18456        }
18457
18458        if (uss.mState != UserStartedState.STATE_STOPPING
18459                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18460            uss.mState = UserStartedState.STATE_STOPPING;
18461            updateStartedUserArrayLocked();
18462
18463            long ident = Binder.clearCallingIdentity();
18464            try {
18465                // We are going to broadcast ACTION_USER_STOPPING and then
18466                // once that is done send a final ACTION_SHUTDOWN and then
18467                // stop the user.
18468                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18469                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18470                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18471                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18472                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18473                // This is the result receiver for the final shutdown broadcast.
18474                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18475                    @Override
18476                    public void performReceive(Intent intent, int resultCode, String data,
18477                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18478                        finishUserStop(uss);
18479                    }
18480                };
18481                // This is the result receiver for the initial stopping broadcast.
18482                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18483                    @Override
18484                    public void performReceive(Intent intent, int resultCode, String data,
18485                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18486                        // On to the next.
18487                        synchronized (ActivityManagerService.this) {
18488                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18489                                // Whoops, we are being started back up.  Abort, abort!
18490                                return;
18491                            }
18492                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18493                        }
18494                        mBatteryStatsService.noteEvent(
18495                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18496                                Integer.toString(userId), userId);
18497                        mSystemServiceManager.stopUser(userId);
18498                        broadcastIntentLocked(null, null, shutdownIntent,
18499                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18500                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18501                    }
18502                };
18503                // Kick things off.
18504                broadcastIntentLocked(null, null, stoppingIntent,
18505                        null, stoppingReceiver, 0, null, null,
18506                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18507                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18508            } finally {
18509                Binder.restoreCallingIdentity(ident);
18510            }
18511        }
18512
18513        return ActivityManager.USER_OP_SUCCESS;
18514    }
18515
18516    void finishUserStop(UserStartedState uss) {
18517        final int userId = uss.mHandle.getIdentifier();
18518        boolean stopped;
18519        ArrayList<IStopUserCallback> callbacks;
18520        synchronized (this) {
18521            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18522            if (mStartedUsers.get(userId) != uss) {
18523                stopped = false;
18524            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18525                stopped = false;
18526            } else {
18527                stopped = true;
18528                // User can no longer run.
18529                mStartedUsers.remove(userId);
18530                mUserLru.remove(Integer.valueOf(userId));
18531                updateStartedUserArrayLocked();
18532
18533                // Clean up all state and processes associated with the user.
18534                // Kill all the processes for the user.
18535                forceStopUserLocked(userId, "finish user");
18536            }
18537
18538            // Explicitly remove the old information in mRecentTasks.
18539            removeRecentTasksForUserLocked(userId);
18540        }
18541
18542        for (int i=0; i<callbacks.size(); i++) {
18543            try {
18544                if (stopped) callbacks.get(i).userStopped(userId);
18545                else callbacks.get(i).userStopAborted(userId);
18546            } catch (RemoteException e) {
18547            }
18548        }
18549
18550        if (stopped) {
18551            mSystemServiceManager.cleanupUser(userId);
18552            synchronized (this) {
18553                mStackSupervisor.removeUserLocked(userId);
18554            }
18555        }
18556    }
18557
18558    @Override
18559    public UserInfo getCurrentUser() {
18560        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18561                != PackageManager.PERMISSION_GRANTED) && (
18562                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18563                != PackageManager.PERMISSION_GRANTED)) {
18564            String msg = "Permission Denial: getCurrentUser() from pid="
18565                    + Binder.getCallingPid()
18566                    + ", uid=" + Binder.getCallingUid()
18567                    + " requires " + INTERACT_ACROSS_USERS;
18568            Slog.w(TAG, msg);
18569            throw new SecurityException(msg);
18570        }
18571        synchronized (this) {
18572            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18573            return getUserManagerLocked().getUserInfo(userId);
18574        }
18575    }
18576
18577    int getCurrentUserIdLocked() {
18578        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18579    }
18580
18581    @Override
18582    public boolean isUserRunning(int userId, boolean orStopped) {
18583        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18584                != PackageManager.PERMISSION_GRANTED) {
18585            String msg = "Permission Denial: isUserRunning() from pid="
18586                    + Binder.getCallingPid()
18587                    + ", uid=" + Binder.getCallingUid()
18588                    + " requires " + INTERACT_ACROSS_USERS;
18589            Slog.w(TAG, msg);
18590            throw new SecurityException(msg);
18591        }
18592        synchronized (this) {
18593            return isUserRunningLocked(userId, orStopped);
18594        }
18595    }
18596
18597    boolean isUserRunningLocked(int userId, boolean orStopped) {
18598        UserStartedState state = mStartedUsers.get(userId);
18599        if (state == null) {
18600            return false;
18601        }
18602        if (orStopped) {
18603            return true;
18604        }
18605        return state.mState != UserStartedState.STATE_STOPPING
18606                && state.mState != UserStartedState.STATE_SHUTDOWN;
18607    }
18608
18609    @Override
18610    public int[] getRunningUserIds() {
18611        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18612                != PackageManager.PERMISSION_GRANTED) {
18613            String msg = "Permission Denial: isUserRunning() from pid="
18614                    + Binder.getCallingPid()
18615                    + ", uid=" + Binder.getCallingUid()
18616                    + " requires " + INTERACT_ACROSS_USERS;
18617            Slog.w(TAG, msg);
18618            throw new SecurityException(msg);
18619        }
18620        synchronized (this) {
18621            return mStartedUserArray;
18622        }
18623    }
18624
18625    private void updateStartedUserArrayLocked() {
18626        int num = 0;
18627        for (int i=0; i<mStartedUsers.size();  i++) {
18628            UserStartedState uss = mStartedUsers.valueAt(i);
18629            // This list does not include stopping users.
18630            if (uss.mState != UserStartedState.STATE_STOPPING
18631                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18632                num++;
18633            }
18634        }
18635        mStartedUserArray = new int[num];
18636        num = 0;
18637        for (int i=0; i<mStartedUsers.size();  i++) {
18638            UserStartedState uss = mStartedUsers.valueAt(i);
18639            if (uss.mState != UserStartedState.STATE_STOPPING
18640                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18641                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18642                num++;
18643            }
18644        }
18645    }
18646
18647    @Override
18648    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18649        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18650                != PackageManager.PERMISSION_GRANTED) {
18651            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18652                    + Binder.getCallingPid()
18653                    + ", uid=" + Binder.getCallingUid()
18654                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18655            Slog.w(TAG, msg);
18656            throw new SecurityException(msg);
18657        }
18658
18659        mUserSwitchObservers.register(observer);
18660    }
18661
18662    @Override
18663    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18664        mUserSwitchObservers.unregister(observer);
18665    }
18666
18667    private boolean userExists(int userId) {
18668        if (userId == 0) {
18669            return true;
18670        }
18671        UserManagerService ums = getUserManagerLocked();
18672        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18673    }
18674
18675    int[] getUsersLocked() {
18676        UserManagerService ums = getUserManagerLocked();
18677        return ums != null ? ums.getUserIds() : new int[] { 0 };
18678    }
18679
18680    UserManagerService getUserManagerLocked() {
18681        if (mUserManager == null) {
18682            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18683            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18684        }
18685        return mUserManager;
18686    }
18687
18688    private int applyUserId(int uid, int userId) {
18689        return UserHandle.getUid(userId, uid);
18690    }
18691
18692    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18693        if (info == null) return null;
18694        ApplicationInfo newInfo = new ApplicationInfo(info);
18695        newInfo.uid = applyUserId(info.uid, userId);
18696        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18697                + info.packageName;
18698        return newInfo;
18699    }
18700
18701    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18702        if (aInfo == null
18703                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18704            return aInfo;
18705        }
18706
18707        ActivityInfo info = new ActivityInfo(aInfo);
18708        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18709        return info;
18710    }
18711
18712    private final class LocalService extends ActivityManagerInternal {
18713        @Override
18714        public void goingToSleep() {
18715            ActivityManagerService.this.goingToSleep();
18716        }
18717
18718        @Override
18719        public void wakingUp() {
18720            ActivityManagerService.this.wakingUp();
18721        }
18722
18723        @Override
18724        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18725                String processName, String abiOverride, int uid, Runnable crashHandler) {
18726            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18727                    processName, abiOverride, uid, crashHandler);
18728        }
18729    }
18730
18731    /**
18732     * An implementation of IAppTask, that allows an app to manage its own tasks via
18733     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18734     * only the process that calls getAppTasks() can call the AppTask methods.
18735     */
18736    class AppTaskImpl extends IAppTask.Stub {
18737        private int mTaskId;
18738        private int mCallingUid;
18739
18740        public AppTaskImpl(int taskId, int callingUid) {
18741            mTaskId = taskId;
18742            mCallingUid = callingUid;
18743        }
18744
18745        private void checkCaller() {
18746            if (mCallingUid != Binder.getCallingUid()) {
18747                throw new SecurityException("Caller " + mCallingUid
18748                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18749            }
18750        }
18751
18752        @Override
18753        public void finishAndRemoveTask() {
18754            checkCaller();
18755
18756            synchronized (ActivityManagerService.this) {
18757                long origId = Binder.clearCallingIdentity();
18758                try {
18759                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18760                    if (tr == null) {
18761                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18762                    }
18763                    // Only kill the process if we are not a new document
18764                    int flags = tr.getBaseIntent().getFlags();
18765                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18766                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18767                    removeTaskByIdLocked(mTaskId,
18768                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18769                } finally {
18770                    Binder.restoreCallingIdentity(origId);
18771                }
18772            }
18773        }
18774
18775        @Override
18776        public ActivityManager.RecentTaskInfo getTaskInfo() {
18777            checkCaller();
18778
18779            synchronized (ActivityManagerService.this) {
18780                long origId = Binder.clearCallingIdentity();
18781                try {
18782                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18783                    if (tr == null) {
18784                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18785                    }
18786                    return createRecentTaskInfoFromTaskRecord(tr);
18787                } finally {
18788                    Binder.restoreCallingIdentity(origId);
18789                }
18790            }
18791        }
18792
18793        @Override
18794        public void moveToFront() {
18795            checkCaller();
18796
18797            final TaskRecord tr;
18798            synchronized (ActivityManagerService.this) {
18799                tr = recentTaskForIdLocked(mTaskId);
18800                if (tr == null) {
18801                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18802                }
18803                if (tr.getRootActivity() != null) {
18804                    long origId = Binder.clearCallingIdentity();
18805                    try {
18806                        moveTaskToFrontLocked(tr.taskId, 0, null);
18807                        return;
18808                    } finally {
18809                        Binder.restoreCallingIdentity(origId);
18810                    }
18811                }
18812            }
18813
18814            startActivityFromRecentsInner(tr.taskId, null);
18815        }
18816
18817        @Override
18818        public int startActivity(IBinder whoThread, String callingPackage,
18819                Intent intent, String resolvedType, Bundle options) {
18820            checkCaller();
18821
18822            int callingUser = UserHandle.getCallingUserId();
18823            TaskRecord tr;
18824            IApplicationThread appThread;
18825            synchronized (ActivityManagerService.this) {
18826                tr = recentTaskForIdLocked(mTaskId);
18827                if (tr == null) {
18828                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18829                }
18830                appThread = ApplicationThreadNative.asInterface(whoThread);
18831                if (appThread == null) {
18832                    throw new IllegalArgumentException("Bad app thread " + appThread);
18833                }
18834            }
18835            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18836                    resolvedType, null, null, null, null, 0, 0, null, null,
18837                    null, options, callingUser, null, tr);
18838        }
18839
18840        @Override
18841        public void setExcludeFromRecents(boolean exclude) {
18842            checkCaller();
18843
18844            synchronized (ActivityManagerService.this) {
18845                long origId = Binder.clearCallingIdentity();
18846                try {
18847                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18848                    if (tr == null) {
18849                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18850                    }
18851                    Intent intent = tr.getBaseIntent();
18852                    if (exclude) {
18853                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18854                    } else {
18855                        intent.setFlags(intent.getFlags()
18856                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18857                    }
18858                } finally {
18859                    Binder.restoreCallingIdentity(origId);
18860                }
18861            }
18862        }
18863    }
18864}
18865