ActivityManagerService.java revision a4ccb86ddc8f9f486aee25fb836f4aff97bf7679
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageEvents;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.content.res.Resources;
44import android.graphics.Bitmap;
45import android.graphics.Point;
46import android.graphics.Rect;
47import android.os.BatteryStats;
48import android.os.PersistableBundle;
49import android.service.voice.IVoiceInteractionSession;
50import android.util.ArrayMap;
51import android.util.ArraySet;
52import android.util.SparseIntArray;
53
54import com.android.internal.R;
55import com.android.internal.annotations.GuardedBy;
56import com.android.internal.app.IAppOpsService;
57import com.android.internal.app.IVoiceInteractor;
58import com.android.internal.app.ProcessMap;
59import com.android.internal.app.ProcessStats;
60import com.android.internal.content.PackageMonitor;
61import com.android.internal.os.BackgroundThread;
62import com.android.internal.os.BatteryStatsImpl;
63import com.android.internal.os.ProcessCpuTracker;
64import com.android.internal.os.TransferPipe;
65import com.android.internal.os.Zygote;
66import com.android.internal.util.FastPrintWriter;
67import com.android.internal.util.FastXmlSerializer;
68import com.android.internal.util.MemInfoReader;
69import com.android.internal.util.Preconditions;
70import com.android.server.AppOpsService;
71import com.android.server.AttributeCache;
72import com.android.server.IntentResolver;
73import com.android.server.LocalServices;
74import com.android.server.ServiceThread;
75import com.android.server.SystemService;
76import com.android.server.SystemServiceManager;
77import com.android.server.Watchdog;
78import com.android.server.am.ActivityStack.ActivityState;
79import com.android.server.firewall.IntentFirewall;
80import com.android.server.pm.UserManagerService;
81import com.android.server.wm.AppTransition;
82import com.android.server.wm.WindowManagerService;
83import com.google.android.collect.Lists;
84import com.google.android.collect.Maps;
85
86import libcore.io.IoUtils;
87
88import org.xmlpull.v1.XmlPullParser;
89import org.xmlpull.v1.XmlPullParserException;
90import org.xmlpull.v1.XmlSerializer;
91
92import android.app.Activity;
93import android.app.ActivityManager;
94import android.app.ActivityManager.RunningTaskInfo;
95import android.app.ActivityManager.StackInfo;
96import android.app.ActivityManagerInternal;
97import android.app.ActivityManagerNative;
98import android.app.ActivityOptions;
99import android.app.ActivityThread;
100import android.app.AlertDialog;
101import android.app.AppGlobals;
102import android.app.ApplicationErrorReport;
103import android.app.Dialog;
104import android.app.IActivityController;
105import android.app.IApplicationThread;
106import android.app.IInstrumentationWatcher;
107import android.app.INotificationManager;
108import android.app.IProcessObserver;
109import android.app.IServiceConnection;
110import android.app.IStopUserCallback;
111import android.app.IUiAutomationConnection;
112import android.app.IUserSwitchObserver;
113import android.app.Instrumentation;
114import android.app.Notification;
115import android.app.NotificationManager;
116import android.app.PendingIntent;
117import android.app.backup.IBackupManager;
118import android.content.ActivityNotFoundException;
119import android.content.BroadcastReceiver;
120import android.content.ClipData;
121import android.content.ComponentCallbacks2;
122import android.content.ComponentName;
123import android.content.ContentProvider;
124import android.content.ContentResolver;
125import android.content.Context;
126import android.content.DialogInterface;
127import android.content.IContentProvider;
128import android.content.IIntentReceiver;
129import android.content.IIntentSender;
130import android.content.Intent;
131import android.content.IntentFilter;
132import android.content.IntentSender;
133import android.content.pm.ActivityInfo;
134import android.content.pm.ApplicationInfo;
135import android.content.pm.ConfigurationInfo;
136import android.content.pm.IPackageDataObserver;
137import android.content.pm.IPackageManager;
138import android.content.pm.InstrumentationInfo;
139import android.content.pm.PackageInfo;
140import android.content.pm.PackageManager;
141import android.content.pm.ParceledListSlice;
142import android.content.pm.UserInfo;
143import android.content.pm.PackageManager.NameNotFoundException;
144import android.content.pm.PathPermission;
145import android.content.pm.ProviderInfo;
146import android.content.pm.ResolveInfo;
147import android.content.pm.ServiceInfo;
148import android.content.res.CompatibilityInfo;
149import android.content.res.Configuration;
150import android.net.Proxy;
151import android.net.ProxyInfo;
152import android.net.Uri;
153import android.os.Binder;
154import android.os.Build;
155import android.os.Bundle;
156import android.os.Debug;
157import android.os.DropBoxManager;
158import android.os.Environment;
159import android.os.FactoryTest;
160import android.os.FileObserver;
161import android.os.FileUtils;
162import android.os.Handler;
163import android.os.IBinder;
164import android.os.IPermissionController;
165import android.os.IRemoteCallback;
166import android.os.IUserManager;
167import android.os.Looper;
168import android.os.Message;
169import android.os.Parcel;
170import android.os.ParcelFileDescriptor;
171import android.os.Process;
172import android.os.RemoteCallbackList;
173import android.os.RemoteException;
174import android.os.SELinux;
175import android.os.ServiceManager;
176import android.os.StrictMode;
177import android.os.SystemClock;
178import android.os.SystemProperties;
179import android.os.UpdateLock;
180import android.os.UserHandle;
181import android.provider.Settings;
182import android.text.format.DateUtils;
183import android.text.format.Time;
184import android.util.AtomicFile;
185import android.util.EventLog;
186import android.util.Log;
187import android.util.Pair;
188import android.util.PrintWriterPrinter;
189import android.util.Slog;
190import android.util.SparseArray;
191import android.util.TimeUtils;
192import android.util.Xml;
193import android.view.Gravity;
194import android.view.LayoutInflater;
195import android.view.View;
196import android.view.WindowManager;
197
198import java.io.BufferedInputStream;
199import java.io.BufferedOutputStream;
200import java.io.DataInputStream;
201import java.io.DataOutputStream;
202import java.io.File;
203import java.io.FileDescriptor;
204import java.io.FileInputStream;
205import java.io.FileNotFoundException;
206import java.io.FileOutputStream;
207import java.io.IOException;
208import java.io.InputStreamReader;
209import java.io.PrintWriter;
210import java.io.StringWriter;
211import java.lang.ref.WeakReference;
212import java.util.ArrayList;
213import java.util.Arrays;
214import java.util.Collections;
215import java.util.Comparator;
216import java.util.HashMap;
217import java.util.HashSet;
218import java.util.Iterator;
219import java.util.List;
220import java.util.Locale;
221import java.util.Map;
222import java.util.Set;
223import java.util.concurrent.atomic.AtomicBoolean;
224import java.util.concurrent.atomic.AtomicLong;
225
226public final class ActivityManagerService extends ActivityManagerNative
227        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
228
229    private static final String USER_DATA_DIR = "/data/user/";
230    // File that stores last updated system version and called preboot receivers
231    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
232
233    static final String TAG = "ActivityManager";
234    static final String TAG_MU = "ActivityManagerServiceMU";
235    static final boolean DEBUG = false;
236    static final boolean localLOGV = DEBUG;
237    static final boolean DEBUG_BACKUP = localLOGV || false;
238    static final boolean DEBUG_BROADCAST = localLOGV || false;
239    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
240    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
241    static final boolean DEBUG_CLEANUP = localLOGV || false;
242    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
243    static final boolean DEBUG_FOCUS = false;
244    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
245    static final boolean DEBUG_MU = localLOGV || false;
246    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
247    static final boolean DEBUG_LRU = localLOGV || false;
248    static final boolean DEBUG_PAUSE = localLOGV || false;
249    static final boolean DEBUG_POWER = localLOGV || false;
250    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
251    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
252    static final boolean DEBUG_PROCESSES = localLOGV || false;
253    static final boolean DEBUG_PROVIDER = localLOGV || false;
254    static final boolean DEBUG_RESULTS = localLOGV || false;
255    static final boolean DEBUG_SERVICE = localLOGV || false;
256    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
257    static final boolean DEBUG_STACK = localLOGV || false;
258    static final boolean DEBUG_SWITCH = localLOGV || false;
259    static final boolean DEBUG_TASKS = localLOGV || false;
260    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
261    static final boolean DEBUG_TRANSITION = localLOGV || false;
262    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
263    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
264    static final boolean DEBUG_VISBILITY = localLOGV || false;
265    static final boolean DEBUG_PSS = localLOGV || false;
266    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
267    static final boolean DEBUG_RECENTS = localLOGV || false;
268    static final boolean VALIDATE_TOKENS = false;
269    static final boolean SHOW_ACTIVITY_START_TIME = true;
270
271    // Control over CPU and battery monitoring.
272    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
273    static final boolean MONITOR_CPU_USAGE = true;
274    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
275    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
276    static final boolean MONITOR_THREAD_CPU_USAGE = false;
277
278    // The flags that are set for all calls we make to the package manager.
279    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
280
281    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
282
283    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
284
285    // Maximum number of recent tasks that we can remember.
286    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
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 mProfileType = 0;
1053    boolean mAutoStopProfiler = false;
1054    String mOpenGlTraceApp = null;
1055
1056    static class ProcessChangeItem {
1057        static final int CHANGE_ACTIVITIES = 1<<0;
1058        static final int CHANGE_PROCESS_STATE = 1<<1;
1059        int changes;
1060        int uid;
1061        int pid;
1062        int processState;
1063        boolean foregroundActivities;
1064    }
1065
1066    final RemoteCallbackList<IProcessObserver> mProcessObservers
1067            = new RemoteCallbackList<IProcessObserver>();
1068    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1069
1070    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074
1075    /**
1076     * Runtime CPU use collection thread.  This object's lock is used to
1077     * protect all related state.
1078     */
1079    final Thread mProcessCpuThread;
1080
1081    /**
1082     * Used to collect process stats when showing not responding dialog.
1083     * Protected by mProcessCpuThread.
1084     */
1085    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1086            MONITOR_THREAD_CPU_USAGE);
1087    final AtomicLong mLastCpuTime = new AtomicLong(0);
1088    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1089
1090    long mLastWriteTime = 0;
1091
1092    /**
1093     * Used to retain an update lock when the foreground activity is in
1094     * immersive mode.
1095     */
1096    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1097
1098    /**
1099     * Set to true after the system has finished booting.
1100     */
1101    boolean mBooted = false;
1102
1103    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1104    int mProcessLimitOverride = -1;
1105
1106    WindowManagerService mWindowManager;
1107
1108    final ActivityThread mSystemThread;
1109
1110    int mCurrentUserId = 0;
1111    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1112
1113    /**
1114     * Mapping from each known user ID to the profile group ID it is associated with.
1115     */
1116    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1117
1118    private UserManagerService mUserManager;
1119
1120    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1121        final ProcessRecord mApp;
1122        final int mPid;
1123        final IApplicationThread mAppThread;
1124
1125        AppDeathRecipient(ProcessRecord app, int pid,
1126                IApplicationThread thread) {
1127            if (localLOGV) Slog.v(
1128                TAG, "New death recipient " + this
1129                + " for thread " + thread.asBinder());
1130            mApp = app;
1131            mPid = pid;
1132            mAppThread = thread;
1133        }
1134
1135        @Override
1136        public void binderDied() {
1137            if (localLOGV) Slog.v(
1138                TAG, "Death received in " + this
1139                + " for thread " + mAppThread.asBinder());
1140            synchronized(ActivityManagerService.this) {
1141                appDiedLocked(mApp, mPid, mAppThread);
1142            }
1143        }
1144    }
1145
1146    static final int SHOW_ERROR_MSG = 1;
1147    static final int SHOW_NOT_RESPONDING_MSG = 2;
1148    static final int SHOW_FACTORY_ERROR_MSG = 3;
1149    static final int UPDATE_CONFIGURATION_MSG = 4;
1150    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1151    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1152    static final int SERVICE_TIMEOUT_MSG = 12;
1153    static final int UPDATE_TIME_ZONE = 13;
1154    static final int SHOW_UID_ERROR_MSG = 14;
1155    static final int IM_FEELING_LUCKY_MSG = 15;
1156    static final int PROC_START_TIMEOUT_MSG = 20;
1157    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1158    static final int KILL_APPLICATION_MSG = 22;
1159    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1160    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1161    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1162    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1163    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1164    static final int CLEAR_DNS_CACHE_MSG = 28;
1165    static final int UPDATE_HTTP_PROXY_MSG = 29;
1166    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1167    static final int DISPATCH_PROCESSES_CHANGED = 31;
1168    static final int DISPATCH_PROCESS_DIED = 32;
1169    static final int REPORT_MEM_USAGE_MSG = 33;
1170    static final int REPORT_USER_SWITCH_MSG = 34;
1171    static final int CONTINUE_USER_SWITCH_MSG = 35;
1172    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1173    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1174    static final int PERSIST_URI_GRANTS_MSG = 38;
1175    static final int REQUEST_ALL_PSS_MSG = 39;
1176    static final int START_PROFILES_MSG = 40;
1177    static final int UPDATE_TIME = 41;
1178    static final int SYSTEM_USER_START_MSG = 42;
1179    static final int SYSTEM_USER_CURRENT_MSG = 43;
1180    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1181    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1182
1183    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1184    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1185    static final int FIRST_COMPAT_MODE_MSG = 300;
1186    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1187
1188    AlertDialog mUidAlert;
1189    CompatModeDialog mCompatModeDialog;
1190    long mLastMemUsageReportTime = 0;
1191
1192    private LockToAppRequestDialog mLockToAppRequest;
1193
1194    /**
1195     * Flag whether the current user is a "monkey", i.e. whether
1196     * the UI is driven by a UI automation tool.
1197     */
1198    private boolean mUserIsMonkey;
1199
1200    /** Flag whether the device has a recents UI */
1201    final boolean mHasRecents;
1202
1203    final int mThumbnailWidth;
1204    final int mThumbnailHeight;
1205
1206    final ServiceThread mHandlerThread;
1207    final MainHandler mHandler;
1208
1209    final class MainHandler extends Handler {
1210        public MainHandler(Looper looper) {
1211            super(looper, null, true);
1212        }
1213
1214        @Override
1215        public void handleMessage(Message msg) {
1216            switch (msg.what) {
1217            case SHOW_ERROR_MSG: {
1218                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1219                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1220                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1221                synchronized (ActivityManagerService.this) {
1222                    ProcessRecord proc = (ProcessRecord)data.get("app");
1223                    AppErrorResult res = (AppErrorResult) data.get("result");
1224                    if (proc != null && proc.crashDialog != null) {
1225                        Slog.e(TAG, "App already has crash dialog: " + proc);
1226                        if (res != null) {
1227                            res.set(0);
1228                        }
1229                        return;
1230                    }
1231                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1232                            >= Process.FIRST_APPLICATION_UID
1233                            && proc.pid != MY_PID);
1234                    for (int userId : mCurrentProfileIds) {
1235                        isBackground &= (proc.userId != userId);
1236                    }
1237                    if (isBackground && !showBackground) {
1238                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1239                        if (res != null) {
1240                            res.set(0);
1241                        }
1242                        return;
1243                    }
1244                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1245                        Dialog d = new AppErrorDialog(mContext,
1246                                ActivityManagerService.this, res, proc);
1247                        d.show();
1248                        proc.crashDialog = d;
1249                    } else {
1250                        // The device is asleep, so just pretend that the user
1251                        // saw a crash dialog and hit "force quit".
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                    }
1256                }
1257
1258                ensureBootCompleted();
1259            } break;
1260            case SHOW_NOT_RESPONDING_MSG: {
1261                synchronized (ActivityManagerService.this) {
1262                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1263                    ProcessRecord proc = (ProcessRecord)data.get("app");
1264                    if (proc != null && proc.anrDialog != null) {
1265                        Slog.e(TAG, "App already has anr dialog: " + proc);
1266                        return;
1267                    }
1268
1269                    Intent intent = new Intent("android.intent.action.ANR");
1270                    if (!mProcessesReady) {
1271                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1272                                | Intent.FLAG_RECEIVER_FOREGROUND);
1273                    }
1274                    broadcastIntentLocked(null, null, intent,
1275                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1276                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1277
1278                    if (mShowDialogs) {
1279                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1280                                mContext, proc, (ActivityRecord)data.get("activity"),
1281                                msg.arg1 != 0);
1282                        d.show();
1283                        proc.anrDialog = d;
1284                    } else {
1285                        // Just kill the app if there is no dialog to be shown.
1286                        killAppAtUsersRequest(proc, null);
1287                    }
1288                }
1289
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1293                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1294                synchronized (ActivityManagerService.this) {
1295                    ProcessRecord proc = (ProcessRecord) data.get("app");
1296                    if (proc == null) {
1297                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1298                        break;
1299                    }
1300                    if (proc.crashDialog != null) {
1301                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1302                        return;
1303                    }
1304                    AppErrorResult res = (AppErrorResult) data.get("result");
1305                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1306                        Dialog d = new StrictModeViolationDialog(mContext,
1307                                ActivityManagerService.this, res, proc);
1308                        d.show();
1309                        proc.crashDialog = d;
1310                    } else {
1311                        // The device is asleep, so just pretend that the user
1312                        // saw a crash dialog and hit "force quit".
1313                        res.set(0);
1314                    }
1315                }
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_FACTORY_ERROR_MSG: {
1319                Dialog d = new FactoryErrorDialog(
1320                    mContext, msg.getData().getCharSequence("msg"));
1321                d.show();
1322                ensureBootCompleted();
1323            } break;
1324            case UPDATE_CONFIGURATION_MSG: {
1325                final ContentResolver resolver = mContext.getContentResolver();
1326                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1327            } break;
1328            case GC_BACKGROUND_PROCESSES_MSG: {
1329                synchronized (ActivityManagerService.this) {
1330                    performAppGcsIfAppropriateLocked();
1331                }
1332            } break;
1333            case WAIT_FOR_DEBUGGER_MSG: {
1334                synchronized (ActivityManagerService.this) {
1335                    ProcessRecord app = (ProcessRecord)msg.obj;
1336                    if (msg.arg1 != 0) {
1337                        if (!app.waitedForDebugger) {
1338                            Dialog d = new AppWaitingForDebuggerDialog(
1339                                    ActivityManagerService.this,
1340                                    mContext, app);
1341                            app.waitDialog = d;
1342                            app.waitedForDebugger = true;
1343                            d.show();
1344                        }
1345                    } else {
1346                        if (app.waitDialog != null) {
1347                            app.waitDialog.dismiss();
1348                            app.waitDialog = null;
1349                        }
1350                    }
1351                }
1352            } break;
1353            case SERVICE_TIMEOUT_MSG: {
1354                if (mDidDexOpt) {
1355                    mDidDexOpt = false;
1356                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1357                    nmsg.obj = msg.obj;
1358                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1359                    return;
1360                }
1361                mServices.serviceTimeout((ProcessRecord)msg.obj);
1362            } break;
1363            case UPDATE_TIME_ZONE: {
1364                synchronized (ActivityManagerService.this) {
1365                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1366                        ProcessRecord r = mLruProcesses.get(i);
1367                        if (r.thread != null) {
1368                            try {
1369                                r.thread.updateTimeZone();
1370                            } catch (RemoteException ex) {
1371                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1372                            }
1373                        }
1374                    }
1375                }
1376            } break;
1377            case CLEAR_DNS_CACHE_MSG: {
1378                synchronized (ActivityManagerService.this) {
1379                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1380                        ProcessRecord r = mLruProcesses.get(i);
1381                        if (r.thread != null) {
1382                            try {
1383                                r.thread.clearDnsCache();
1384                            } catch (RemoteException ex) {
1385                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case UPDATE_HTTP_PROXY_MSG: {
1392                ProxyInfo proxy = (ProxyInfo)msg.obj;
1393                String host = "";
1394                String port = "";
1395                String exclList = "";
1396                Uri pacFileUrl = Uri.EMPTY;
1397                if (proxy != null) {
1398                    host = proxy.getHost();
1399                    port = Integer.toString(proxy.getPort());
1400                    exclList = proxy.getExclusionListAsString();
1401                    pacFileUrl = proxy.getPacFileUrl();
1402                }
1403                synchronized (ActivityManagerService.this) {
1404                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1405                        ProcessRecord r = mLruProcesses.get(i);
1406                        if (r.thread != null) {
1407                            try {
1408                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1409                            } catch (RemoteException ex) {
1410                                Slog.w(TAG, "Failed to update http proxy for: " +
1411                                        r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case SHOW_UID_ERROR_MSG: {
1418                String title = "System UIDs Inconsistent";
1419                String text = "UIDs on the system are inconsistent, you need to wipe your"
1420                        + " data partition or your device will be unstable.";
1421                Log.e(TAG, title + ": " + text);
1422                if (mShowDialogs) {
1423                    // XXX This is a temporary dialog, no need to localize.
1424                    AlertDialog d = new BaseErrorDialog(mContext);
1425                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1426                    d.setCancelable(false);
1427                    d.setTitle(title);
1428                    d.setMessage(text);
1429                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1430                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1431                    mUidAlert = d;
1432                    d.show();
1433                }
1434            } break;
1435            case IM_FEELING_LUCKY_MSG: {
1436                if (mUidAlert != null) {
1437                    mUidAlert.dismiss();
1438                    mUidAlert = null;
1439                }
1440            } break;
1441            case PROC_START_TIMEOUT_MSG: {
1442                if (mDidDexOpt) {
1443                    mDidDexOpt = false;
1444                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1445                    nmsg.obj = msg.obj;
1446                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1447                    return;
1448                }
1449                ProcessRecord app = (ProcessRecord)msg.obj;
1450                synchronized (ActivityManagerService.this) {
1451                    processStartTimedOutLocked(app);
1452                }
1453            } break;
1454            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1455                synchronized (ActivityManagerService.this) {
1456                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1457                }
1458            } break;
1459            case KILL_APPLICATION_MSG: {
1460                synchronized (ActivityManagerService.this) {
1461                    int appid = msg.arg1;
1462                    boolean restart = (msg.arg2 == 1);
1463                    Bundle bundle = (Bundle)msg.obj;
1464                    String pkg = bundle.getString("pkg");
1465                    String reason = bundle.getString("reason");
1466                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1467                            false, UserHandle.USER_ALL, reason);
1468                }
1469            } break;
1470            case FINALIZE_PENDING_INTENT_MSG: {
1471                ((PendingIntentRecord)msg.obj).completeFinalize();
1472            } break;
1473            case POST_HEAVY_NOTIFICATION_MSG: {
1474                INotificationManager inm = NotificationManager.getService();
1475                if (inm == null) {
1476                    return;
1477                }
1478
1479                ActivityRecord root = (ActivityRecord)msg.obj;
1480                ProcessRecord process = root.app;
1481                if (process == null) {
1482                    return;
1483                }
1484
1485                try {
1486                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1487                    String text = mContext.getString(R.string.heavy_weight_notification,
1488                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1489                    Notification notification = new Notification();
1490                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1491                    notification.when = 0;
1492                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1493                    notification.tickerText = text;
1494                    notification.defaults = 0; // please be quiet
1495                    notification.sound = null;
1496                    notification.vibrate = null;
1497                    notification.color = mContext.getResources().getColor(
1498                            com.android.internal.R.color.system_notification_accent_color);
1499                    notification.setLatestEventInfo(context, text,
1500                            mContext.getText(R.string.heavy_weight_notification_detail),
1501                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1502                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1503                                    new UserHandle(root.userId)));
1504
1505                    try {
1506                        int[] outId = new int[1];
1507                        inm.enqueueNotificationWithTag("android", "android", null,
1508                                R.string.heavy_weight_notification,
1509                                notification, outId, root.userId);
1510                    } catch (RuntimeException e) {
1511                        Slog.w(ActivityManagerService.TAG,
1512                                "Error showing notification for heavy-weight app", e);
1513                    } catch (RemoteException e) {
1514                    }
1515                } catch (NameNotFoundException e) {
1516                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1517                }
1518            } break;
1519            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1520                INotificationManager inm = NotificationManager.getService();
1521                if (inm == null) {
1522                    return;
1523                }
1524                try {
1525                    inm.cancelNotificationWithTag("android", null,
1526                            R.string.heavy_weight_notification,  msg.arg1);
1527                } catch (RuntimeException e) {
1528                    Slog.w(ActivityManagerService.TAG,
1529                            "Error canceling notification for service", e);
1530                } catch (RemoteException e) {
1531                }
1532            } break;
1533            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1534                synchronized (ActivityManagerService.this) {
1535                    checkExcessivePowerUsageLocked(true);
1536                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1537                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1538                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1539                }
1540            } break;
1541            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1542                synchronized (ActivityManagerService.this) {
1543                    ActivityRecord ar = (ActivityRecord)msg.obj;
1544                    if (mCompatModeDialog != null) {
1545                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1546                                ar.info.applicationInfo.packageName)) {
1547                            return;
1548                        }
1549                        mCompatModeDialog.dismiss();
1550                        mCompatModeDialog = null;
1551                    }
1552                    if (ar != null && false) {
1553                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1554                                ar.packageName)) {
1555                            int mode = mCompatModePackages.computeCompatModeLocked(
1556                                    ar.info.applicationInfo);
1557                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1558                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1559                                mCompatModeDialog = new CompatModeDialog(
1560                                        ActivityManagerService.this, mContext,
1561                                        ar.info.applicationInfo);
1562                                mCompatModeDialog.show();
1563                            }
1564                        }
1565                    }
1566                }
1567                break;
1568            }
1569            case DISPATCH_PROCESSES_CHANGED: {
1570                dispatchProcessesChanged();
1571                break;
1572            }
1573            case DISPATCH_PROCESS_DIED: {
1574                final int pid = msg.arg1;
1575                final int uid = msg.arg2;
1576                dispatchProcessDied(pid, uid);
1577                break;
1578            }
1579            case REPORT_MEM_USAGE_MSG: {
1580                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1581                Thread thread = new Thread() {
1582                    @Override public void run() {
1583                        final SparseArray<ProcessMemInfo> infoMap
1584                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            infoMap.put(mi.pid, mi);
1588                        }
1589                        updateCpuStatsNow();
1590                        synchronized (mProcessCpuThread) {
1591                            final int N = mProcessCpuTracker.countStats();
1592                            for (int i=0; i<N; i++) {
1593                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1594                                if (st.vsize > 0) {
1595                                    long pss = Debug.getPss(st.pid, null);
1596                                    if (pss > 0) {
1597                                        if (infoMap.indexOfKey(st.pid) < 0) {
1598                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1599                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1600                                            mi.pss = pss;
1601                                            memInfos.add(mi);
1602                                        }
1603                                    }
1604                                }
1605                            }
1606                        }
1607
1608                        long totalPss = 0;
1609                        for (int i=0, N=memInfos.size(); i<N; i++) {
1610                            ProcessMemInfo mi = memInfos.get(i);
1611                            if (mi.pss == 0) {
1612                                mi.pss = Debug.getPss(mi.pid, null);
1613                            }
1614                            totalPss += mi.pss;
1615                        }
1616                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1617                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1618                                if (lhs.oomAdj != rhs.oomAdj) {
1619                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1620                                }
1621                                if (lhs.pss != rhs.pss) {
1622                                    return lhs.pss < rhs.pss ? 1 : -1;
1623                                }
1624                                return 0;
1625                            }
1626                        });
1627
1628                        StringBuilder tag = new StringBuilder(128);
1629                        StringBuilder stack = new StringBuilder(128);
1630                        tag.append("Low on memory -- ");
1631                        appendMemBucket(tag, totalPss, "total", false);
1632                        appendMemBucket(stack, totalPss, "total", true);
1633
1634                        StringBuilder logBuilder = new StringBuilder(1024);
1635                        logBuilder.append("Low on memory:\n");
1636
1637                        boolean firstLine = true;
1638                        int lastOomAdj = Integer.MIN_VALUE;
1639                        for (int i=0, N=memInfos.size(); i<N; i++) {
1640                            ProcessMemInfo mi = memInfos.get(i);
1641
1642                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1643                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1644                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1645                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1646                                if (lastOomAdj != mi.oomAdj) {
1647                                    lastOomAdj = mi.oomAdj;
1648                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1649                                        tag.append(" / ");
1650                                    }
1651                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1652                                        if (firstLine) {
1653                                            stack.append(":");
1654                                            firstLine = false;
1655                                        }
1656                                        stack.append("\n\t at ");
1657                                    } else {
1658                                        stack.append("$");
1659                                    }
1660                                } else {
1661                                    tag.append(" ");
1662                                    stack.append("$");
1663                                }
1664                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1665                                    appendMemBucket(tag, mi.pss, mi.name, false);
1666                                }
1667                                appendMemBucket(stack, mi.pss, mi.name, true);
1668                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1669                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1670                                    stack.append("(");
1671                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1672                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1673                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1674                                            stack.append(":");
1675                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1676                                        }
1677                                    }
1678                                    stack.append(")");
1679                                }
1680                            }
1681
1682                            logBuilder.append("  ");
1683                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1684                            logBuilder.append(' ');
1685                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1686                            logBuilder.append(' ');
1687                            ProcessList.appendRamKb(logBuilder, mi.pss);
1688                            logBuilder.append(" kB: ");
1689                            logBuilder.append(mi.name);
1690                            logBuilder.append(" (");
1691                            logBuilder.append(mi.pid);
1692                            logBuilder.append(") ");
1693                            logBuilder.append(mi.adjType);
1694                            logBuilder.append('\n');
1695                            if (mi.adjReason != null) {
1696                                logBuilder.append("                      ");
1697                                logBuilder.append(mi.adjReason);
1698                                logBuilder.append('\n');
1699                            }
1700                        }
1701
1702                        logBuilder.append("           ");
1703                        ProcessList.appendRamKb(logBuilder, totalPss);
1704                        logBuilder.append(" kB: TOTAL\n");
1705
1706                        long[] infos = new long[Debug.MEMINFO_COUNT];
1707                        Debug.getMemInfo(infos);
1708                        logBuilder.append("  MemInfo: ");
1709                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1710                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1711                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1714                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1715                            logBuilder.append("  ZRAM: ");
1716                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1717                            logBuilder.append(" kB RAM, ");
1718                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1719                            logBuilder.append(" kB swap total, ");
1720                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1721                            logBuilder.append(" kB swap free\n");
1722                        }
1723                        Slog.i(TAG, logBuilder.toString());
1724
1725                        StringBuilder dropBuilder = new StringBuilder(1024);
1726                        /*
1727                        StringWriter oomSw = new StringWriter();
1728                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1729                        StringWriter catSw = new StringWriter();
1730                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1731                        String[] emptyArgs = new String[] { };
1732                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1733                        oomPw.flush();
1734                        String oomString = oomSw.toString();
1735                        */
1736                        dropBuilder.append(stack);
1737                        dropBuilder.append('\n');
1738                        dropBuilder.append('\n');
1739                        dropBuilder.append(logBuilder);
1740                        dropBuilder.append('\n');
1741                        /*
1742                        dropBuilder.append(oomString);
1743                        dropBuilder.append('\n');
1744                        */
1745                        StringWriter catSw = new StringWriter();
1746                        synchronized (ActivityManagerService.this) {
1747                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1748                            String[] emptyArgs = new String[] { };
1749                            catPw.println();
1750                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1751                            catPw.println();
1752                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1753                                    false, false, null);
1754                            catPw.println();
1755                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1756                            catPw.flush();
1757                        }
1758                        dropBuilder.append(catSw.toString());
1759                        addErrorToDropBox("lowmem", null, "system_server", null,
1760                                null, tag.toString(), dropBuilder.toString(), null, null);
1761                        //Slog.i(TAG, "Sent to dropbox:");
1762                        //Slog.i(TAG, dropBuilder.toString());
1763                        synchronized (ActivityManagerService.this) {
1764                            long now = SystemClock.uptimeMillis();
1765                            if (mLastMemUsageReportTime < now) {
1766                                mLastMemUsageReportTime = now;
1767                            }
1768                        }
1769                    }
1770                };
1771                thread.start();
1772                break;
1773            }
1774            case REPORT_USER_SWITCH_MSG: {
1775                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1776                break;
1777            }
1778            case CONTINUE_USER_SWITCH_MSG: {
1779                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1780                break;
1781            }
1782            case USER_SWITCH_TIMEOUT_MSG: {
1783                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1784                break;
1785            }
1786            case IMMERSIVE_MODE_LOCK_MSG: {
1787                final boolean nextState = (msg.arg1 != 0);
1788                if (mUpdateLock.isHeld() != nextState) {
1789                    if (DEBUG_IMMERSIVE) {
1790                        final ActivityRecord r = (ActivityRecord) msg.obj;
1791                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1792                    }
1793                    if (nextState) {
1794                        mUpdateLock.acquire();
1795                    } else {
1796                        mUpdateLock.release();
1797                    }
1798                }
1799                break;
1800            }
1801            case PERSIST_URI_GRANTS_MSG: {
1802                writeGrantedUriPermissions();
1803                break;
1804            }
1805            case REQUEST_ALL_PSS_MSG: {
1806                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1807                break;
1808            }
1809            case START_PROFILES_MSG: {
1810                synchronized (ActivityManagerService.this) {
1811                    startProfilesLocked();
1812                }
1813                break;
1814            }
1815            case UPDATE_TIME: {
1816                synchronized (ActivityManagerService.this) {
1817                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1818                        ProcessRecord r = mLruProcesses.get(i);
1819                        if (r.thread != null) {
1820                            try {
1821                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1822                            } catch (RemoteException ex) {
1823                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1824                            }
1825                        }
1826                    }
1827                }
1828                break;
1829            }
1830            case SYSTEM_USER_START_MSG: {
1831                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1832                        Integer.toString(msg.arg1), msg.arg1);
1833                mSystemServiceManager.startUser(msg.arg1);
1834                break;
1835            }
1836            case SYSTEM_USER_CURRENT_MSG: {
1837                mBatteryStatsService.noteEvent(
1838                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1839                        Integer.toString(msg.arg2), msg.arg2);
1840                mBatteryStatsService.noteEvent(
1841                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1842                        Integer.toString(msg.arg1), msg.arg1);
1843                mSystemServiceManager.switchUser(msg.arg1);
1844                mLockToAppRequest.clearPrompt();
1845                break;
1846            }
1847            case ENTER_ANIMATION_COMPLETE_MSG: {
1848                synchronized (ActivityManagerService.this) {
1849                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1850                    if (r != null && r.app != null && r.app.thread != null) {
1851                        try {
1852                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1853                        } catch (RemoteException e) {
1854                        }
1855                    }
1856                }
1857                break;
1858            }
1859            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1860                enableScreenAfterBoot();
1861                break;
1862            }
1863            }
1864        }
1865    };
1866
1867    static final int COLLECT_PSS_BG_MSG = 1;
1868
1869    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1870        @Override
1871        public void handleMessage(Message msg) {
1872            switch (msg.what) {
1873            case COLLECT_PSS_BG_MSG: {
1874                long start = SystemClock.uptimeMillis();
1875                MemInfoReader memInfo = null;
1876                synchronized (ActivityManagerService.this) {
1877                    if (mFullPssPending) {
1878                        mFullPssPending = false;
1879                        memInfo = new MemInfoReader();
1880                    }
1881                }
1882                if (memInfo != null) {
1883                    updateCpuStatsNow();
1884                    long nativeTotalPss = 0;
1885                    synchronized (mProcessCpuThread) {
1886                        final int N = mProcessCpuTracker.countStats();
1887                        for (int j=0; j<N; j++) {
1888                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1889                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1890                                // This is definitely an application process; skip it.
1891                                continue;
1892                            }
1893                            synchronized (mPidsSelfLocked) {
1894                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1895                                    // This is one of our own processes; skip it.
1896                                    continue;
1897                                }
1898                            }
1899                            nativeTotalPss += Debug.getPss(st.pid, null);
1900                        }
1901                    }
1902                    memInfo.readMemInfo();
1903                    synchronized (this) {
1904                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1905                                + (SystemClock.uptimeMillis()-start) + "ms");
1906                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1907                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1908                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1909                                        +memInfo.getSlabSizeKb(),
1910                                nativeTotalPss);
1911                    }
1912                }
1913
1914                int i=0, num=0;
1915                long[] tmp = new long[1];
1916                do {
1917                    ProcessRecord proc;
1918                    int procState;
1919                    int pid;
1920                    synchronized (ActivityManagerService.this) {
1921                        if (i >= mPendingPssProcesses.size()) {
1922                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1923                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1924                            mPendingPssProcesses.clear();
1925                            return;
1926                        }
1927                        proc = mPendingPssProcesses.get(i);
1928                        procState = proc.pssProcState;
1929                        if (proc.thread != null && procState == proc.setProcState) {
1930                            pid = proc.pid;
1931                        } else {
1932                            proc = null;
1933                            pid = 0;
1934                        }
1935                        i++;
1936                    }
1937                    if (proc != null) {
1938                        long pss = Debug.getPss(pid, tmp);
1939                        synchronized (ActivityManagerService.this) {
1940                            if (proc.thread != null && proc.setProcState == procState
1941                                    && proc.pid == pid) {
1942                                num++;
1943                                proc.lastPssTime = SystemClock.uptimeMillis();
1944                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1945                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1946                                        + ": " + pss + " lastPss=" + proc.lastPss
1947                                        + " state=" + ProcessList.makeProcStateString(procState));
1948                                if (proc.initialIdlePss == 0) {
1949                                    proc.initialIdlePss = pss;
1950                                }
1951                                proc.lastPss = pss;
1952                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1953                                    proc.lastCachedPss = pss;
1954                                }
1955                            }
1956                        }
1957                    }
1958                } while (true);
1959            }
1960            }
1961        }
1962    };
1963
1964    /**
1965     * Monitor for package changes and update our internal state.
1966     */
1967    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1968        @Override
1969        public void onPackageRemoved(String packageName, int uid) {
1970            // Remove all tasks with activities in the specified package from the list of recent tasks
1971            synchronized (ActivityManagerService.this) {
1972                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1973                    TaskRecord tr = mRecentTasks.get(i);
1974                    ComponentName cn = tr.intent.getComponent();
1975                    if (cn != null && cn.getPackageName().equals(packageName)) {
1976                        // If the package name matches, remove the task and kill the process
1977                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1978                    }
1979                }
1980            }
1981        }
1982
1983        @Override
1984        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1985            onPackageModified(packageName);
1986            return true;
1987        }
1988
1989        @Override
1990        public void onPackageModified(String packageName) {
1991            final PackageManager pm = mContext.getPackageManager();
1992            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1993                    new ArrayList<Pair<Intent, Integer>>();
1994            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1995            // Copy the list of recent tasks so that we don't hold onto the lock on
1996            // ActivityManagerService for long periods while checking if components exist.
1997            synchronized (ActivityManagerService.this) {
1998                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1999                    TaskRecord tr = mRecentTasks.get(i);
2000                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2001                }
2002            }
2003            // Check the recent tasks and filter out all tasks with components that no longer exist.
2004            Intent tmpI = new Intent();
2005            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2006                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2007                ComponentName cn = p.first.getComponent();
2008                if (cn != null && cn.getPackageName().equals(packageName)) {
2009                    try {
2010                        // Add the task to the list to remove if the component no longer exists
2011                        tmpI.setComponent(cn);
2012                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2013                            tasksToRemove.add(p.second);
2014                        }
2015                    } catch (Exception e) {}
2016                }
2017            }
2018            // Prune all the tasks with removed components from the list of recent tasks
2019            synchronized (ActivityManagerService.this) {
2020                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2021                    // Remove the task but don't kill the process (since other components in that
2022                    // package may still be running and in the background)
2023                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2024                }
2025            }
2026        }
2027
2028        @Override
2029        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2030            // Force stop the specified packages
2031            if (packages != null) {
2032                for (String pkg : packages) {
2033                    synchronized (ActivityManagerService.this) {
2034                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2035                                "finished booting")) {
2036                            return true;
2037                        }
2038                    }
2039                }
2040            }
2041            return false;
2042        }
2043    };
2044
2045    public void setSystemProcess() {
2046        try {
2047            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2048            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2049            ServiceManager.addService("meminfo", new MemBinder(this));
2050            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2051            ServiceManager.addService("dbinfo", new DbBinder(this));
2052            if (MONITOR_CPU_USAGE) {
2053                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2054            }
2055            ServiceManager.addService("permission", new PermissionController(this));
2056
2057            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2058                    "android", STOCK_PM_FLAGS);
2059            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2060
2061            synchronized (this) {
2062                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2063                app.persistent = true;
2064                app.pid = MY_PID;
2065                app.maxAdj = ProcessList.SYSTEM_ADJ;
2066                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2067                mProcessNames.put(app.processName, app.uid, app);
2068                synchronized (mPidsSelfLocked) {
2069                    mPidsSelfLocked.put(app.pid, app);
2070                }
2071                updateLruProcessLocked(app, false, null);
2072                updateOomAdjLocked();
2073            }
2074        } catch (PackageManager.NameNotFoundException e) {
2075            throw new RuntimeException(
2076                    "Unable to find android system package", e);
2077        }
2078    }
2079
2080    public void setWindowManager(WindowManagerService wm) {
2081        mWindowManager = wm;
2082        mStackSupervisor.setWindowManager(wm);
2083    }
2084
2085    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2086        mUsageStatsService = usageStatsManager;
2087    }
2088
2089    public void startObservingNativeCrashes() {
2090        final NativeCrashListener ncl = new NativeCrashListener(this);
2091        ncl.start();
2092    }
2093
2094    public IAppOpsService getAppOpsService() {
2095        return mAppOpsService;
2096    }
2097
2098    static class MemBinder extends Binder {
2099        ActivityManagerService mActivityManagerService;
2100        MemBinder(ActivityManagerService activityManagerService) {
2101            mActivityManagerService = activityManagerService;
2102        }
2103
2104        @Override
2105        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2106            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2107                    != PackageManager.PERMISSION_GRANTED) {
2108                pw.println("Permission Denial: can't dump meminfo from from pid="
2109                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2110                        + " without permission " + android.Manifest.permission.DUMP);
2111                return;
2112            }
2113
2114            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2115        }
2116    }
2117
2118    static class GraphicsBinder extends Binder {
2119        ActivityManagerService mActivityManagerService;
2120        GraphicsBinder(ActivityManagerService activityManagerService) {
2121            mActivityManagerService = activityManagerService;
2122        }
2123
2124        @Override
2125        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2126            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2127                    != PackageManager.PERMISSION_GRANTED) {
2128                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2129                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2130                        + " without permission " + android.Manifest.permission.DUMP);
2131                return;
2132            }
2133
2134            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2135        }
2136    }
2137
2138    static class DbBinder extends Binder {
2139        ActivityManagerService mActivityManagerService;
2140        DbBinder(ActivityManagerService activityManagerService) {
2141            mActivityManagerService = activityManagerService;
2142        }
2143
2144        @Override
2145        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2146            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2147                    != PackageManager.PERMISSION_GRANTED) {
2148                pw.println("Permission Denial: can't dump dbinfo from from pid="
2149                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2150                        + " without permission " + android.Manifest.permission.DUMP);
2151                return;
2152            }
2153
2154            mActivityManagerService.dumpDbInfo(fd, pw, args);
2155        }
2156    }
2157
2158    static class CpuBinder extends Binder {
2159        ActivityManagerService mActivityManagerService;
2160        CpuBinder(ActivityManagerService activityManagerService) {
2161            mActivityManagerService = activityManagerService;
2162        }
2163
2164        @Override
2165        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2166            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2167                    != PackageManager.PERMISSION_GRANTED) {
2168                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2169                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2170                        + " without permission " + android.Manifest.permission.DUMP);
2171                return;
2172            }
2173
2174            synchronized (mActivityManagerService.mProcessCpuThread) {
2175                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2176                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2177                        SystemClock.uptimeMillis()));
2178            }
2179        }
2180    }
2181
2182    public static final class Lifecycle extends SystemService {
2183        private final ActivityManagerService mService;
2184
2185        public Lifecycle(Context context) {
2186            super(context);
2187            mService = new ActivityManagerService(context);
2188        }
2189
2190        @Override
2191        public void onStart() {
2192            mService.start();
2193        }
2194
2195        public ActivityManagerService getService() {
2196            return mService;
2197        }
2198    }
2199
2200    // Note: This method is invoked on the main thread but may need to attach various
2201    // handlers to other threads.  So take care to be explicit about the looper.
2202    public ActivityManagerService(Context systemContext) {
2203        mContext = systemContext;
2204        mFactoryTest = FactoryTest.getMode();
2205        mSystemThread = ActivityThread.currentActivityThread();
2206
2207        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2208
2209        mHandlerThread = new ServiceThread(TAG,
2210                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2211        mHandlerThread.start();
2212        mHandler = new MainHandler(mHandlerThread.getLooper());
2213
2214        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2215                "foreground", BROADCAST_FG_TIMEOUT, false);
2216        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2217                "background", BROADCAST_BG_TIMEOUT, true);
2218        mBroadcastQueues[0] = mFgBroadcastQueue;
2219        mBroadcastQueues[1] = mBgBroadcastQueue;
2220
2221        mServices = new ActiveServices(this);
2222        mProviderMap = new ProviderMap(this);
2223
2224        // TODO: Move creation of battery stats service outside of activity manager service.
2225        File dataDir = Environment.getDataDirectory();
2226        File systemDir = new File(dataDir, "system");
2227        systemDir.mkdirs();
2228        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2229        mBatteryStatsService.getActiveStatistics().readLocked();
2230        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2231        mOnBattery = DEBUG_POWER ? true
2232                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2233        mBatteryStatsService.getActiveStatistics().setCallback(this);
2234
2235        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2236
2237        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2238
2239        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2240
2241        // User 0 is the first and only user that runs at boot.
2242        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2243        mUserLru.add(Integer.valueOf(0));
2244        updateStartedUserArrayLocked();
2245
2246        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2247            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2248
2249        mConfiguration.setToDefaults();
2250        mConfiguration.setLocale(Locale.getDefault());
2251
2252        mConfigurationSeq = mConfiguration.seq = 1;
2253        mProcessCpuTracker.init();
2254
2255        final Resources res = mContext.getResources();
2256        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2257        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2258        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2259
2260        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2261        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2262        mStackSupervisor = new ActivityStackSupervisor(this);
2263        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2264
2265        mProcessCpuThread = new Thread("CpuTracker") {
2266            @Override
2267            public void run() {
2268                while (true) {
2269                    try {
2270                        try {
2271                            synchronized(this) {
2272                                final long now = SystemClock.uptimeMillis();
2273                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2274                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2275                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2276                                //        + ", write delay=" + nextWriteDelay);
2277                                if (nextWriteDelay < nextCpuDelay) {
2278                                    nextCpuDelay = nextWriteDelay;
2279                                }
2280                                if (nextCpuDelay > 0) {
2281                                    mProcessCpuMutexFree.set(true);
2282                                    this.wait(nextCpuDelay);
2283                                }
2284                            }
2285                        } catch (InterruptedException e) {
2286                        }
2287                        updateCpuStatsNow();
2288                    } catch (Exception e) {
2289                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2290                    }
2291                }
2292            }
2293        };
2294
2295        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2296
2297        Watchdog.getInstance().addMonitor(this);
2298        Watchdog.getInstance().addThread(mHandler);
2299    }
2300
2301    public void setSystemServiceManager(SystemServiceManager mgr) {
2302        mSystemServiceManager = mgr;
2303    }
2304
2305    private void start() {
2306        Process.removeAllProcessGroups();
2307        mProcessCpuThread.start();
2308
2309        mBatteryStatsService.publish(mContext);
2310        mAppOpsService.publish(mContext);
2311        Slog.d("AppOps", "AppOpsService published");
2312        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2313    }
2314
2315    public void initPowerManagement() {
2316        mStackSupervisor.initPowerManagement();
2317        mBatteryStatsService.initPowerManagement();
2318    }
2319
2320    @Override
2321    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2322            throws RemoteException {
2323        if (code == SYSPROPS_TRANSACTION) {
2324            // We need to tell all apps about the system property change.
2325            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2326            synchronized(this) {
2327                final int NP = mProcessNames.getMap().size();
2328                for (int ip=0; ip<NP; ip++) {
2329                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2330                    final int NA = apps.size();
2331                    for (int ia=0; ia<NA; ia++) {
2332                        ProcessRecord app = apps.valueAt(ia);
2333                        if (app.thread != null) {
2334                            procs.add(app.thread.asBinder());
2335                        }
2336                    }
2337                }
2338            }
2339
2340            int N = procs.size();
2341            for (int i=0; i<N; i++) {
2342                Parcel data2 = Parcel.obtain();
2343                try {
2344                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2345                } catch (RemoteException e) {
2346                }
2347                data2.recycle();
2348            }
2349        }
2350        try {
2351            return super.onTransact(code, data, reply, flags);
2352        } catch (RuntimeException e) {
2353            // The activity manager only throws security exceptions, so let's
2354            // log all others.
2355            if (!(e instanceof SecurityException)) {
2356                Slog.wtf(TAG, "Activity Manager Crash", e);
2357            }
2358            throw e;
2359        }
2360    }
2361
2362    void updateCpuStats() {
2363        final long now = SystemClock.uptimeMillis();
2364        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2365            return;
2366        }
2367        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2368            synchronized (mProcessCpuThread) {
2369                mProcessCpuThread.notify();
2370            }
2371        }
2372    }
2373
2374    void updateCpuStatsNow() {
2375        synchronized (mProcessCpuThread) {
2376            mProcessCpuMutexFree.set(false);
2377            final long now = SystemClock.uptimeMillis();
2378            boolean haveNewCpuStats = false;
2379
2380            if (MONITOR_CPU_USAGE &&
2381                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2382                mLastCpuTime.set(now);
2383                haveNewCpuStats = true;
2384                mProcessCpuTracker.update();
2385                //Slog.i(TAG, mProcessCpu.printCurrentState());
2386                //Slog.i(TAG, "Total CPU usage: "
2387                //        + mProcessCpu.getTotalCpuPercent() + "%");
2388
2389                // Slog the cpu usage if the property is set.
2390                if ("true".equals(SystemProperties.get("events.cpu"))) {
2391                    int user = mProcessCpuTracker.getLastUserTime();
2392                    int system = mProcessCpuTracker.getLastSystemTime();
2393                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2394                    int irq = mProcessCpuTracker.getLastIrqTime();
2395                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2396                    int idle = mProcessCpuTracker.getLastIdleTime();
2397
2398                    int total = user + system + iowait + irq + softIrq + idle;
2399                    if (total == 0) total = 1;
2400
2401                    EventLog.writeEvent(EventLogTags.CPU,
2402                            ((user+system+iowait+irq+softIrq) * 100) / total,
2403                            (user * 100) / total,
2404                            (system * 100) / total,
2405                            (iowait * 100) / total,
2406                            (irq * 100) / total,
2407                            (softIrq * 100) / total);
2408                }
2409            }
2410
2411            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2412            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2413            synchronized(bstats) {
2414                synchronized(mPidsSelfLocked) {
2415                    if (haveNewCpuStats) {
2416                        if (mOnBattery) {
2417                            int perc = bstats.startAddingCpuLocked();
2418                            int totalUTime = 0;
2419                            int totalSTime = 0;
2420                            final int N = mProcessCpuTracker.countStats();
2421                            for (int i=0; i<N; i++) {
2422                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2423                                if (!st.working) {
2424                                    continue;
2425                                }
2426                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2427                                int otherUTime = (st.rel_utime*perc)/100;
2428                                int otherSTime = (st.rel_stime*perc)/100;
2429                                totalUTime += otherUTime;
2430                                totalSTime += otherSTime;
2431                                if (pr != null) {
2432                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2433                                    if (ps == null || !ps.isActive()) {
2434                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2435                                                pr.info.uid, pr.processName);
2436                                    }
2437                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2438                                            st.rel_stime-otherSTime);
2439                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2440                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2441                                } else {
2442                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2443                                    if (ps == null || !ps.isActive()) {
2444                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2445                                                bstats.mapUid(st.uid), st.name);
2446                                    }
2447                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2448                                            st.rel_stime-otherSTime);
2449                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2450                                }
2451                            }
2452                            bstats.finishAddingCpuLocked(perc, totalUTime,
2453                                    totalSTime, cpuSpeedTimes);
2454                        }
2455                    }
2456                }
2457
2458                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2459                    mLastWriteTime = now;
2460                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2461                }
2462            }
2463        }
2464    }
2465
2466    @Override
2467    public void batteryNeedsCpuUpdate() {
2468        updateCpuStatsNow();
2469    }
2470
2471    @Override
2472    public void batteryPowerChanged(boolean onBattery) {
2473        // When plugging in, update the CPU stats first before changing
2474        // the plug state.
2475        updateCpuStatsNow();
2476        synchronized (this) {
2477            synchronized(mPidsSelfLocked) {
2478                mOnBattery = DEBUG_POWER ? true : onBattery;
2479            }
2480        }
2481    }
2482
2483    /**
2484     * Initialize the application bind args. These are passed to each
2485     * process when the bindApplication() IPC is sent to the process. They're
2486     * lazily setup to make sure the services are running when they're asked for.
2487     */
2488    private HashMap<String, IBinder> getCommonServicesLocked() {
2489        if (mAppBindArgs == null) {
2490            mAppBindArgs = new HashMap<String, IBinder>();
2491
2492            // Setup the application init args
2493            mAppBindArgs.put("package", ServiceManager.getService("package"));
2494            mAppBindArgs.put("window", ServiceManager.getService("window"));
2495            mAppBindArgs.put(Context.ALARM_SERVICE,
2496                    ServiceManager.getService(Context.ALARM_SERVICE));
2497        }
2498        return mAppBindArgs;
2499    }
2500
2501    final void setFocusedActivityLocked(ActivityRecord r) {
2502        if (mFocusedActivity != r) {
2503            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2504            mFocusedActivity = r;
2505            if (r.task != null && r.task.voiceInteractor != null) {
2506                startRunningVoiceLocked();
2507            } else {
2508                finishRunningVoiceLocked();
2509            }
2510            mStackSupervisor.setFocusedStack(r);
2511            if (r != null) {
2512                mWindowManager.setFocusedApp(r.appToken, true);
2513            }
2514            applyUpdateLockStateLocked(r);
2515        }
2516    }
2517
2518    final void clearFocusedActivity(ActivityRecord r) {
2519        if (mFocusedActivity == r) {
2520            mFocusedActivity = null;
2521        }
2522    }
2523
2524    @Override
2525    public void setFocusedStack(int stackId) {
2526        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2527        synchronized (ActivityManagerService.this) {
2528            ActivityStack stack = mStackSupervisor.getStack(stackId);
2529            if (stack != null) {
2530                ActivityRecord r = stack.topRunningActivityLocked(null);
2531                if (r != null) {
2532                    setFocusedActivityLocked(r);
2533                }
2534            }
2535        }
2536    }
2537
2538    @Override
2539    public void notifyActivityDrawn(IBinder token) {
2540        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2541        synchronized (this) {
2542            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2543            if (r != null) {
2544                r.task.stack.notifyActivityDrawnLocked(r);
2545            }
2546        }
2547    }
2548
2549    final void applyUpdateLockStateLocked(ActivityRecord r) {
2550        // Modifications to the UpdateLock state are done on our handler, outside
2551        // the activity manager's locks.  The new state is determined based on the
2552        // state *now* of the relevant activity record.  The object is passed to
2553        // the handler solely for logging detail, not to be consulted/modified.
2554        final boolean nextState = r != null && r.immersive;
2555        mHandler.sendMessage(
2556                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2557    }
2558
2559    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2560        Message msg = Message.obtain();
2561        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2562        msg.obj = r.task.askedCompatMode ? null : r;
2563        mHandler.sendMessage(msg);
2564    }
2565
2566    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2567            String what, Object obj, ProcessRecord srcApp) {
2568        app.lastActivityTime = now;
2569
2570        if (app.activities.size() > 0) {
2571            // Don't want to touch dependent processes that are hosting activities.
2572            return index;
2573        }
2574
2575        int lrui = mLruProcesses.lastIndexOf(app);
2576        if (lrui < 0) {
2577            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2578                    + what + " " + obj + " from " + srcApp);
2579            return index;
2580        }
2581
2582        if (lrui >= index) {
2583            // Don't want to cause this to move dependent processes *back* in the
2584            // list as if they were less frequently used.
2585            return index;
2586        }
2587
2588        if (lrui >= mLruProcessActivityStart) {
2589            // Don't want to touch dependent processes that are hosting activities.
2590            return index;
2591        }
2592
2593        mLruProcesses.remove(lrui);
2594        if (index > 0) {
2595            index--;
2596        }
2597        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2598                + " in LRU list: " + app);
2599        mLruProcesses.add(index, app);
2600        return index;
2601    }
2602
2603    final void removeLruProcessLocked(ProcessRecord app) {
2604        int lrui = mLruProcesses.lastIndexOf(app);
2605        if (lrui >= 0) {
2606            if (lrui <= mLruProcessActivityStart) {
2607                mLruProcessActivityStart--;
2608            }
2609            if (lrui <= mLruProcessServiceStart) {
2610                mLruProcessServiceStart--;
2611            }
2612            mLruProcesses.remove(lrui);
2613        }
2614    }
2615
2616    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2617            ProcessRecord client) {
2618        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2619                || app.treatLikeActivity;
2620        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2621        if (!activityChange && hasActivity) {
2622            // The process has activities, so we are only allowing activity-based adjustments
2623            // to move it.  It should be kept in the front of the list with other
2624            // processes that have activities, and we don't want those to change their
2625            // order except due to activity operations.
2626            return;
2627        }
2628
2629        mLruSeq++;
2630        final long now = SystemClock.uptimeMillis();
2631        app.lastActivityTime = now;
2632
2633        // First a quick reject: if the app is already at the position we will
2634        // put it, then there is nothing to do.
2635        if (hasActivity) {
2636            final int N = mLruProcesses.size();
2637            if (N > 0 && mLruProcesses.get(N-1) == app) {
2638                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2639                return;
2640            }
2641        } else {
2642            if (mLruProcessServiceStart > 0
2643                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2644                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2645                return;
2646            }
2647        }
2648
2649        int lrui = mLruProcesses.lastIndexOf(app);
2650
2651        if (app.persistent && lrui >= 0) {
2652            // We don't care about the position of persistent processes, as long as
2653            // they are in the list.
2654            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2655            return;
2656        }
2657
2658        /* In progress: compute new position first, so we can avoid doing work
2659           if the process is not actually going to move.  Not yet working.
2660        int addIndex;
2661        int nextIndex;
2662        boolean inActivity = false, inService = false;
2663        if (hasActivity) {
2664            // Process has activities, put it at the very tipsy-top.
2665            addIndex = mLruProcesses.size();
2666            nextIndex = mLruProcessServiceStart;
2667            inActivity = true;
2668        } else if (hasService) {
2669            // Process has services, put it at the top of the service list.
2670            addIndex = mLruProcessActivityStart;
2671            nextIndex = mLruProcessServiceStart;
2672            inActivity = true;
2673            inService = true;
2674        } else  {
2675            // Process not otherwise of interest, it goes to the top of the non-service area.
2676            addIndex = mLruProcessServiceStart;
2677            if (client != null) {
2678                int clientIndex = mLruProcesses.lastIndexOf(client);
2679                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2680                        + app);
2681                if (clientIndex >= 0 && addIndex > clientIndex) {
2682                    addIndex = clientIndex;
2683                }
2684            }
2685            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2686        }
2687
2688        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2689                + mLruProcessActivityStart + "): " + app);
2690        */
2691
2692        if (lrui >= 0) {
2693            if (lrui < mLruProcessActivityStart) {
2694                mLruProcessActivityStart--;
2695            }
2696            if (lrui < mLruProcessServiceStart) {
2697                mLruProcessServiceStart--;
2698            }
2699            /*
2700            if (addIndex > lrui) {
2701                addIndex--;
2702            }
2703            if (nextIndex > lrui) {
2704                nextIndex--;
2705            }
2706            */
2707            mLruProcesses.remove(lrui);
2708        }
2709
2710        /*
2711        mLruProcesses.add(addIndex, app);
2712        if (inActivity) {
2713            mLruProcessActivityStart++;
2714        }
2715        if (inService) {
2716            mLruProcessActivityStart++;
2717        }
2718        */
2719
2720        int nextIndex;
2721        if (hasActivity) {
2722            final int N = mLruProcesses.size();
2723            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2724                // Process doesn't have activities, but has clients with
2725                // activities...  move it up, but one below the top (the top
2726                // should always have a real activity).
2727                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2728                mLruProcesses.add(N-1, app);
2729                // To keep it from spamming the LRU list (by making a bunch of clients),
2730                // we will push down any other entries owned by the app.
2731                final int uid = app.info.uid;
2732                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2733                    ProcessRecord subProc = mLruProcesses.get(i);
2734                    if (subProc.info.uid == uid) {
2735                        // We want to push this one down the list.  If the process after
2736                        // it is for the same uid, however, don't do so, because we don't
2737                        // want them internally to be re-ordered.
2738                        if (mLruProcesses.get(i-1).info.uid != uid) {
2739                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2740                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2741                            ProcessRecord tmp = mLruProcesses.get(i);
2742                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2743                            mLruProcesses.set(i-1, tmp);
2744                            i--;
2745                        }
2746                    } else {
2747                        // A gap, we can stop here.
2748                        break;
2749                    }
2750                }
2751            } else {
2752                // Process has activities, put it at the very tipsy-top.
2753                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2754                mLruProcesses.add(app);
2755            }
2756            nextIndex = mLruProcessServiceStart;
2757        } else if (hasService) {
2758            // Process has services, put it at the top of the service list.
2759            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2760            mLruProcesses.add(mLruProcessActivityStart, app);
2761            nextIndex = mLruProcessServiceStart;
2762            mLruProcessActivityStart++;
2763        } else  {
2764            // Process not otherwise of interest, it goes to the top of the non-service area.
2765            int index = mLruProcessServiceStart;
2766            if (client != null) {
2767                // If there is a client, don't allow the process to be moved up higher
2768                // in the list than that client.
2769                int clientIndex = mLruProcesses.lastIndexOf(client);
2770                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2771                        + " when updating " + app);
2772                if (clientIndex <= lrui) {
2773                    // Don't allow the client index restriction to push it down farther in the
2774                    // list than it already is.
2775                    clientIndex = lrui;
2776                }
2777                if (clientIndex >= 0 && index > clientIndex) {
2778                    index = clientIndex;
2779                }
2780            }
2781            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2782            mLruProcesses.add(index, app);
2783            nextIndex = index-1;
2784            mLruProcessActivityStart++;
2785            mLruProcessServiceStart++;
2786        }
2787
2788        // If the app is currently using a content provider or service,
2789        // bump those processes as well.
2790        for (int j=app.connections.size()-1; j>=0; j--) {
2791            ConnectionRecord cr = app.connections.valueAt(j);
2792            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2793                    && cr.binding.service.app != null
2794                    && cr.binding.service.app.lruSeq != mLruSeq
2795                    && !cr.binding.service.app.persistent) {
2796                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2797                        "service connection", cr, app);
2798            }
2799        }
2800        for (int j=app.conProviders.size()-1; j>=0; j--) {
2801            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2802            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2803                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2804                        "provider reference", cpr, app);
2805            }
2806        }
2807    }
2808
2809    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2810        if (uid == Process.SYSTEM_UID) {
2811            // The system gets to run in any process.  If there are multiple
2812            // processes with the same uid, just pick the first (this
2813            // should never happen).
2814            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2815            if (procs == null) return null;
2816            final int N = procs.size();
2817            for (int i = 0; i < N; i++) {
2818                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2819            }
2820        }
2821        ProcessRecord proc = mProcessNames.get(processName, uid);
2822        if (false && proc != null && !keepIfLarge
2823                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2824                && proc.lastCachedPss >= 4000) {
2825            // Turn this condition on to cause killing to happen regularly, for testing.
2826            if (proc.baseProcessTracker != null) {
2827                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2828            }
2829            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2830                    + "k from cached");
2831        } else if (proc != null && !keepIfLarge
2832                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2833                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2834            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2835            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2836                if (proc.baseProcessTracker != null) {
2837                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2838                }
2839                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2840                        + "k from cached");
2841            }
2842        }
2843        return proc;
2844    }
2845
2846    void ensurePackageDexOpt(String packageName) {
2847        IPackageManager pm = AppGlobals.getPackageManager();
2848        try {
2849            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2850                mDidDexOpt = true;
2851            }
2852        } catch (RemoteException e) {
2853        }
2854    }
2855
2856    boolean isNextTransitionForward() {
2857        int transit = mWindowManager.getPendingAppTransition();
2858        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2859                || transit == AppTransition.TRANSIT_TASK_OPEN
2860                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2861    }
2862
2863    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2864            String processName, String abiOverride, int uid, Runnable crashHandler) {
2865        synchronized(this) {
2866            ApplicationInfo info = new ApplicationInfo();
2867            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2868            // For isolated processes, the former contains the parent's uid and the latter the
2869            // actual uid of the isolated process.
2870            // In the special case introduced by this method (which is, starting an isolated
2871            // process directly from the SystemServer without an actual parent app process) the
2872            // closest thing to a parent's uid is SYSTEM_UID.
2873            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2874            // the |isolated| logic in the ProcessRecord constructor.
2875            info.uid = Process.SYSTEM_UID;
2876            info.processName = processName;
2877            info.className = entryPoint;
2878            info.packageName = "android";
2879            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2880                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2881                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2882                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2883                    crashHandler);
2884            return proc != null ? proc.pid : 0;
2885        }
2886    }
2887
2888    final ProcessRecord startProcessLocked(String processName,
2889            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2890            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2891            boolean isolated, boolean keepIfLarge) {
2892        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2893                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2894                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2895                null /* crashHandler */);
2896    }
2897
2898    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2899            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2900            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2901            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2902        ProcessRecord app;
2903        if (!isolated) {
2904            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2905        } else {
2906            // If this is an isolated process, it can't re-use an existing process.
2907            app = null;
2908        }
2909        // We don't have to do anything more if:
2910        // (1) There is an existing application record; and
2911        // (2) The caller doesn't think it is dead, OR there is no thread
2912        //     object attached to it so we know it couldn't have crashed; and
2913        // (3) There is a pid assigned to it, so it is either starting or
2914        //     already running.
2915        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2916                + " app=" + app + " knownToBeDead=" + knownToBeDead
2917                + " thread=" + (app != null ? app.thread : null)
2918                + " pid=" + (app != null ? app.pid : -1));
2919        if (app != null && app.pid > 0) {
2920            if (!knownToBeDead || app.thread == null) {
2921                // We already have the app running, or are waiting for it to
2922                // come up (we have a pid but not yet its thread), so keep it.
2923                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2924                // If this is a new package in the process, add the package to the list
2925                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2926                return app;
2927            }
2928
2929            // An application record is attached to a previous process,
2930            // clean it up now.
2931            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2932            Process.killProcessGroup(app.info.uid, app.pid);
2933            handleAppDiedLocked(app, true, true);
2934        }
2935
2936        String hostingNameStr = hostingName != null
2937                ? hostingName.flattenToShortString() : null;
2938
2939        if (!isolated) {
2940            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2941                // If we are in the background, then check to see if this process
2942                // is bad.  If so, we will just silently fail.
2943                if (mBadProcesses.get(info.processName, info.uid) != null) {
2944                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2945                            + "/" + info.processName);
2946                    return null;
2947                }
2948            } else {
2949                // When the user is explicitly starting a process, then clear its
2950                // crash count so that we won't make it bad until they see at
2951                // least one crash dialog again, and make the process good again
2952                // if it had been bad.
2953                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2954                        + "/" + info.processName);
2955                mProcessCrashTimes.remove(info.processName, info.uid);
2956                if (mBadProcesses.get(info.processName, info.uid) != null) {
2957                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2958                            UserHandle.getUserId(info.uid), info.uid,
2959                            info.processName);
2960                    mBadProcesses.remove(info.processName, info.uid);
2961                    if (app != null) {
2962                        app.bad = false;
2963                    }
2964                }
2965            }
2966        }
2967
2968        if (app == null) {
2969            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2970            app.crashHandler = crashHandler;
2971            if (app == null) {
2972                Slog.w(TAG, "Failed making new process record for "
2973                        + processName + "/" + info.uid + " isolated=" + isolated);
2974                return null;
2975            }
2976            mProcessNames.put(processName, app.uid, app);
2977            if (isolated) {
2978                mIsolatedProcesses.put(app.uid, app);
2979            }
2980        } else {
2981            // If this is a new package in the process, add the package to the list
2982            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2983        }
2984
2985        // If the system is not ready yet, then hold off on starting this
2986        // process until it is.
2987        if (!mProcessesReady
2988                && !isAllowedWhileBooting(info)
2989                && !allowWhileBooting) {
2990            if (!mProcessesOnHold.contains(app)) {
2991                mProcessesOnHold.add(app);
2992            }
2993            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2994            return app;
2995        }
2996
2997        startProcessLocked(
2998                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2999        return (app.pid != 0) ? app : null;
3000    }
3001
3002    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3003        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3004    }
3005
3006    private final void startProcessLocked(ProcessRecord app,
3007            String hostingType, String hostingNameStr) {
3008        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3009                null /* entryPoint */, null /* entryPointArgs */);
3010    }
3011
3012    private final void startProcessLocked(ProcessRecord app, String hostingType,
3013            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3014        if (app.pid > 0 && app.pid != MY_PID) {
3015            synchronized (mPidsSelfLocked) {
3016                mPidsSelfLocked.remove(app.pid);
3017                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3018            }
3019            app.setPid(0);
3020        }
3021
3022        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3023                "startProcessLocked removing on hold: " + app);
3024        mProcessesOnHold.remove(app);
3025
3026        updateCpuStats();
3027
3028        try {
3029            int uid = app.uid;
3030
3031            int[] gids = null;
3032            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3033            if (!app.isolated) {
3034                int[] permGids = null;
3035                try {
3036                    final PackageManager pm = mContext.getPackageManager();
3037                    permGids = pm.getPackageGids(app.info.packageName);
3038
3039                    if (Environment.isExternalStorageEmulated()) {
3040                        if (pm.checkPermission(
3041                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3042                                app.info.packageName) == PERMISSION_GRANTED) {
3043                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3044                        } else {
3045                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3046                        }
3047                    }
3048                } catch (PackageManager.NameNotFoundException e) {
3049                    Slog.w(TAG, "Unable to retrieve gids", e);
3050                }
3051
3052                /*
3053                 * Add shared application and profile GIDs so applications can share some
3054                 * resources like shared libraries and access user-wide resources
3055                 */
3056                if (permGids == null) {
3057                    gids = new int[2];
3058                } else {
3059                    gids = new int[permGids.length + 2];
3060                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3061                }
3062                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3063                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3064            }
3065            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3066                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3067                        && mTopComponent != null
3068                        && app.processName.equals(mTopComponent.getPackageName())) {
3069                    uid = 0;
3070                }
3071                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3072                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3073                    uid = 0;
3074                }
3075            }
3076            int debugFlags = 0;
3077            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3078                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3079                // Also turn on CheckJNI for debuggable apps. It's quite
3080                // awkward to turn on otherwise.
3081                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3082            }
3083            // Run the app in safe mode if its manifest requests so or the
3084            // system is booted in safe mode.
3085            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3086                mSafeMode == true) {
3087                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3088            }
3089            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3090                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3091            }
3092            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3093                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3094            }
3095            if ("1".equals(SystemProperties.get("debug.assert"))) {
3096                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3097            }
3098
3099            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3100            if (requiredAbi == null) {
3101                requiredAbi = Build.SUPPORTED_ABIS[0];
3102            }
3103
3104            // Start the process.  It will either succeed and return a result containing
3105            // the PID of the new process, or else throw a RuntimeException.
3106            boolean isActivityProcess = (entryPoint == null);
3107            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3108            Process.ProcessStartResult startResult = Process.start(entryPoint,
3109                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3110                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3111
3112            if (app.isolated) {
3113                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3114            }
3115            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3116
3117            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3118                    UserHandle.getUserId(uid), startResult.pid, uid,
3119                    app.processName, hostingType,
3120                    hostingNameStr != null ? hostingNameStr : "");
3121
3122            if (app.persistent) {
3123                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3124            }
3125
3126            StringBuilder buf = mStringBuilder;
3127            buf.setLength(0);
3128            buf.append("Start proc ");
3129            buf.append(app.processName);
3130            if (!isActivityProcess) {
3131                buf.append(" [");
3132                buf.append(entryPoint);
3133                buf.append("]");
3134            }
3135            buf.append(" for ");
3136            buf.append(hostingType);
3137            if (hostingNameStr != null) {
3138                buf.append(" ");
3139                buf.append(hostingNameStr);
3140            }
3141            buf.append(": pid=");
3142            buf.append(startResult.pid);
3143            buf.append(" uid=");
3144            buf.append(uid);
3145            buf.append(" gids={");
3146            if (gids != null) {
3147                for (int gi=0; gi<gids.length; gi++) {
3148                    if (gi != 0) buf.append(", ");
3149                    buf.append(gids[gi]);
3150
3151                }
3152            }
3153            buf.append("}");
3154            if (requiredAbi != null) {
3155                buf.append(" abi=");
3156                buf.append(requiredAbi);
3157            }
3158            Slog.i(TAG, buf.toString());
3159            app.setPid(startResult.pid);
3160            app.usingWrapper = startResult.usingWrapper;
3161            app.removed = false;
3162            app.killedByAm = false;
3163            synchronized (mPidsSelfLocked) {
3164                this.mPidsSelfLocked.put(startResult.pid, app);
3165                if (isActivityProcess) {
3166                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3167                    msg.obj = app;
3168                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3169                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3170                }
3171            }
3172        } catch (RuntimeException e) {
3173            // XXX do better error recovery.
3174            app.setPid(0);
3175            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3176            if (app.isolated) {
3177                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3178            }
3179            Slog.e(TAG, "Failure starting process " + app.processName, e);
3180        }
3181    }
3182
3183    void updateUsageStats(ActivityRecord component, boolean resumed) {
3184        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3185        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3186        if (resumed) {
3187            if (mUsageStatsService != null) {
3188                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3189                        System.currentTimeMillis(),
3190                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3191            }
3192            synchronized (stats) {
3193                stats.noteActivityResumedLocked(component.app.uid);
3194            }
3195        } else {
3196            if (mUsageStatsService != null) {
3197                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3198                        System.currentTimeMillis(),
3199                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3200            }
3201            synchronized (stats) {
3202                stats.noteActivityPausedLocked(component.app.uid);
3203            }
3204        }
3205    }
3206
3207    Intent getHomeIntent() {
3208        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3209        intent.setComponent(mTopComponent);
3210        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3211            intent.addCategory(Intent.CATEGORY_HOME);
3212        }
3213        return intent;
3214    }
3215
3216    boolean startHomeActivityLocked(int userId) {
3217        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3218                && mTopAction == null) {
3219            // We are running in factory test mode, but unable to find
3220            // the factory test app, so just sit around displaying the
3221            // error message and don't try to start anything.
3222            return false;
3223        }
3224        Intent intent = getHomeIntent();
3225        ActivityInfo aInfo =
3226            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3227        if (aInfo != null) {
3228            intent.setComponent(new ComponentName(
3229                    aInfo.applicationInfo.packageName, aInfo.name));
3230            // Don't do this if the home app is currently being
3231            // instrumented.
3232            aInfo = new ActivityInfo(aInfo);
3233            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3234            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3235                    aInfo.applicationInfo.uid, true);
3236            if (app == null || app.instrumentationClass == null) {
3237                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3238                mStackSupervisor.startHomeActivity(intent, aInfo);
3239            }
3240        }
3241
3242        return true;
3243    }
3244
3245    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3246        ActivityInfo ai = null;
3247        ComponentName comp = intent.getComponent();
3248        try {
3249            if (comp != null) {
3250                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3251            } else {
3252                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3253                        intent,
3254                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3255                            flags, userId);
3256
3257                if (info != null) {
3258                    ai = info.activityInfo;
3259                }
3260            }
3261        } catch (RemoteException e) {
3262            // ignore
3263        }
3264
3265        return ai;
3266    }
3267
3268    /**
3269     * Starts the "new version setup screen" if appropriate.
3270     */
3271    void startSetupActivityLocked() {
3272        // Only do this once per boot.
3273        if (mCheckedForSetup) {
3274            return;
3275        }
3276
3277        // We will show this screen if the current one is a different
3278        // version than the last one shown, and we are not running in
3279        // low-level factory test mode.
3280        final ContentResolver resolver = mContext.getContentResolver();
3281        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3282                Settings.Global.getInt(resolver,
3283                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3284            mCheckedForSetup = true;
3285
3286            // See if we should be showing the platform update setup UI.
3287            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3288            List<ResolveInfo> ris = mContext.getPackageManager()
3289                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3290
3291            // We don't allow third party apps to replace this.
3292            ResolveInfo ri = null;
3293            for (int i=0; ris != null && i<ris.size(); i++) {
3294                if ((ris.get(i).activityInfo.applicationInfo.flags
3295                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3296                    ri = ris.get(i);
3297                    break;
3298                }
3299            }
3300
3301            if (ri != null) {
3302                String vers = ri.activityInfo.metaData != null
3303                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3304                        : null;
3305                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3306                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3307                            Intent.METADATA_SETUP_VERSION);
3308                }
3309                String lastVers = Settings.Secure.getString(
3310                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3311                if (vers != null && !vers.equals(lastVers)) {
3312                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3313                    intent.setComponent(new ComponentName(
3314                            ri.activityInfo.packageName, ri.activityInfo.name));
3315                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3316                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3317                }
3318            }
3319        }
3320    }
3321
3322    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3323        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3324    }
3325
3326    void enforceNotIsolatedCaller(String caller) {
3327        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3328            throw new SecurityException("Isolated process not allowed to call " + caller);
3329        }
3330    }
3331
3332    @Override
3333    public int getFrontActivityScreenCompatMode() {
3334        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3335        synchronized (this) {
3336            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3337        }
3338    }
3339
3340    @Override
3341    public void setFrontActivityScreenCompatMode(int mode) {
3342        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3343                "setFrontActivityScreenCompatMode");
3344        synchronized (this) {
3345            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3346        }
3347    }
3348
3349    @Override
3350    public int getPackageScreenCompatMode(String packageName) {
3351        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3352        synchronized (this) {
3353            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3354        }
3355    }
3356
3357    @Override
3358    public void setPackageScreenCompatMode(String packageName, int mode) {
3359        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3360                "setPackageScreenCompatMode");
3361        synchronized (this) {
3362            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3363        }
3364    }
3365
3366    @Override
3367    public boolean getPackageAskScreenCompat(String packageName) {
3368        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3369        synchronized (this) {
3370            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3371        }
3372    }
3373
3374    @Override
3375    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3376        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3377                "setPackageAskScreenCompat");
3378        synchronized (this) {
3379            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3380        }
3381    }
3382
3383    private void dispatchProcessesChanged() {
3384        int N;
3385        synchronized (this) {
3386            N = mPendingProcessChanges.size();
3387            if (mActiveProcessChanges.length < N) {
3388                mActiveProcessChanges = new ProcessChangeItem[N];
3389            }
3390            mPendingProcessChanges.toArray(mActiveProcessChanges);
3391            mAvailProcessChanges.addAll(mPendingProcessChanges);
3392            mPendingProcessChanges.clear();
3393            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3394        }
3395
3396        int i = mProcessObservers.beginBroadcast();
3397        while (i > 0) {
3398            i--;
3399            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3400            if (observer != null) {
3401                try {
3402                    for (int j=0; j<N; j++) {
3403                        ProcessChangeItem item = mActiveProcessChanges[j];
3404                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3405                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3406                                    + item.pid + " uid=" + item.uid + ": "
3407                                    + item.foregroundActivities);
3408                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3409                                    item.foregroundActivities);
3410                        }
3411                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3412                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3413                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3414                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3415                        }
3416                    }
3417                } catch (RemoteException e) {
3418                }
3419            }
3420        }
3421        mProcessObservers.finishBroadcast();
3422    }
3423
3424    private void dispatchProcessDied(int pid, int uid) {
3425        int i = mProcessObservers.beginBroadcast();
3426        while (i > 0) {
3427            i--;
3428            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3429            if (observer != null) {
3430                try {
3431                    observer.onProcessDied(pid, uid);
3432                } catch (RemoteException e) {
3433                }
3434            }
3435        }
3436        mProcessObservers.finishBroadcast();
3437    }
3438
3439    @Override
3440    public final int startActivity(IApplicationThread caller, String callingPackage,
3441            Intent intent, String resolvedType, IBinder resultTo,
3442            String resultWho, int requestCode, int startFlags,
3443            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3444        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3445                resultWho, requestCode,
3446                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3447    }
3448
3449    @Override
3450    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3451            Intent intent, String resolvedType, IBinder resultTo,
3452            String resultWho, int requestCode, int startFlags,
3453            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3454        enforceNotIsolatedCaller("startActivity");
3455        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3456                false, ALLOW_FULL_ONLY, "startActivity", null);
3457        // TODO: Switch to user app stacks here.
3458        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3459                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3460                null, null, options, userId, null);
3461    }
3462
3463    @Override
3464    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3465            Intent intent, String resolvedType, IBinder resultTo,
3466            String resultWho, int requestCode, int startFlags,
3467            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3468
3469        // This is very dangerous -- it allows you to perform a start activity (including
3470        // permission grants) as any app that may launch one of your own activities.  So
3471        // we will only allow this to be done from activities that are part of the core framework,
3472        // and then only when they are running as the system.
3473        final ActivityRecord sourceRecord;
3474        final int targetUid;
3475        final String targetPackage;
3476        synchronized (this) {
3477            if (resultTo == null) {
3478                throw new SecurityException("Must be called from an activity");
3479            }
3480            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3481            if (sourceRecord == null) {
3482                throw new SecurityException("Called with bad activity token: " + resultTo);
3483            }
3484            if (!sourceRecord.info.packageName.equals("android")) {
3485                throw new SecurityException(
3486                        "Must be called from an activity that is declared in the android package");
3487            }
3488            if (sourceRecord.app == null) {
3489                throw new SecurityException("Called without a process attached to activity");
3490            }
3491            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3492                // This is still okay, as long as this activity is running under the
3493                // uid of the original calling activity.
3494                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3495                    throw new SecurityException(
3496                            "Calling activity in uid " + sourceRecord.app.uid
3497                                    + " must be system uid or original calling uid "
3498                                    + sourceRecord.launchedFromUid);
3499                }
3500            }
3501            targetUid = sourceRecord.launchedFromUid;
3502            targetPackage = sourceRecord.launchedFromPackage;
3503        }
3504
3505        // TODO: Switch to user app stacks here.
3506        try {
3507            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3508                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3509                    null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid),
3510                    null);
3511            return ret;
3512        } catch (SecurityException e) {
3513            // XXX need to figure out how to propagate to original app.
3514            // A SecurityException here is generally actually a fault of the original
3515            // calling activity (such as a fairly granting permissions), so propagate it
3516            // back to them.
3517            /*
3518            StringBuilder msg = new StringBuilder();
3519            msg.append("While launching");
3520            msg.append(intent.toString());
3521            msg.append(": ");
3522            msg.append(e.getMessage());
3523            */
3524            throw e;
3525        }
3526    }
3527
3528    @Override
3529    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3530            Intent intent, String resolvedType, IBinder resultTo,
3531            String resultWho, int requestCode, int startFlags, String profileFile,
3532            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3533        enforceNotIsolatedCaller("startActivityAndWait");
3534        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3535                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3536        WaitResult res = new WaitResult();
3537        // TODO: Switch to user app stacks here.
3538        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3539                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3540                res, null, options, userId, null);
3541        return res;
3542    }
3543
3544    @Override
3545    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3546            Intent intent, String resolvedType, IBinder resultTo,
3547            String resultWho, int requestCode, int startFlags, Configuration config,
3548            Bundle options, int userId) {
3549        enforceNotIsolatedCaller("startActivityWithConfig");
3550        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3551                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3552        // TODO: Switch to user app stacks here.
3553        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3554                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3555                null, null, null, config, options, userId, null);
3556        return ret;
3557    }
3558
3559    @Override
3560    public int startActivityIntentSender(IApplicationThread caller,
3561            IntentSender intent, Intent fillInIntent, String resolvedType,
3562            IBinder resultTo, String resultWho, int requestCode,
3563            int flagsMask, int flagsValues, Bundle options) {
3564        enforceNotIsolatedCaller("startActivityIntentSender");
3565        // Refuse possible leaked file descriptors
3566        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3567            throw new IllegalArgumentException("File descriptors passed in Intent");
3568        }
3569
3570        IIntentSender sender = intent.getTarget();
3571        if (!(sender instanceof PendingIntentRecord)) {
3572            throw new IllegalArgumentException("Bad PendingIntent object");
3573        }
3574
3575        PendingIntentRecord pir = (PendingIntentRecord)sender;
3576
3577        synchronized (this) {
3578            // If this is coming from the currently resumed activity, it is
3579            // effectively saying that app switches are allowed at this point.
3580            final ActivityStack stack = getFocusedStack();
3581            if (stack.mResumedActivity != null &&
3582                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3583                mAppSwitchesAllowedTime = 0;
3584            }
3585        }
3586        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3587                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3588        return ret;
3589    }
3590
3591    @Override
3592    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3593            Intent intent, String resolvedType, IVoiceInteractionSession session,
3594            IVoiceInteractor interactor, int startFlags, String profileFile,
3595            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3596        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3597                != PackageManager.PERMISSION_GRANTED) {
3598            String msg = "Permission Denial: startVoiceActivity() from pid="
3599                    + Binder.getCallingPid()
3600                    + ", uid=" + Binder.getCallingUid()
3601                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3602            Slog.w(TAG, msg);
3603            throw new SecurityException(msg);
3604        }
3605        if (session == null || interactor == null) {
3606            throw new NullPointerException("null session or interactor");
3607        }
3608        userId = handleIncomingUser(callingPid, callingUid, userId,
3609                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3610        // TODO: Switch to user app stacks here.
3611        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3612                resolvedType, session, interactor, null, null, 0, startFlags,
3613                profileFile, profileFd, null, null, options, userId, null);
3614    }
3615
3616    @Override
3617    public boolean startNextMatchingActivity(IBinder callingActivity,
3618            Intent intent, Bundle options) {
3619        // Refuse possible leaked file descriptors
3620        if (intent != null && intent.hasFileDescriptors() == true) {
3621            throw new IllegalArgumentException("File descriptors passed in Intent");
3622        }
3623
3624        synchronized (this) {
3625            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3626            if (r == null) {
3627                ActivityOptions.abort(options);
3628                return false;
3629            }
3630            if (r.app == null || r.app.thread == null) {
3631                // The caller is not running...  d'oh!
3632                ActivityOptions.abort(options);
3633                return false;
3634            }
3635            intent = new Intent(intent);
3636            // The caller is not allowed to change the data.
3637            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3638            // And we are resetting to find the next component...
3639            intent.setComponent(null);
3640
3641            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3642
3643            ActivityInfo aInfo = null;
3644            try {
3645                List<ResolveInfo> resolves =
3646                    AppGlobals.getPackageManager().queryIntentActivities(
3647                            intent, r.resolvedType,
3648                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3649                            UserHandle.getCallingUserId());
3650
3651                // Look for the original activity in the list...
3652                final int N = resolves != null ? resolves.size() : 0;
3653                for (int i=0; i<N; i++) {
3654                    ResolveInfo rInfo = resolves.get(i);
3655                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3656                            && rInfo.activityInfo.name.equals(r.info.name)) {
3657                        // We found the current one...  the next matching is
3658                        // after it.
3659                        i++;
3660                        if (i<N) {
3661                            aInfo = resolves.get(i).activityInfo;
3662                        }
3663                        if (debug) {
3664                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3665                                    + "/" + r.info.name);
3666                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3667                                    + "/" + aInfo.name);
3668                        }
3669                        break;
3670                    }
3671                }
3672            } catch (RemoteException e) {
3673            }
3674
3675            if (aInfo == null) {
3676                // Nobody who is next!
3677                ActivityOptions.abort(options);
3678                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3679                return false;
3680            }
3681
3682            intent.setComponent(new ComponentName(
3683                    aInfo.applicationInfo.packageName, aInfo.name));
3684            intent.setFlags(intent.getFlags()&~(
3685                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3686                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3687                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3688                    Intent.FLAG_ACTIVITY_NEW_TASK));
3689
3690            // Okay now we need to start the new activity, replacing the
3691            // currently running activity.  This is a little tricky because
3692            // we want to start the new one as if the current one is finished,
3693            // but not finish the current one first so that there is no flicker.
3694            // And thus...
3695            final boolean wasFinishing = r.finishing;
3696            r.finishing = true;
3697
3698            // Propagate reply information over to the new activity.
3699            final ActivityRecord resultTo = r.resultTo;
3700            final String resultWho = r.resultWho;
3701            final int requestCode = r.requestCode;
3702            r.resultTo = null;
3703            if (resultTo != null) {
3704                resultTo.removeResultsLocked(r, resultWho, requestCode);
3705            }
3706
3707            final long origId = Binder.clearCallingIdentity();
3708            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3709                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3710                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3711                    options, false, null, null);
3712            Binder.restoreCallingIdentity(origId);
3713
3714            r.finishing = wasFinishing;
3715            if (res != ActivityManager.START_SUCCESS) {
3716                return false;
3717            }
3718            return true;
3719        }
3720    }
3721
3722    @Override
3723    public final int startActivityFromRecents(int taskId, Bundle options) {
3724        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3725            String msg = "Permission Denial: startActivityFromRecents called without " +
3726                    START_TASKS_FROM_RECENTS;
3727            Slog.w(TAG, msg);
3728            throw new SecurityException(msg);
3729        }
3730        final int callingUid;
3731        final String callingPackage;
3732        final Intent intent;
3733        final int userId;
3734        synchronized (this) {
3735            final TaskRecord task = recentTaskForIdLocked(taskId);
3736            if (task == null) {
3737                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3738            }
3739            callingUid = task.mCallingUid;
3740            callingPackage = task.mCallingPackage;
3741            intent = task.intent;
3742            userId = task.userId;
3743        }
3744        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3745                options, userId, null);
3746    }
3747
3748    final int startActivityInPackage(int uid, String callingPackage,
3749            Intent intent, String resolvedType, IBinder resultTo,
3750            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3751                    IActivityContainer container) {
3752
3753        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3754                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3755
3756        // TODO: Switch to user app stacks here.
3757        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3758                null, null, resultTo, resultWho, requestCode, startFlags,
3759                null, null, null, null, options, userId, container);
3760        return ret;
3761    }
3762
3763    @Override
3764    public final int startActivities(IApplicationThread caller, String callingPackage,
3765            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3766            int userId) {
3767        enforceNotIsolatedCaller("startActivities");
3768        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3769                false, ALLOW_FULL_ONLY, "startActivity", null);
3770        // TODO: Switch to user app stacks here.
3771        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3772                resolvedTypes, resultTo, options, userId);
3773        return ret;
3774    }
3775
3776    final int startActivitiesInPackage(int uid, String callingPackage,
3777            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3778            Bundle options, int userId) {
3779
3780        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3781                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3782        // TODO: Switch to user app stacks here.
3783        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3784                resultTo, options, userId);
3785        return ret;
3786    }
3787
3788    //explicitly remove thd old information in mRecentTasks when removing existing user.
3789    private void removeRecentTasksForUserLocked(int userId) {
3790        if(userId <= 0) {
3791            Slog.i(TAG, "Can't remove recent task on user " + userId);
3792            return;
3793        }
3794
3795        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3796            TaskRecord tr = mRecentTasks.get(i);
3797            if (tr.userId == userId) {
3798                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3799                        + " when finishing user" + userId);
3800                tr.disposeThumbnail();
3801                mRecentTasks.remove(i);
3802            }
3803        }
3804
3805        // Remove tasks from persistent storage.
3806        mTaskPersister.wakeup(null, true);
3807    }
3808
3809    final void addRecentTaskLocked(TaskRecord task) {
3810        final int N = mRecentTasks.size();
3811        // Quick case: check if the top-most recent task is the same.
3812        if (N > 0 && mRecentTasks.get(0) == task) {
3813            return;
3814        }
3815        // Another quick case: never add voice sessions.
3816        if (task.voiceSession != null) {
3817            return;
3818        }
3819
3820        trimRecentsForTask(task, true);
3821
3822        if (N >= MAX_RECENT_TASKS) {
3823            final TaskRecord tr = mRecentTasks.remove(N - 1);
3824            tr.disposeThumbnail();
3825            tr.closeRecentsChain();
3826        }
3827        mRecentTasks.add(0, task);
3828    }
3829
3830    /**
3831     * If needed, remove oldest existing entries in recents that are for the same kind
3832     * of task as the given one.
3833     */
3834    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
3835        int N = mRecentTasks.size();
3836        final Intent intent = task.intent;
3837        final boolean document = intent != null && intent.isDocument();
3838
3839        int maxRecents = task.maxRecents - 1;
3840        for (int i=0; i<N; i++) {
3841            final TaskRecord tr = mRecentTasks.get(i);
3842            if (task != tr) {
3843                if (task.userId != tr.userId) {
3844                    continue;
3845                }
3846                if (i > MAX_RECENT_BITMAPS) {
3847                    tr.freeLastThumbnail();
3848                }
3849                final Intent trIntent = tr.intent;
3850                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3851                    (intent == null || !intent.filterEquals(trIntent))) {
3852                    continue;
3853                }
3854                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3855                if (document && trIsDocument) {
3856                    // These are the same document activity (not necessarily the same doc).
3857                    if (maxRecents > 0) {
3858                        --maxRecents;
3859                        continue;
3860                    }
3861                    // Hit the maximum number of documents for this task. Fall through
3862                    // and remove this document from recents.
3863                } else if (document || trIsDocument) {
3864                    // Only one of these is a document. Not the droid we're looking for.
3865                    continue;
3866                }
3867            }
3868
3869            if (!doTrim) {
3870                // If the caller is not actually asking for a trim, just tell them we reached
3871                // a point where the trim would happen.
3872                return i;
3873            }
3874
3875            // Either task and tr are the same or, their affinities match or their intents match
3876            // and neither of them is a document, or they are documents using the same activity
3877            // and their maxRecents has been reached.
3878            tr.disposeThumbnail();
3879            mRecentTasks.remove(i);
3880            if (task != tr) {
3881                tr.closeRecentsChain();
3882            }
3883            i--;
3884            N--;
3885            if (task.intent == null) {
3886                // If the new recent task we are adding is not fully
3887                // specified, then replace it with the existing recent task.
3888                task = tr;
3889            }
3890            notifyTaskPersisterLocked(tr, false);
3891        }
3892
3893        return -1;
3894    }
3895
3896    @Override
3897    public void reportActivityFullyDrawn(IBinder token) {
3898        synchronized (this) {
3899            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3900            if (r == null) {
3901                return;
3902            }
3903            r.reportFullyDrawnLocked();
3904        }
3905    }
3906
3907    @Override
3908    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3909        synchronized (this) {
3910            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3911            if (r == null) {
3912                return;
3913            }
3914            final long origId = Binder.clearCallingIdentity();
3915            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3916            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3917                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3918            if (config != null) {
3919                r.frozenBeforeDestroy = true;
3920                if (!updateConfigurationLocked(config, r, false, false)) {
3921                    mStackSupervisor.resumeTopActivitiesLocked();
3922                }
3923            }
3924            Binder.restoreCallingIdentity(origId);
3925        }
3926    }
3927
3928    @Override
3929    public int getRequestedOrientation(IBinder token) {
3930        synchronized (this) {
3931            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3932            if (r == null) {
3933                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3934            }
3935            return mWindowManager.getAppOrientation(r.appToken);
3936        }
3937    }
3938
3939    /**
3940     * This is the internal entry point for handling Activity.finish().
3941     *
3942     * @param token The Binder token referencing the Activity we want to finish.
3943     * @param resultCode Result code, if any, from this Activity.
3944     * @param resultData Result data (Intent), if any, from this Activity.
3945     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3946     *            the root Activity in the task.
3947     *
3948     * @return Returns true if the activity successfully finished, or false if it is still running.
3949     */
3950    @Override
3951    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3952            boolean finishTask) {
3953        // Refuse possible leaked file descriptors
3954        if (resultData != null && resultData.hasFileDescriptors() == true) {
3955            throw new IllegalArgumentException("File descriptors passed in Intent");
3956        }
3957
3958        synchronized(this) {
3959            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3960            if (r == null) {
3961                return true;
3962            }
3963            // Keep track of the root activity of the task before we finish it
3964            TaskRecord tr = r.task;
3965            ActivityRecord rootR = tr.getRootActivity();
3966            // Do not allow task to finish in Lock Task mode.
3967            if (tr == mStackSupervisor.mLockTaskModeTask) {
3968                if (rootR == r) {
3969                    mStackSupervisor.showLockTaskToast();
3970                    return false;
3971                }
3972            }
3973            if (mController != null) {
3974                // Find the first activity that is not finishing.
3975                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3976                if (next != null) {
3977                    // ask watcher if this is allowed
3978                    boolean resumeOK = true;
3979                    try {
3980                        resumeOK = mController.activityResuming(next.packageName);
3981                    } catch (RemoteException e) {
3982                        mController = null;
3983                        Watchdog.getInstance().setActivityController(null);
3984                    }
3985
3986                    if (!resumeOK) {
3987                        return false;
3988                    }
3989                }
3990            }
3991            final long origId = Binder.clearCallingIdentity();
3992            try {
3993                boolean res;
3994                if (finishTask && r == rootR) {
3995                    // If requested, remove the task that is associated to this activity only if it
3996                    // was the root activity in the task.  The result code and data is ignored because
3997                    // we don't support returning them across task boundaries.
3998                    res = removeTaskByIdLocked(tr.taskId, 0);
3999                } else {
4000                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4001                            resultData, "app-request", true);
4002                }
4003                return res;
4004            } finally {
4005                Binder.restoreCallingIdentity(origId);
4006            }
4007        }
4008    }
4009
4010    @Override
4011    public final void finishHeavyWeightApp() {
4012        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4013                != PackageManager.PERMISSION_GRANTED) {
4014            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4015                    + Binder.getCallingPid()
4016                    + ", uid=" + Binder.getCallingUid()
4017                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4018            Slog.w(TAG, msg);
4019            throw new SecurityException(msg);
4020        }
4021
4022        synchronized(this) {
4023            if (mHeavyWeightProcess == null) {
4024                return;
4025            }
4026
4027            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4028                    mHeavyWeightProcess.activities);
4029            for (int i=0; i<activities.size(); i++) {
4030                ActivityRecord r = activities.get(i);
4031                if (!r.finishing) {
4032                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4033                            null, "finish-heavy", true);
4034                }
4035            }
4036
4037            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4038                    mHeavyWeightProcess.userId, 0));
4039            mHeavyWeightProcess = null;
4040        }
4041    }
4042
4043    @Override
4044    public void crashApplication(int uid, int initialPid, String packageName,
4045            String message) {
4046        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4047                != PackageManager.PERMISSION_GRANTED) {
4048            String msg = "Permission Denial: crashApplication() from pid="
4049                    + Binder.getCallingPid()
4050                    + ", uid=" + Binder.getCallingUid()
4051                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4052            Slog.w(TAG, msg);
4053            throw new SecurityException(msg);
4054        }
4055
4056        synchronized(this) {
4057            ProcessRecord proc = null;
4058
4059            // Figure out which process to kill.  We don't trust that initialPid
4060            // still has any relation to current pids, so must scan through the
4061            // list.
4062            synchronized (mPidsSelfLocked) {
4063                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4064                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4065                    if (p.uid != uid) {
4066                        continue;
4067                    }
4068                    if (p.pid == initialPid) {
4069                        proc = p;
4070                        break;
4071                    }
4072                    if (p.pkgList.containsKey(packageName)) {
4073                        proc = p;
4074                    }
4075                }
4076            }
4077
4078            if (proc == null) {
4079                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4080                        + " initialPid=" + initialPid
4081                        + " packageName=" + packageName);
4082                return;
4083            }
4084
4085            if (proc.thread != null) {
4086                if (proc.pid == Process.myPid()) {
4087                    Log.w(TAG, "crashApplication: trying to crash self!");
4088                    return;
4089                }
4090                long ident = Binder.clearCallingIdentity();
4091                try {
4092                    proc.thread.scheduleCrash(message);
4093                } catch (RemoteException e) {
4094                }
4095                Binder.restoreCallingIdentity(ident);
4096            }
4097        }
4098    }
4099
4100    @Override
4101    public final void finishSubActivity(IBinder token, String resultWho,
4102            int requestCode) {
4103        synchronized(this) {
4104            final long origId = Binder.clearCallingIdentity();
4105            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4106            if (r != null) {
4107                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4108            }
4109            Binder.restoreCallingIdentity(origId);
4110        }
4111    }
4112
4113    @Override
4114    public boolean finishActivityAffinity(IBinder token) {
4115        synchronized(this) {
4116            final long origId = Binder.clearCallingIdentity();
4117            try {
4118                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4119
4120                ActivityRecord rootR = r.task.getRootActivity();
4121                // Do not allow task to finish in Lock Task mode.
4122                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4123                    if (rootR == r) {
4124                        mStackSupervisor.showLockTaskToast();
4125                        return false;
4126                    }
4127                }
4128                boolean res = false;
4129                if (r != null) {
4130                    res = r.task.stack.finishActivityAffinityLocked(r);
4131                }
4132                return res;
4133            } finally {
4134                Binder.restoreCallingIdentity(origId);
4135            }
4136        }
4137    }
4138
4139    @Override
4140    public void finishVoiceTask(IVoiceInteractionSession session) {
4141        synchronized(this) {
4142            final long origId = Binder.clearCallingIdentity();
4143            try {
4144                mStackSupervisor.finishVoiceTask(session);
4145            } finally {
4146                Binder.restoreCallingIdentity(origId);
4147            }
4148        }
4149
4150    }
4151
4152    @Override
4153    public boolean willActivityBeVisible(IBinder token) {
4154        synchronized(this) {
4155            ActivityStack stack = ActivityRecord.getStackLocked(token);
4156            if (stack != null) {
4157                return stack.willActivityBeVisibleLocked(token);
4158            }
4159            return false;
4160        }
4161    }
4162
4163    @Override
4164    public void overridePendingTransition(IBinder token, String packageName,
4165            int enterAnim, int exitAnim) {
4166        synchronized(this) {
4167            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4168            if (self == null) {
4169                return;
4170            }
4171
4172            final long origId = Binder.clearCallingIdentity();
4173
4174            if (self.state == ActivityState.RESUMED
4175                    || self.state == ActivityState.PAUSING) {
4176                mWindowManager.overridePendingAppTransition(packageName,
4177                        enterAnim, exitAnim, null);
4178            }
4179
4180            Binder.restoreCallingIdentity(origId);
4181        }
4182    }
4183
4184    /**
4185     * Main function for removing an existing process from the activity manager
4186     * as a result of that process going away.  Clears out all connections
4187     * to the process.
4188     */
4189    private final void handleAppDiedLocked(ProcessRecord app,
4190            boolean restarting, boolean allowRestart) {
4191        int pid = app.pid;
4192        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4193        if (!restarting) {
4194            removeLruProcessLocked(app);
4195            if (pid > 0) {
4196                ProcessList.remove(pid);
4197            }
4198        }
4199
4200        if (mProfileProc == app) {
4201            clearProfilerLocked();
4202        }
4203
4204        // Remove this application's activities from active lists.
4205        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4206
4207        app.activities.clear();
4208
4209        if (app.instrumentationClass != null) {
4210            Slog.w(TAG, "Crash of app " + app.processName
4211                  + " running instrumentation " + app.instrumentationClass);
4212            Bundle info = new Bundle();
4213            info.putString("shortMsg", "Process crashed.");
4214            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4215        }
4216
4217        if (!restarting) {
4218            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4219                // If there was nothing to resume, and we are not already
4220                // restarting this process, but there is a visible activity that
4221                // is hosted by the process...  then make sure all visible
4222                // activities are running, taking care of restarting this
4223                // process.
4224                if (hasVisibleActivities) {
4225                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4226                }
4227            }
4228        }
4229    }
4230
4231    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4232        IBinder threadBinder = thread.asBinder();
4233        // Find the application record.
4234        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4235            ProcessRecord rec = mLruProcesses.get(i);
4236            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4237                return i;
4238            }
4239        }
4240        return -1;
4241    }
4242
4243    final ProcessRecord getRecordForAppLocked(
4244            IApplicationThread thread) {
4245        if (thread == null) {
4246            return null;
4247        }
4248
4249        int appIndex = getLRURecordIndexForAppLocked(thread);
4250        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4251    }
4252
4253    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4254        // If there are no longer any background processes running,
4255        // and the app that died was not running instrumentation,
4256        // then tell everyone we are now low on memory.
4257        boolean haveBg = false;
4258        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4259            ProcessRecord rec = mLruProcesses.get(i);
4260            if (rec.thread != null
4261                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4262                haveBg = true;
4263                break;
4264            }
4265        }
4266
4267        if (!haveBg) {
4268            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4269            if (doReport) {
4270                long now = SystemClock.uptimeMillis();
4271                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4272                    doReport = false;
4273                } else {
4274                    mLastMemUsageReportTime = now;
4275                }
4276            }
4277            final ArrayList<ProcessMemInfo> memInfos
4278                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4279            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4280            long now = SystemClock.uptimeMillis();
4281            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4282                ProcessRecord rec = mLruProcesses.get(i);
4283                if (rec == dyingProc || rec.thread == null) {
4284                    continue;
4285                }
4286                if (doReport) {
4287                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4288                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4289                }
4290                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4291                    // The low memory report is overriding any current
4292                    // state for a GC request.  Make sure to do
4293                    // heavy/important/visible/foreground processes first.
4294                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4295                        rec.lastRequestedGc = 0;
4296                    } else {
4297                        rec.lastRequestedGc = rec.lastLowMemory;
4298                    }
4299                    rec.reportLowMemory = true;
4300                    rec.lastLowMemory = now;
4301                    mProcessesToGc.remove(rec);
4302                    addProcessToGcListLocked(rec);
4303                }
4304            }
4305            if (doReport) {
4306                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4307                mHandler.sendMessage(msg);
4308            }
4309            scheduleAppGcsLocked();
4310        }
4311    }
4312
4313    final void appDiedLocked(ProcessRecord app) {
4314       appDiedLocked(app, app.pid, app.thread);
4315    }
4316
4317    final void appDiedLocked(ProcessRecord app, int pid,
4318            IApplicationThread thread) {
4319
4320        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4321        synchronized (stats) {
4322            stats.noteProcessDiedLocked(app.info.uid, pid);
4323        }
4324
4325        Process.killProcessGroup(app.info.uid, pid);
4326
4327        // Clean up already done if the process has been re-started.
4328        if (app.pid == pid && app.thread != null &&
4329                app.thread.asBinder() == thread.asBinder()) {
4330            boolean doLowMem = app.instrumentationClass == null;
4331            boolean doOomAdj = doLowMem;
4332            if (!app.killedByAm) {
4333                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4334                        + ") has died.");
4335                mAllowLowerMemLevel = true;
4336            } else {
4337                // Note that we always want to do oom adj to update our state with the
4338                // new number of procs.
4339                mAllowLowerMemLevel = false;
4340                doLowMem = false;
4341            }
4342            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4343            if (DEBUG_CLEANUP) Slog.v(
4344                TAG, "Dying app: " + app + ", pid: " + pid
4345                + ", thread: " + thread.asBinder());
4346            handleAppDiedLocked(app, false, true);
4347
4348            if (doOomAdj) {
4349                updateOomAdjLocked();
4350            }
4351            if (doLowMem) {
4352                doLowMemReportIfNeededLocked(app);
4353            }
4354        } else if (app.pid != pid) {
4355            // A new process has already been started.
4356            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4357                    + ") has died and restarted (pid " + app.pid + ").");
4358            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4359        } else if (DEBUG_PROCESSES) {
4360            Slog.d(TAG, "Received spurious death notification for thread "
4361                    + thread.asBinder());
4362        }
4363    }
4364
4365    /**
4366     * If a stack trace dump file is configured, dump process stack traces.
4367     * @param clearTraces causes the dump file to be erased prior to the new
4368     *    traces being written, if true; when false, the new traces will be
4369     *    appended to any existing file content.
4370     * @param firstPids of dalvik VM processes to dump stack traces for first
4371     * @param lastPids of dalvik VM processes to dump stack traces for last
4372     * @param nativeProcs optional list of native process names to dump stack crawls
4373     * @return file containing stack traces, or null if no dump file is configured
4374     */
4375    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4376            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4377        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4378        if (tracesPath == null || tracesPath.length() == 0) {
4379            return null;
4380        }
4381
4382        File tracesFile = new File(tracesPath);
4383        try {
4384            File tracesDir = tracesFile.getParentFile();
4385            if (!tracesDir.exists()) {
4386                tracesFile.mkdirs();
4387                if (!SELinux.restorecon(tracesDir)) {
4388                    return null;
4389                }
4390            }
4391            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4392
4393            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4394            tracesFile.createNewFile();
4395            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4396        } catch (IOException e) {
4397            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4398            return null;
4399        }
4400
4401        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4402        return tracesFile;
4403    }
4404
4405    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4406            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4407        // Use a FileObserver to detect when traces finish writing.
4408        // The order of traces is considered important to maintain for legibility.
4409        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4410            @Override
4411            public synchronized void onEvent(int event, String path) { notify(); }
4412        };
4413
4414        try {
4415            observer.startWatching();
4416
4417            // First collect all of the stacks of the most important pids.
4418            if (firstPids != null) {
4419                try {
4420                    int num = firstPids.size();
4421                    for (int i = 0; i < num; i++) {
4422                        synchronized (observer) {
4423                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4424                            observer.wait(200);  // Wait for write-close, give up after 200msec
4425                        }
4426                    }
4427                } catch (InterruptedException e) {
4428                    Log.wtf(TAG, e);
4429                }
4430            }
4431
4432            // Next collect the stacks of the native pids
4433            if (nativeProcs != null) {
4434                int[] pids = Process.getPidsForCommands(nativeProcs);
4435                if (pids != null) {
4436                    for (int pid : pids) {
4437                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4438                    }
4439                }
4440            }
4441
4442            // Lastly, measure CPU usage.
4443            if (processCpuTracker != null) {
4444                processCpuTracker.init();
4445                System.gc();
4446                processCpuTracker.update();
4447                try {
4448                    synchronized (processCpuTracker) {
4449                        processCpuTracker.wait(500); // measure over 1/2 second.
4450                    }
4451                } catch (InterruptedException e) {
4452                }
4453                processCpuTracker.update();
4454
4455                // We'll take the stack crawls of just the top apps using CPU.
4456                final int N = processCpuTracker.countWorkingStats();
4457                int numProcs = 0;
4458                for (int i=0; i<N && numProcs<5; i++) {
4459                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4460                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4461                        numProcs++;
4462                        try {
4463                            synchronized (observer) {
4464                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4465                                observer.wait(200);  // Wait for write-close, give up after 200msec
4466                            }
4467                        } catch (InterruptedException e) {
4468                            Log.wtf(TAG, e);
4469                        }
4470
4471                    }
4472                }
4473            }
4474        } finally {
4475            observer.stopWatching();
4476        }
4477    }
4478
4479    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4480        if (true || IS_USER_BUILD) {
4481            return;
4482        }
4483        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4484        if (tracesPath == null || tracesPath.length() == 0) {
4485            return;
4486        }
4487
4488        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4489        StrictMode.allowThreadDiskWrites();
4490        try {
4491            final File tracesFile = new File(tracesPath);
4492            final File tracesDir = tracesFile.getParentFile();
4493            final File tracesTmp = new File(tracesDir, "__tmp__");
4494            try {
4495                if (!tracesDir.exists()) {
4496                    tracesFile.mkdirs();
4497                    if (!SELinux.restorecon(tracesDir.getPath())) {
4498                        return;
4499                    }
4500                }
4501                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4502
4503                if (tracesFile.exists()) {
4504                    tracesTmp.delete();
4505                    tracesFile.renameTo(tracesTmp);
4506                }
4507                StringBuilder sb = new StringBuilder();
4508                Time tobj = new Time();
4509                tobj.set(System.currentTimeMillis());
4510                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4511                sb.append(": ");
4512                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4513                sb.append(" since ");
4514                sb.append(msg);
4515                FileOutputStream fos = new FileOutputStream(tracesFile);
4516                fos.write(sb.toString().getBytes());
4517                if (app == null) {
4518                    fos.write("\n*** No application process!".getBytes());
4519                }
4520                fos.close();
4521                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4522            } catch (IOException e) {
4523                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4524                return;
4525            }
4526
4527            if (app != null) {
4528                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4529                firstPids.add(app.pid);
4530                dumpStackTraces(tracesPath, firstPids, null, null, null);
4531            }
4532
4533            File lastTracesFile = null;
4534            File curTracesFile = null;
4535            for (int i=9; i>=0; i--) {
4536                String name = String.format(Locale.US, "slow%02d.txt", i);
4537                curTracesFile = new File(tracesDir, name);
4538                if (curTracesFile.exists()) {
4539                    if (lastTracesFile != null) {
4540                        curTracesFile.renameTo(lastTracesFile);
4541                    } else {
4542                        curTracesFile.delete();
4543                    }
4544                }
4545                lastTracesFile = curTracesFile;
4546            }
4547            tracesFile.renameTo(curTracesFile);
4548            if (tracesTmp.exists()) {
4549                tracesTmp.renameTo(tracesFile);
4550            }
4551        } finally {
4552            StrictMode.setThreadPolicy(oldPolicy);
4553        }
4554    }
4555
4556    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4557            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4558        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4559        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4560
4561        if (mController != null) {
4562            try {
4563                // 0 == continue, -1 = kill process immediately
4564                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4565                if (res < 0 && app.pid != MY_PID) {
4566                    Process.killProcess(app.pid);
4567                    Process.killProcessGroup(app.info.uid, app.pid);
4568                }
4569            } catch (RemoteException e) {
4570                mController = null;
4571                Watchdog.getInstance().setActivityController(null);
4572            }
4573        }
4574
4575        long anrTime = SystemClock.uptimeMillis();
4576        if (MONITOR_CPU_USAGE) {
4577            updateCpuStatsNow();
4578        }
4579
4580        synchronized (this) {
4581            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4582            if (mShuttingDown) {
4583                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4584                return;
4585            } else if (app.notResponding) {
4586                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4587                return;
4588            } else if (app.crashing) {
4589                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4590                return;
4591            }
4592
4593            // In case we come through here for the same app before completing
4594            // this one, mark as anring now so we will bail out.
4595            app.notResponding = true;
4596
4597            // Log the ANR to the event log.
4598            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4599                    app.processName, app.info.flags, annotation);
4600
4601            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4602            firstPids.add(app.pid);
4603
4604            int parentPid = app.pid;
4605            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4606            if (parentPid != app.pid) firstPids.add(parentPid);
4607
4608            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4609
4610            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4611                ProcessRecord r = mLruProcesses.get(i);
4612                if (r != null && r.thread != null) {
4613                    int pid = r.pid;
4614                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4615                        if (r.persistent) {
4616                            firstPids.add(pid);
4617                        } else {
4618                            lastPids.put(pid, Boolean.TRUE);
4619                        }
4620                    }
4621                }
4622            }
4623        }
4624
4625        // Log the ANR to the main log.
4626        StringBuilder info = new StringBuilder();
4627        info.setLength(0);
4628        info.append("ANR in ").append(app.processName);
4629        if (activity != null && activity.shortComponentName != null) {
4630            info.append(" (").append(activity.shortComponentName).append(")");
4631        }
4632        info.append("\n");
4633        info.append("PID: ").append(app.pid).append("\n");
4634        if (annotation != null) {
4635            info.append("Reason: ").append(annotation).append("\n");
4636        }
4637        if (parent != null && parent != activity) {
4638            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4639        }
4640
4641        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4642
4643        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4644                NATIVE_STACKS_OF_INTEREST);
4645
4646        String cpuInfo = null;
4647        if (MONITOR_CPU_USAGE) {
4648            updateCpuStatsNow();
4649            synchronized (mProcessCpuThread) {
4650                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4651            }
4652            info.append(processCpuTracker.printCurrentLoad());
4653            info.append(cpuInfo);
4654        }
4655
4656        info.append(processCpuTracker.printCurrentState(anrTime));
4657
4658        Slog.e(TAG, info.toString());
4659        if (tracesFile == null) {
4660            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4661            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4662        }
4663
4664        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4665                cpuInfo, tracesFile, null);
4666
4667        if (mController != null) {
4668            try {
4669                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4670                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4671                if (res != 0) {
4672                    if (res < 0 && app.pid != MY_PID) {
4673                        Process.killProcess(app.pid);
4674                        Process.killProcessGroup(app.info.uid, app.pid);
4675                    } else {
4676                        synchronized (this) {
4677                            mServices.scheduleServiceTimeoutLocked(app);
4678                        }
4679                    }
4680                    return;
4681                }
4682            } catch (RemoteException e) {
4683                mController = null;
4684                Watchdog.getInstance().setActivityController(null);
4685            }
4686        }
4687
4688        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4689        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4690                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4691
4692        synchronized (this) {
4693            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4694                killUnneededProcessLocked(app, "background ANR");
4695                return;
4696            }
4697
4698            // Set the app's notResponding state, and look up the errorReportReceiver
4699            makeAppNotRespondingLocked(app,
4700                    activity != null ? activity.shortComponentName : null,
4701                    annotation != null ? "ANR " + annotation : "ANR",
4702                    info.toString());
4703
4704            // Bring up the infamous App Not Responding dialog
4705            Message msg = Message.obtain();
4706            HashMap<String, Object> map = new HashMap<String, Object>();
4707            msg.what = SHOW_NOT_RESPONDING_MSG;
4708            msg.obj = map;
4709            msg.arg1 = aboveSystem ? 1 : 0;
4710            map.put("app", app);
4711            if (activity != null) {
4712                map.put("activity", activity);
4713            }
4714
4715            mHandler.sendMessage(msg);
4716        }
4717    }
4718
4719    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4720        if (!mLaunchWarningShown) {
4721            mLaunchWarningShown = true;
4722            mHandler.post(new Runnable() {
4723                @Override
4724                public void run() {
4725                    synchronized (ActivityManagerService.this) {
4726                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4727                        d.show();
4728                        mHandler.postDelayed(new Runnable() {
4729                            @Override
4730                            public void run() {
4731                                synchronized (ActivityManagerService.this) {
4732                                    d.dismiss();
4733                                    mLaunchWarningShown = false;
4734                                }
4735                            }
4736                        }, 4000);
4737                    }
4738                }
4739            });
4740        }
4741    }
4742
4743    @Override
4744    public boolean clearApplicationUserData(final String packageName,
4745            final IPackageDataObserver observer, int userId) {
4746        enforceNotIsolatedCaller("clearApplicationUserData");
4747        int uid = Binder.getCallingUid();
4748        int pid = Binder.getCallingPid();
4749        userId = handleIncomingUser(pid, uid,
4750                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4751        long callingId = Binder.clearCallingIdentity();
4752        try {
4753            IPackageManager pm = AppGlobals.getPackageManager();
4754            int pkgUid = -1;
4755            synchronized(this) {
4756                try {
4757                    pkgUid = pm.getPackageUid(packageName, userId);
4758                } catch (RemoteException e) {
4759                }
4760                if (pkgUid == -1) {
4761                    Slog.w(TAG, "Invalid packageName: " + packageName);
4762                    if (observer != null) {
4763                        try {
4764                            observer.onRemoveCompleted(packageName, false);
4765                        } catch (RemoteException e) {
4766                            Slog.i(TAG, "Observer no longer exists.");
4767                        }
4768                    }
4769                    return false;
4770                }
4771                if (uid == pkgUid || checkComponentPermission(
4772                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4773                        pid, uid, -1, true)
4774                        == PackageManager.PERMISSION_GRANTED) {
4775                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4776                } else {
4777                    throw new SecurityException("PID " + pid + " does not have permission "
4778                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4779                                    + " of package " + packageName);
4780                }
4781
4782                // Remove all tasks match the cleared application package and user
4783                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4784                    final TaskRecord tr = mRecentTasks.get(i);
4785                    final String taskPackageName =
4786                            tr.getBaseIntent().getComponent().getPackageName();
4787                    if (tr.userId != userId) continue;
4788                    if (!taskPackageName.equals(packageName)) continue;
4789                    removeTaskByIdLocked(tr.taskId, 0);
4790                }
4791            }
4792
4793            try {
4794                // Clear application user data
4795                pm.clearApplicationUserData(packageName, observer, userId);
4796
4797                synchronized(this) {
4798                    // Remove all permissions granted from/to this package
4799                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4800                }
4801
4802                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4803                        Uri.fromParts("package", packageName, null));
4804                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4805                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4806                        null, null, 0, null, null, null, false, false, userId);
4807            } catch (RemoteException e) {
4808            }
4809        } finally {
4810            Binder.restoreCallingIdentity(callingId);
4811        }
4812        return true;
4813    }
4814
4815    @Override
4816    public void killBackgroundProcesses(final String packageName, int userId) {
4817        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4818                != PackageManager.PERMISSION_GRANTED &&
4819                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4820                        != PackageManager.PERMISSION_GRANTED) {
4821            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4822                    + Binder.getCallingPid()
4823                    + ", uid=" + Binder.getCallingUid()
4824                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4825            Slog.w(TAG, msg);
4826            throw new SecurityException(msg);
4827        }
4828
4829        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4830                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4831        long callingId = Binder.clearCallingIdentity();
4832        try {
4833            IPackageManager pm = AppGlobals.getPackageManager();
4834            synchronized(this) {
4835                int appId = -1;
4836                try {
4837                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4838                } catch (RemoteException e) {
4839                }
4840                if (appId == -1) {
4841                    Slog.w(TAG, "Invalid packageName: " + packageName);
4842                    return;
4843                }
4844                killPackageProcessesLocked(packageName, appId, userId,
4845                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4846            }
4847        } finally {
4848            Binder.restoreCallingIdentity(callingId);
4849        }
4850    }
4851
4852    @Override
4853    public void killAllBackgroundProcesses() {
4854        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4855                != PackageManager.PERMISSION_GRANTED) {
4856            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4857                    + Binder.getCallingPid()
4858                    + ", uid=" + Binder.getCallingUid()
4859                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4860            Slog.w(TAG, msg);
4861            throw new SecurityException(msg);
4862        }
4863
4864        long callingId = Binder.clearCallingIdentity();
4865        try {
4866            synchronized(this) {
4867                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4868                final int NP = mProcessNames.getMap().size();
4869                for (int ip=0; ip<NP; ip++) {
4870                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4871                    final int NA = apps.size();
4872                    for (int ia=0; ia<NA; ia++) {
4873                        ProcessRecord app = apps.valueAt(ia);
4874                        if (app.persistent) {
4875                            // we don't kill persistent processes
4876                            continue;
4877                        }
4878                        if (app.removed) {
4879                            procs.add(app);
4880                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4881                            app.removed = true;
4882                            procs.add(app);
4883                        }
4884                    }
4885                }
4886
4887                int N = procs.size();
4888                for (int i=0; i<N; i++) {
4889                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4890                }
4891                mAllowLowerMemLevel = true;
4892                updateOomAdjLocked();
4893                doLowMemReportIfNeededLocked(null);
4894            }
4895        } finally {
4896            Binder.restoreCallingIdentity(callingId);
4897        }
4898    }
4899
4900    @Override
4901    public void forceStopPackage(final String packageName, int userId) {
4902        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4903                != PackageManager.PERMISSION_GRANTED) {
4904            String msg = "Permission Denial: forceStopPackage() from pid="
4905                    + Binder.getCallingPid()
4906                    + ", uid=" + Binder.getCallingUid()
4907                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4908            Slog.w(TAG, msg);
4909            throw new SecurityException(msg);
4910        }
4911        final int callingPid = Binder.getCallingPid();
4912        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4913                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4914        long callingId = Binder.clearCallingIdentity();
4915        try {
4916            IPackageManager pm = AppGlobals.getPackageManager();
4917            synchronized(this) {
4918                int[] users = userId == UserHandle.USER_ALL
4919                        ? getUsersLocked() : new int[] { userId };
4920                for (int user : users) {
4921                    int pkgUid = -1;
4922                    try {
4923                        pkgUid = pm.getPackageUid(packageName, user);
4924                    } catch (RemoteException e) {
4925                    }
4926                    if (pkgUid == -1) {
4927                        Slog.w(TAG, "Invalid packageName: " + packageName);
4928                        continue;
4929                    }
4930                    try {
4931                        pm.setPackageStoppedState(packageName, true, user);
4932                    } catch (RemoteException e) {
4933                    } catch (IllegalArgumentException e) {
4934                        Slog.w(TAG, "Failed trying to unstop package "
4935                                + packageName + ": " + e);
4936                    }
4937                    if (isUserRunningLocked(user, false)) {
4938                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4939                    }
4940                }
4941            }
4942        } finally {
4943            Binder.restoreCallingIdentity(callingId);
4944        }
4945    }
4946
4947    @Override
4948    public void addPackageDependency(String packageName) {
4949        synchronized (this) {
4950            int callingPid = Binder.getCallingPid();
4951            if (callingPid == Process.myPid()) {
4952                //  Yeah, um, no.
4953                Slog.w(TAG, "Can't addPackageDependency on system process");
4954                return;
4955            }
4956            ProcessRecord proc;
4957            synchronized (mPidsSelfLocked) {
4958                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4959            }
4960            if (proc != null) {
4961                if (proc.pkgDeps == null) {
4962                    proc.pkgDeps = new ArraySet<String>(1);
4963                }
4964                proc.pkgDeps.add(packageName);
4965            }
4966        }
4967    }
4968
4969    /*
4970     * The pkg name and app id have to be specified.
4971     */
4972    @Override
4973    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4974        if (pkg == null) {
4975            return;
4976        }
4977        // Make sure the uid is valid.
4978        if (appid < 0) {
4979            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4980            return;
4981        }
4982        int callerUid = Binder.getCallingUid();
4983        // Only the system server can kill an application
4984        if (callerUid == Process.SYSTEM_UID) {
4985            // Post an aysnc message to kill the application
4986            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4987            msg.arg1 = appid;
4988            msg.arg2 = 0;
4989            Bundle bundle = new Bundle();
4990            bundle.putString("pkg", pkg);
4991            bundle.putString("reason", reason);
4992            msg.obj = bundle;
4993            mHandler.sendMessage(msg);
4994        } else {
4995            throw new SecurityException(callerUid + " cannot kill pkg: " +
4996                    pkg);
4997        }
4998    }
4999
5000    @Override
5001    public void closeSystemDialogs(String reason) {
5002        enforceNotIsolatedCaller("closeSystemDialogs");
5003
5004        final int pid = Binder.getCallingPid();
5005        final int uid = Binder.getCallingUid();
5006        final long origId = Binder.clearCallingIdentity();
5007        try {
5008            synchronized (this) {
5009                // Only allow this from foreground processes, so that background
5010                // applications can't abuse it to prevent system UI from being shown.
5011                if (uid >= Process.FIRST_APPLICATION_UID) {
5012                    ProcessRecord proc;
5013                    synchronized (mPidsSelfLocked) {
5014                        proc = mPidsSelfLocked.get(pid);
5015                    }
5016                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5017                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5018                                + " from background process " + proc);
5019                        return;
5020                    }
5021                }
5022                closeSystemDialogsLocked(reason);
5023            }
5024        } finally {
5025            Binder.restoreCallingIdentity(origId);
5026        }
5027    }
5028
5029    void closeSystemDialogsLocked(String reason) {
5030        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5031        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5032                | Intent.FLAG_RECEIVER_FOREGROUND);
5033        if (reason != null) {
5034            intent.putExtra("reason", reason);
5035        }
5036        mWindowManager.closeSystemDialogs(reason);
5037
5038        mStackSupervisor.closeSystemDialogsLocked();
5039
5040        broadcastIntentLocked(null, null, intent, null,
5041                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5042                Process.SYSTEM_UID, UserHandle.USER_ALL);
5043    }
5044
5045    @Override
5046    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5047        enforceNotIsolatedCaller("getProcessMemoryInfo");
5048        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5049        for (int i=pids.length-1; i>=0; i--) {
5050            ProcessRecord proc;
5051            int oomAdj;
5052            synchronized (this) {
5053                synchronized (mPidsSelfLocked) {
5054                    proc = mPidsSelfLocked.get(pids[i]);
5055                    oomAdj = proc != null ? proc.setAdj : 0;
5056                }
5057            }
5058            infos[i] = new Debug.MemoryInfo();
5059            Debug.getMemoryInfo(pids[i], infos[i]);
5060            if (proc != null) {
5061                synchronized (this) {
5062                    if (proc.thread != null && proc.setAdj == oomAdj) {
5063                        // Record this for posterity if the process has been stable.
5064                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5065                                infos[i].getTotalUss(), false, proc.pkgList);
5066                    }
5067                }
5068            }
5069        }
5070        return infos;
5071    }
5072
5073    @Override
5074    public long[] getProcessPss(int[] pids) {
5075        enforceNotIsolatedCaller("getProcessPss");
5076        long[] pss = new long[pids.length];
5077        for (int i=pids.length-1; i>=0; i--) {
5078            ProcessRecord proc;
5079            int oomAdj;
5080            synchronized (this) {
5081                synchronized (mPidsSelfLocked) {
5082                    proc = mPidsSelfLocked.get(pids[i]);
5083                    oomAdj = proc != null ? proc.setAdj : 0;
5084                }
5085            }
5086            long[] tmpUss = new long[1];
5087            pss[i] = Debug.getPss(pids[i], tmpUss);
5088            if (proc != null) {
5089                synchronized (this) {
5090                    if (proc.thread != null && proc.setAdj == oomAdj) {
5091                        // Record this for posterity if the process has been stable.
5092                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5093                    }
5094                }
5095            }
5096        }
5097        return pss;
5098    }
5099
5100    @Override
5101    public void killApplicationProcess(String processName, int uid) {
5102        if (processName == null) {
5103            return;
5104        }
5105
5106        int callerUid = Binder.getCallingUid();
5107        // Only the system server can kill an application
5108        if (callerUid == Process.SYSTEM_UID) {
5109            synchronized (this) {
5110                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5111                if (app != null && app.thread != null) {
5112                    try {
5113                        app.thread.scheduleSuicide();
5114                    } catch (RemoteException e) {
5115                        // If the other end already died, then our work here is done.
5116                    }
5117                } else {
5118                    Slog.w(TAG, "Process/uid not found attempting kill of "
5119                            + processName + " / " + uid);
5120                }
5121            }
5122        } else {
5123            throw new SecurityException(callerUid + " cannot kill app process: " +
5124                    processName);
5125        }
5126    }
5127
5128    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5129        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5130                false, true, false, false, UserHandle.getUserId(uid), reason);
5131        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5132                Uri.fromParts("package", packageName, null));
5133        if (!mProcessesReady) {
5134            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5135                    | Intent.FLAG_RECEIVER_FOREGROUND);
5136        }
5137        intent.putExtra(Intent.EXTRA_UID, uid);
5138        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5139        broadcastIntentLocked(null, null, intent,
5140                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5141                false, false,
5142                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5143    }
5144
5145    private void forceStopUserLocked(int userId, String reason) {
5146        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5147        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5148        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5149                | Intent.FLAG_RECEIVER_FOREGROUND);
5150        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5151        broadcastIntentLocked(null, null, intent,
5152                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5153                false, false,
5154                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5155    }
5156
5157    private final boolean killPackageProcessesLocked(String packageName, int appId,
5158            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5159            boolean doit, boolean evenPersistent, String reason) {
5160        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5161
5162        // Remove all processes this package may have touched: all with the
5163        // same UID (except for the system or root user), and all whose name
5164        // matches the package name.
5165        final int NP = mProcessNames.getMap().size();
5166        for (int ip=0; ip<NP; ip++) {
5167            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5168            final int NA = apps.size();
5169            for (int ia=0; ia<NA; ia++) {
5170                ProcessRecord app = apps.valueAt(ia);
5171                if (app.persistent && !evenPersistent) {
5172                    // we don't kill persistent processes
5173                    continue;
5174                }
5175                if (app.removed) {
5176                    if (doit) {
5177                        procs.add(app);
5178                    }
5179                    continue;
5180                }
5181
5182                // Skip process if it doesn't meet our oom adj requirement.
5183                if (app.setAdj < minOomAdj) {
5184                    continue;
5185                }
5186
5187                // If no package is specified, we call all processes under the
5188                // give user id.
5189                if (packageName == null) {
5190                    if (app.userId != userId) {
5191                        continue;
5192                    }
5193                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5194                        continue;
5195                    }
5196                // Package has been specified, we want to hit all processes
5197                // that match it.  We need to qualify this by the processes
5198                // that are running under the specified app and user ID.
5199                } else {
5200                    final boolean isDep = app.pkgDeps != null
5201                            && app.pkgDeps.contains(packageName);
5202                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5203                        continue;
5204                    }
5205                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5206                        continue;
5207                    }
5208                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5209                        continue;
5210                    }
5211                }
5212
5213                // Process has passed all conditions, kill it!
5214                if (!doit) {
5215                    return true;
5216                }
5217                app.removed = true;
5218                procs.add(app);
5219            }
5220        }
5221
5222        int N = procs.size();
5223        for (int i=0; i<N; i++) {
5224            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5225        }
5226        updateOomAdjLocked();
5227        return N > 0;
5228    }
5229
5230    private final boolean forceStopPackageLocked(String name, int appId,
5231            boolean callerWillRestart, boolean purgeCache, boolean doit,
5232            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5233        int i;
5234        int N;
5235
5236        if (userId == UserHandle.USER_ALL && name == null) {
5237            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5238        }
5239
5240        if (appId < 0 && name != null) {
5241            try {
5242                appId = UserHandle.getAppId(
5243                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5244            } catch (RemoteException e) {
5245            }
5246        }
5247
5248        if (doit) {
5249            if (name != null) {
5250                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5251                        + " user=" + userId + ": " + reason);
5252            } else {
5253                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5254            }
5255
5256            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5257            for (int ip=pmap.size()-1; ip>=0; ip--) {
5258                SparseArray<Long> ba = pmap.valueAt(ip);
5259                for (i=ba.size()-1; i>=0; i--) {
5260                    boolean remove = false;
5261                    final int entUid = ba.keyAt(i);
5262                    if (name != null) {
5263                        if (userId == UserHandle.USER_ALL) {
5264                            if (UserHandle.getAppId(entUid) == appId) {
5265                                remove = true;
5266                            }
5267                        } else {
5268                            if (entUid == UserHandle.getUid(userId, appId)) {
5269                                remove = true;
5270                            }
5271                        }
5272                    } else if (UserHandle.getUserId(entUid) == userId) {
5273                        remove = true;
5274                    }
5275                    if (remove) {
5276                        ba.removeAt(i);
5277                    }
5278                }
5279                if (ba.size() == 0) {
5280                    pmap.removeAt(ip);
5281                }
5282            }
5283        }
5284
5285        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5286                -100, callerWillRestart, true, doit, evenPersistent,
5287                name == null ? ("stop user " + userId) : ("stop " + name));
5288
5289        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5290            if (!doit) {
5291                return true;
5292            }
5293            didSomething = true;
5294        }
5295
5296        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5297            if (!doit) {
5298                return true;
5299            }
5300            didSomething = true;
5301        }
5302
5303        if (name == null) {
5304            // Remove all sticky broadcasts from this user.
5305            mStickyBroadcasts.remove(userId);
5306        }
5307
5308        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5309        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5310                userId, providers)) {
5311            if (!doit) {
5312                return true;
5313            }
5314            didSomething = true;
5315        }
5316        N = providers.size();
5317        for (i=0; i<N; i++) {
5318            removeDyingProviderLocked(null, providers.get(i), true);
5319        }
5320
5321        // Remove transient permissions granted from/to this package/user
5322        removeUriPermissionsForPackageLocked(name, userId, false);
5323
5324        if (name == null || uninstalling) {
5325            // Remove pending intents.  For now we only do this when force
5326            // stopping users, because we have some problems when doing this
5327            // for packages -- app widgets are not currently cleaned up for
5328            // such packages, so they can be left with bad pending intents.
5329            if (mIntentSenderRecords.size() > 0) {
5330                Iterator<WeakReference<PendingIntentRecord>> it
5331                        = mIntentSenderRecords.values().iterator();
5332                while (it.hasNext()) {
5333                    WeakReference<PendingIntentRecord> wpir = it.next();
5334                    if (wpir == null) {
5335                        it.remove();
5336                        continue;
5337                    }
5338                    PendingIntentRecord pir = wpir.get();
5339                    if (pir == null) {
5340                        it.remove();
5341                        continue;
5342                    }
5343                    if (name == null) {
5344                        // Stopping user, remove all objects for the user.
5345                        if (pir.key.userId != userId) {
5346                            // Not the same user, skip it.
5347                            continue;
5348                        }
5349                    } else {
5350                        if (UserHandle.getAppId(pir.uid) != appId) {
5351                            // Different app id, skip it.
5352                            continue;
5353                        }
5354                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5355                            // Different user, skip it.
5356                            continue;
5357                        }
5358                        if (!pir.key.packageName.equals(name)) {
5359                            // Different package, skip it.
5360                            continue;
5361                        }
5362                    }
5363                    if (!doit) {
5364                        return true;
5365                    }
5366                    didSomething = true;
5367                    it.remove();
5368                    pir.canceled = true;
5369                    if (pir.key.activity != null) {
5370                        pir.key.activity.pendingResults.remove(pir.ref);
5371                    }
5372                }
5373            }
5374        }
5375
5376        if (doit) {
5377            if (purgeCache && name != null) {
5378                AttributeCache ac = AttributeCache.instance();
5379                if (ac != null) {
5380                    ac.removePackage(name);
5381                }
5382            }
5383            if (mBooted) {
5384                mStackSupervisor.resumeTopActivitiesLocked();
5385                mStackSupervisor.scheduleIdleLocked();
5386            }
5387        }
5388
5389        return didSomething;
5390    }
5391
5392    private final boolean removeProcessLocked(ProcessRecord app,
5393            boolean callerWillRestart, boolean allowRestart, String reason) {
5394        final String name = app.processName;
5395        final int uid = app.uid;
5396        if (DEBUG_PROCESSES) Slog.d(
5397            TAG, "Force removing proc " + app.toShortString() + " (" + name
5398            + "/" + uid + ")");
5399
5400        mProcessNames.remove(name, uid);
5401        mIsolatedProcesses.remove(app.uid);
5402        if (mHeavyWeightProcess == app) {
5403            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5404                    mHeavyWeightProcess.userId, 0));
5405            mHeavyWeightProcess = null;
5406        }
5407        boolean needRestart = false;
5408        if (app.pid > 0 && app.pid != MY_PID) {
5409            int pid = app.pid;
5410            synchronized (mPidsSelfLocked) {
5411                mPidsSelfLocked.remove(pid);
5412                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5413            }
5414            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5415            if (app.isolated) {
5416                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5417            }
5418            killUnneededProcessLocked(app, reason);
5419            Process.killProcessGroup(app.info.uid, app.pid);
5420            handleAppDiedLocked(app, true, allowRestart);
5421            removeLruProcessLocked(app);
5422
5423            if (app.persistent && !app.isolated) {
5424                if (!callerWillRestart) {
5425                    addAppLocked(app.info, false, null /* ABI override */);
5426                } else {
5427                    needRestart = true;
5428                }
5429            }
5430        } else {
5431            mRemovedProcesses.add(app);
5432        }
5433
5434        return needRestart;
5435    }
5436
5437    private final void processStartTimedOutLocked(ProcessRecord app) {
5438        final int pid = app.pid;
5439        boolean gone = false;
5440        synchronized (mPidsSelfLocked) {
5441            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5442            if (knownApp != null && knownApp.thread == null) {
5443                mPidsSelfLocked.remove(pid);
5444                gone = true;
5445            }
5446        }
5447
5448        if (gone) {
5449            Slog.w(TAG, "Process " + app + " failed to attach");
5450            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5451                    pid, app.uid, app.processName);
5452            mProcessNames.remove(app.processName, app.uid);
5453            mIsolatedProcesses.remove(app.uid);
5454            if (mHeavyWeightProcess == app) {
5455                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5456                        mHeavyWeightProcess.userId, 0));
5457                mHeavyWeightProcess = null;
5458            }
5459            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5460            if (app.isolated) {
5461                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5462            }
5463            // Take care of any launching providers waiting for this process.
5464            checkAppInLaunchingProvidersLocked(app, true);
5465            // Take care of any services that are waiting for the process.
5466            mServices.processStartTimedOutLocked(app);
5467            killUnneededProcessLocked(app, "start timeout");
5468            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5469                Slog.w(TAG, "Unattached app died before backup, skipping");
5470                try {
5471                    IBackupManager bm = IBackupManager.Stub.asInterface(
5472                            ServiceManager.getService(Context.BACKUP_SERVICE));
5473                    bm.agentDisconnected(app.info.packageName);
5474                } catch (RemoteException e) {
5475                    // Can't happen; the backup manager is local
5476                }
5477            }
5478            if (isPendingBroadcastProcessLocked(pid)) {
5479                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5480                skipPendingBroadcastLocked(pid);
5481            }
5482        } else {
5483            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5484        }
5485    }
5486
5487    private final boolean attachApplicationLocked(IApplicationThread thread,
5488            int pid) {
5489
5490        // Find the application record that is being attached...  either via
5491        // the pid if we are running in multiple processes, or just pull the
5492        // next app record if we are emulating process with anonymous threads.
5493        ProcessRecord app;
5494        if (pid != MY_PID && pid >= 0) {
5495            synchronized (mPidsSelfLocked) {
5496                app = mPidsSelfLocked.get(pid);
5497            }
5498        } else {
5499            app = null;
5500        }
5501
5502        if (app == null) {
5503            Slog.w(TAG, "No pending application record for pid " + pid
5504                    + " (IApplicationThread " + thread + "); dropping process");
5505            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5506            if (pid > 0 && pid != MY_PID) {
5507                Process.killProcessQuiet(pid);
5508                //TODO: Process.killProcessGroup(app.info.uid, pid);
5509            } else {
5510                try {
5511                    thread.scheduleExit();
5512                } catch (Exception e) {
5513                    // Ignore exceptions.
5514                }
5515            }
5516            return false;
5517        }
5518
5519        // If this application record is still attached to a previous
5520        // process, clean it up now.
5521        if (app.thread != null) {
5522            handleAppDiedLocked(app, true, true);
5523        }
5524
5525        // Tell the process all about itself.
5526
5527        if (localLOGV) Slog.v(
5528                TAG, "Binding process pid " + pid + " to record " + app);
5529
5530        final String processName = app.processName;
5531        try {
5532            AppDeathRecipient adr = new AppDeathRecipient(
5533                    app, pid, thread);
5534            thread.asBinder().linkToDeath(adr, 0);
5535            app.deathRecipient = adr;
5536        } catch (RemoteException e) {
5537            app.resetPackageList(mProcessStats);
5538            startProcessLocked(app, "link fail", processName);
5539            return false;
5540        }
5541
5542        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5543
5544        app.makeActive(thread, mProcessStats);
5545        app.curAdj = app.setAdj = -100;
5546        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5547        app.forcingToForeground = null;
5548        updateProcessForegroundLocked(app, false, false);
5549        app.hasShownUi = false;
5550        app.debugging = false;
5551        app.cached = false;
5552
5553        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5554
5555        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5556        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5557
5558        if (!normalMode) {
5559            Slog.i(TAG, "Launching preboot mode app: " + app);
5560        }
5561
5562        if (localLOGV) Slog.v(
5563            TAG, "New app record " + app
5564            + " thread=" + thread.asBinder() + " pid=" + pid);
5565        try {
5566            int testMode = IApplicationThread.DEBUG_OFF;
5567            if (mDebugApp != null && mDebugApp.equals(processName)) {
5568                testMode = mWaitForDebugger
5569                    ? IApplicationThread.DEBUG_WAIT
5570                    : IApplicationThread.DEBUG_ON;
5571                app.debugging = true;
5572                if (mDebugTransient) {
5573                    mDebugApp = mOrigDebugApp;
5574                    mWaitForDebugger = mOrigWaitForDebugger;
5575                }
5576            }
5577            String profileFile = app.instrumentationProfileFile;
5578            ParcelFileDescriptor profileFd = null;
5579            boolean profileAutoStop = false;
5580            if (mProfileApp != null && mProfileApp.equals(processName)) {
5581                mProfileProc = app;
5582                profileFile = mProfileFile;
5583                profileFd = mProfileFd;
5584                profileAutoStop = mAutoStopProfiler;
5585            }
5586            boolean enableOpenGlTrace = false;
5587            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5588                enableOpenGlTrace = true;
5589                mOpenGlTraceApp = null;
5590            }
5591
5592            // If the app is being launched for restore or full backup, set it up specially
5593            boolean isRestrictedBackupMode = false;
5594            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5595                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5596                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5597                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5598            }
5599
5600            ensurePackageDexOpt(app.instrumentationInfo != null
5601                    ? app.instrumentationInfo.packageName
5602                    : app.info.packageName);
5603            if (app.instrumentationClass != null) {
5604                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5605            }
5606            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5607                    + processName + " with config " + mConfiguration);
5608            ApplicationInfo appInfo = app.instrumentationInfo != null
5609                    ? app.instrumentationInfo : app.info;
5610            app.compat = compatibilityInfoForPackageLocked(appInfo);
5611            if (profileFd != null) {
5612                profileFd = profileFd.dup();
5613            }
5614            thread.bindApplication(processName, appInfo, providers,
5615                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5616                    app.instrumentationArguments, app.instrumentationWatcher,
5617                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5618                    isRestrictedBackupMode || !normalMode, app.persistent,
5619                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5620                    mCoreSettingsObserver.getCoreSettingsLocked());
5621            updateLruProcessLocked(app, false, null);
5622            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5623        } catch (Exception e) {
5624            // todo: Yikes!  What should we do?  For now we will try to
5625            // start another process, but that could easily get us in
5626            // an infinite loop of restarting processes...
5627            Slog.w(TAG, "Exception thrown during bind!", e);
5628
5629            app.resetPackageList(mProcessStats);
5630            app.unlinkDeathRecipient();
5631            startProcessLocked(app, "bind fail", processName);
5632            return false;
5633        }
5634
5635        // Remove this record from the list of starting applications.
5636        mPersistentStartingProcesses.remove(app);
5637        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5638                "Attach application locked removing on hold: " + app);
5639        mProcessesOnHold.remove(app);
5640
5641        boolean badApp = false;
5642        boolean didSomething = false;
5643
5644        // See if the top visible activity is waiting to run in this process...
5645        if (normalMode) {
5646            try {
5647                if (mStackSupervisor.attachApplicationLocked(app)) {
5648                    didSomething = true;
5649                }
5650            } catch (Exception e) {
5651                badApp = true;
5652            }
5653        }
5654
5655        // Find any services that should be running in this process...
5656        if (!badApp) {
5657            try {
5658                didSomething |= mServices.attachApplicationLocked(app, processName);
5659            } catch (Exception e) {
5660                badApp = true;
5661            }
5662        }
5663
5664        // Check if a next-broadcast receiver is in this process...
5665        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5666            try {
5667                didSomething |= sendPendingBroadcastsLocked(app);
5668            } catch (Exception e) {
5669                // If the app died trying to launch the receiver we declare it 'bad'
5670                badApp = true;
5671            }
5672        }
5673
5674        // Check whether the next backup agent is in this process...
5675        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5676            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5677            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5678            try {
5679                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5680                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5681                        mBackupTarget.backupMode);
5682            } catch (Exception e) {
5683                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5684                e.printStackTrace();
5685            }
5686        }
5687
5688        if (badApp) {
5689            // todo: Also need to kill application to deal with all
5690            // kinds of exceptions.
5691            handleAppDiedLocked(app, false, true);
5692            return false;
5693        }
5694
5695        if (!didSomething) {
5696            updateOomAdjLocked();
5697        }
5698
5699        return true;
5700    }
5701
5702    @Override
5703    public final void attachApplication(IApplicationThread thread) {
5704        synchronized (this) {
5705            int callingPid = Binder.getCallingPid();
5706            final long origId = Binder.clearCallingIdentity();
5707            attachApplicationLocked(thread, callingPid);
5708            Binder.restoreCallingIdentity(origId);
5709        }
5710    }
5711
5712    @Override
5713    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5714        final long origId = Binder.clearCallingIdentity();
5715        synchronized (this) {
5716            ActivityStack stack = ActivityRecord.getStackLocked(token);
5717            if (stack != null) {
5718                ActivityRecord r =
5719                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5720                if (stopProfiling) {
5721                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5722                        try {
5723                            mProfileFd.close();
5724                        } catch (IOException e) {
5725                        }
5726                        clearProfilerLocked();
5727                    }
5728                }
5729            }
5730        }
5731        Binder.restoreCallingIdentity(origId);
5732    }
5733
5734    void postEnableScreenAfterBootLocked() {
5735        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5736    }
5737
5738    void enableScreenAfterBoot() {
5739        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5740                SystemClock.uptimeMillis());
5741        mWindowManager.enableScreenAfterBoot();
5742
5743        synchronized (this) {
5744            updateEventDispatchingLocked();
5745        }
5746    }
5747
5748    @Override
5749    public void showBootMessage(final CharSequence msg, final boolean always) {
5750        enforceNotIsolatedCaller("showBootMessage");
5751        mWindowManager.showBootMessage(msg, always);
5752    }
5753
5754    @Override
5755    public void keyguardWaitingForActivityDrawn() {
5756        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5757        final long token = Binder.clearCallingIdentity();
5758        try {
5759            synchronized (this) {
5760                if (DEBUG_LOCKSCREEN) logLockScreen("");
5761                mWindowManager.keyguardWaitingForActivityDrawn();
5762            }
5763        } finally {
5764            Binder.restoreCallingIdentity(token);
5765        }
5766    }
5767
5768    final void finishBooting() {
5769        // Register receivers to handle package update events
5770        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5771
5772        // Let system services know.
5773        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5774
5775        synchronized (this) {
5776            // Ensure that any processes we had put on hold are now started
5777            // up.
5778            final int NP = mProcessesOnHold.size();
5779            if (NP > 0) {
5780                ArrayList<ProcessRecord> procs =
5781                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5782                for (int ip=0; ip<NP; ip++) {
5783                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5784                            + procs.get(ip));
5785                    startProcessLocked(procs.get(ip), "on-hold", null);
5786                }
5787            }
5788
5789            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5790                // Start looking for apps that are abusing wake locks.
5791                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5792                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5793                // Tell anyone interested that we are done booting!
5794                SystemProperties.set("sys.boot_completed", "1");
5795                SystemProperties.set("dev.bootcomplete", "1");
5796                for (int i=0; i<mStartedUsers.size(); i++) {
5797                    UserStartedState uss = mStartedUsers.valueAt(i);
5798                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5799                        uss.mState = UserStartedState.STATE_RUNNING;
5800                        final int userId = mStartedUsers.keyAt(i);
5801                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5802                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5803                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5804                        broadcastIntentLocked(null, null, intent, null,
5805                                new IIntentReceiver.Stub() {
5806                                    @Override
5807                                    public void performReceive(Intent intent, int resultCode,
5808                                            String data, Bundle extras, boolean ordered,
5809                                            boolean sticky, int sendingUser) {
5810                                        synchronized (ActivityManagerService.this) {
5811                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5812                                                    true, false);
5813                                        }
5814                                    }
5815                                },
5816                                0, null, null,
5817                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5818                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5819                                userId);
5820                    }
5821                }
5822                scheduleStartProfilesLocked();
5823            }
5824        }
5825    }
5826
5827    final void ensureBootCompleted() {
5828        boolean booting;
5829        boolean enableScreen;
5830        synchronized (this) {
5831            booting = mBooting;
5832            mBooting = false;
5833            enableScreen = !mBooted;
5834            mBooted = true;
5835        }
5836
5837        if (booting) {
5838            finishBooting();
5839        }
5840
5841        if (enableScreen) {
5842            enableScreenAfterBoot();
5843        }
5844    }
5845
5846    @Override
5847    public final void activityResumed(IBinder token) {
5848        final long origId = Binder.clearCallingIdentity();
5849        synchronized(this) {
5850            ActivityStack stack = ActivityRecord.getStackLocked(token);
5851            if (stack != null) {
5852                ActivityRecord.activityResumedLocked(token);
5853            }
5854        }
5855        Binder.restoreCallingIdentity(origId);
5856    }
5857
5858    @Override
5859    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5860        final long origId = Binder.clearCallingIdentity();
5861        synchronized(this) {
5862            ActivityStack stack = ActivityRecord.getStackLocked(token);
5863            if (stack != null) {
5864                stack.activityPausedLocked(token, false, persistentState);
5865            }
5866        }
5867        Binder.restoreCallingIdentity(origId);
5868    }
5869
5870    @Override
5871    public final void activityStopped(IBinder token, Bundle icicle,
5872            PersistableBundle persistentState, CharSequence description) {
5873        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5874
5875        // Refuse possible leaked file descriptors
5876        if (icicle != null && icicle.hasFileDescriptors()) {
5877            throw new IllegalArgumentException("File descriptors passed in Bundle");
5878        }
5879
5880        final long origId = Binder.clearCallingIdentity();
5881
5882        synchronized (this) {
5883            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5884            if (r != null) {
5885                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5886            }
5887        }
5888
5889        trimApplications();
5890
5891        Binder.restoreCallingIdentity(origId);
5892    }
5893
5894    @Override
5895    public final void activityDestroyed(IBinder token) {
5896        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5897        synchronized (this) {
5898            ActivityStack stack = ActivityRecord.getStackLocked(token);
5899            if (stack != null) {
5900                stack.activityDestroyedLocked(token);
5901            }
5902        }
5903    }
5904
5905    @Override
5906    public final void backgroundResourcesReleased(IBinder token) {
5907        final long origId = Binder.clearCallingIdentity();
5908        try {
5909            synchronized (this) {
5910                ActivityStack stack = ActivityRecord.getStackLocked(token);
5911                if (stack != null) {
5912                    stack.backgroundResourcesReleased(token);
5913                }
5914            }
5915        } finally {
5916            Binder.restoreCallingIdentity(origId);
5917        }
5918    }
5919
5920    @Override
5921    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5922        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5923    }
5924
5925    @Override
5926    public final void notifyEnterAnimationComplete(IBinder token) {
5927        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5928    }
5929
5930    @Override
5931    public String getCallingPackage(IBinder token) {
5932        synchronized (this) {
5933            ActivityRecord r = getCallingRecordLocked(token);
5934            return r != null ? r.info.packageName : null;
5935        }
5936    }
5937
5938    @Override
5939    public ComponentName getCallingActivity(IBinder token) {
5940        synchronized (this) {
5941            ActivityRecord r = getCallingRecordLocked(token);
5942            return r != null ? r.intent.getComponent() : null;
5943        }
5944    }
5945
5946    private ActivityRecord getCallingRecordLocked(IBinder token) {
5947        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5948        if (r == null) {
5949            return null;
5950        }
5951        return r.resultTo;
5952    }
5953
5954    @Override
5955    public ComponentName getActivityClassForToken(IBinder token) {
5956        synchronized(this) {
5957            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5958            if (r == null) {
5959                return null;
5960            }
5961            return r.intent.getComponent();
5962        }
5963    }
5964
5965    @Override
5966    public String getPackageForToken(IBinder token) {
5967        synchronized(this) {
5968            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5969            if (r == null) {
5970                return null;
5971            }
5972            return r.packageName;
5973        }
5974    }
5975
5976    @Override
5977    public IIntentSender getIntentSender(int type,
5978            String packageName, IBinder token, String resultWho,
5979            int requestCode, Intent[] intents, String[] resolvedTypes,
5980            int flags, Bundle options, int userId) {
5981        enforceNotIsolatedCaller("getIntentSender");
5982        // Refuse possible leaked file descriptors
5983        if (intents != null) {
5984            if (intents.length < 1) {
5985                throw new IllegalArgumentException("Intents array length must be >= 1");
5986            }
5987            for (int i=0; i<intents.length; i++) {
5988                Intent intent = intents[i];
5989                if (intent != null) {
5990                    if (intent.hasFileDescriptors()) {
5991                        throw new IllegalArgumentException("File descriptors passed in Intent");
5992                    }
5993                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5994                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5995                        throw new IllegalArgumentException(
5996                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5997                    }
5998                    intents[i] = new Intent(intent);
5999                }
6000            }
6001            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6002                throw new IllegalArgumentException(
6003                        "Intent array length does not match resolvedTypes length");
6004            }
6005        }
6006        if (options != null) {
6007            if (options.hasFileDescriptors()) {
6008                throw new IllegalArgumentException("File descriptors passed in options");
6009            }
6010        }
6011
6012        synchronized(this) {
6013            int callingUid = Binder.getCallingUid();
6014            int origUserId = userId;
6015            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6016                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6017                    ALLOW_NON_FULL, "getIntentSender", null);
6018            if (origUserId == UserHandle.USER_CURRENT) {
6019                // We don't want to evaluate this until the pending intent is
6020                // actually executed.  However, we do want to always do the
6021                // security checking for it above.
6022                userId = UserHandle.USER_CURRENT;
6023            }
6024            try {
6025                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6026                    int uid = AppGlobals.getPackageManager()
6027                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6028                    if (!UserHandle.isSameApp(callingUid, uid)) {
6029                        String msg = "Permission Denial: getIntentSender() from pid="
6030                            + Binder.getCallingPid()
6031                            + ", uid=" + Binder.getCallingUid()
6032                            + ", (need uid=" + uid + ")"
6033                            + " is not allowed to send as package " + packageName;
6034                        Slog.w(TAG, msg);
6035                        throw new SecurityException(msg);
6036                    }
6037                }
6038
6039                return getIntentSenderLocked(type, packageName, callingUid, userId,
6040                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6041
6042            } catch (RemoteException e) {
6043                throw new SecurityException(e);
6044            }
6045        }
6046    }
6047
6048    IIntentSender getIntentSenderLocked(int type, String packageName,
6049            int callingUid, int userId, IBinder token, String resultWho,
6050            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6051            Bundle options) {
6052        if (DEBUG_MU)
6053            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6054        ActivityRecord activity = null;
6055        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6056            activity = ActivityRecord.isInStackLocked(token);
6057            if (activity == null) {
6058                return null;
6059            }
6060            if (activity.finishing) {
6061                return null;
6062            }
6063        }
6064
6065        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6066        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6067        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6068        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6069                |PendingIntent.FLAG_UPDATE_CURRENT);
6070
6071        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6072                type, packageName, activity, resultWho,
6073                requestCode, intents, resolvedTypes, flags, options, userId);
6074        WeakReference<PendingIntentRecord> ref;
6075        ref = mIntentSenderRecords.get(key);
6076        PendingIntentRecord rec = ref != null ? ref.get() : null;
6077        if (rec != null) {
6078            if (!cancelCurrent) {
6079                if (updateCurrent) {
6080                    if (rec.key.requestIntent != null) {
6081                        rec.key.requestIntent.replaceExtras(intents != null ?
6082                                intents[intents.length - 1] : null);
6083                    }
6084                    if (intents != null) {
6085                        intents[intents.length-1] = rec.key.requestIntent;
6086                        rec.key.allIntents = intents;
6087                        rec.key.allResolvedTypes = resolvedTypes;
6088                    } else {
6089                        rec.key.allIntents = null;
6090                        rec.key.allResolvedTypes = null;
6091                    }
6092                }
6093                return rec;
6094            }
6095            rec.canceled = true;
6096            mIntentSenderRecords.remove(key);
6097        }
6098        if (noCreate) {
6099            return rec;
6100        }
6101        rec = new PendingIntentRecord(this, key, callingUid);
6102        mIntentSenderRecords.put(key, rec.ref);
6103        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6104            if (activity.pendingResults == null) {
6105                activity.pendingResults
6106                        = new HashSet<WeakReference<PendingIntentRecord>>();
6107            }
6108            activity.pendingResults.add(rec.ref);
6109        }
6110        return rec;
6111    }
6112
6113    @Override
6114    public void cancelIntentSender(IIntentSender sender) {
6115        if (!(sender instanceof PendingIntentRecord)) {
6116            return;
6117        }
6118        synchronized(this) {
6119            PendingIntentRecord rec = (PendingIntentRecord)sender;
6120            try {
6121                int uid = AppGlobals.getPackageManager()
6122                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6123                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6124                    String msg = "Permission Denial: cancelIntentSender() from pid="
6125                        + Binder.getCallingPid()
6126                        + ", uid=" + Binder.getCallingUid()
6127                        + " is not allowed to cancel packges "
6128                        + rec.key.packageName;
6129                    Slog.w(TAG, msg);
6130                    throw new SecurityException(msg);
6131                }
6132            } catch (RemoteException e) {
6133                throw new SecurityException(e);
6134            }
6135            cancelIntentSenderLocked(rec, true);
6136        }
6137    }
6138
6139    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6140        rec.canceled = true;
6141        mIntentSenderRecords.remove(rec.key);
6142        if (cleanActivity && rec.key.activity != null) {
6143            rec.key.activity.pendingResults.remove(rec.ref);
6144        }
6145    }
6146
6147    @Override
6148    public String getPackageForIntentSender(IIntentSender pendingResult) {
6149        if (!(pendingResult instanceof PendingIntentRecord)) {
6150            return null;
6151        }
6152        try {
6153            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6154            return res.key.packageName;
6155        } catch (ClassCastException e) {
6156        }
6157        return null;
6158    }
6159
6160    @Override
6161    public int getUidForIntentSender(IIntentSender sender) {
6162        if (sender instanceof PendingIntentRecord) {
6163            try {
6164                PendingIntentRecord res = (PendingIntentRecord)sender;
6165                return res.uid;
6166            } catch (ClassCastException e) {
6167            }
6168        }
6169        return -1;
6170    }
6171
6172    @Override
6173    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6174        if (!(pendingResult instanceof PendingIntentRecord)) {
6175            return false;
6176        }
6177        try {
6178            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6179            if (res.key.allIntents == null) {
6180                return false;
6181            }
6182            for (int i=0; i<res.key.allIntents.length; i++) {
6183                Intent intent = res.key.allIntents[i];
6184                if (intent.getPackage() != null && intent.getComponent() != null) {
6185                    return false;
6186                }
6187            }
6188            return true;
6189        } catch (ClassCastException e) {
6190        }
6191        return false;
6192    }
6193
6194    @Override
6195    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6196        if (!(pendingResult instanceof PendingIntentRecord)) {
6197            return false;
6198        }
6199        try {
6200            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6201            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6202                return true;
6203            }
6204            return false;
6205        } catch (ClassCastException e) {
6206        }
6207        return false;
6208    }
6209
6210    @Override
6211    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6212        if (!(pendingResult instanceof PendingIntentRecord)) {
6213            return null;
6214        }
6215        try {
6216            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6217            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6218        } catch (ClassCastException e) {
6219        }
6220        return null;
6221    }
6222
6223    @Override
6224    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6225        if (!(pendingResult instanceof PendingIntentRecord)) {
6226            return null;
6227        }
6228        try {
6229            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6230            Intent intent = res.key.requestIntent;
6231            if (intent != null) {
6232                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6233                        || res.lastTagPrefix.equals(prefix))) {
6234                    return res.lastTag;
6235                }
6236                res.lastTagPrefix = prefix;
6237                StringBuilder sb = new StringBuilder(128);
6238                if (prefix != null) {
6239                    sb.append(prefix);
6240                }
6241                if (intent.getAction() != null) {
6242                    sb.append(intent.getAction());
6243                } else if (intent.getComponent() != null) {
6244                    intent.getComponent().appendShortString(sb);
6245                } else {
6246                    sb.append("?");
6247                }
6248                return res.lastTag = sb.toString();
6249            }
6250        } catch (ClassCastException e) {
6251        }
6252        return null;
6253    }
6254
6255    @Override
6256    public void setProcessLimit(int max) {
6257        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6258                "setProcessLimit()");
6259        synchronized (this) {
6260            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6261            mProcessLimitOverride = max;
6262        }
6263        trimApplications();
6264    }
6265
6266    @Override
6267    public int getProcessLimit() {
6268        synchronized (this) {
6269            return mProcessLimitOverride;
6270        }
6271    }
6272
6273    void foregroundTokenDied(ForegroundToken token) {
6274        synchronized (ActivityManagerService.this) {
6275            synchronized (mPidsSelfLocked) {
6276                ForegroundToken cur
6277                    = mForegroundProcesses.get(token.pid);
6278                if (cur != token) {
6279                    return;
6280                }
6281                mForegroundProcesses.remove(token.pid);
6282                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6283                if (pr == null) {
6284                    return;
6285                }
6286                pr.forcingToForeground = null;
6287                updateProcessForegroundLocked(pr, false, false);
6288            }
6289            updateOomAdjLocked();
6290        }
6291    }
6292
6293    @Override
6294    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6295        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6296                "setProcessForeground()");
6297        synchronized(this) {
6298            boolean changed = false;
6299
6300            synchronized (mPidsSelfLocked) {
6301                ProcessRecord pr = mPidsSelfLocked.get(pid);
6302                if (pr == null && isForeground) {
6303                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6304                    return;
6305                }
6306                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6307                if (oldToken != null) {
6308                    oldToken.token.unlinkToDeath(oldToken, 0);
6309                    mForegroundProcesses.remove(pid);
6310                    if (pr != null) {
6311                        pr.forcingToForeground = null;
6312                    }
6313                    changed = true;
6314                }
6315                if (isForeground && token != null) {
6316                    ForegroundToken newToken = new ForegroundToken() {
6317                        @Override
6318                        public void binderDied() {
6319                            foregroundTokenDied(this);
6320                        }
6321                    };
6322                    newToken.pid = pid;
6323                    newToken.token = token;
6324                    try {
6325                        token.linkToDeath(newToken, 0);
6326                        mForegroundProcesses.put(pid, newToken);
6327                        pr.forcingToForeground = token;
6328                        changed = true;
6329                    } catch (RemoteException e) {
6330                        // If the process died while doing this, we will later
6331                        // do the cleanup with the process death link.
6332                    }
6333                }
6334            }
6335
6336            if (changed) {
6337                updateOomAdjLocked();
6338            }
6339        }
6340    }
6341
6342    // =========================================================
6343    // PERMISSIONS
6344    // =========================================================
6345
6346    static class PermissionController extends IPermissionController.Stub {
6347        ActivityManagerService mActivityManagerService;
6348        PermissionController(ActivityManagerService activityManagerService) {
6349            mActivityManagerService = activityManagerService;
6350        }
6351
6352        @Override
6353        public boolean checkPermission(String permission, int pid, int uid) {
6354            return mActivityManagerService.checkPermission(permission, pid,
6355                    uid) == PackageManager.PERMISSION_GRANTED;
6356        }
6357    }
6358
6359    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6360        @Override
6361        public int checkComponentPermission(String permission, int pid, int uid,
6362                int owningUid, boolean exported) {
6363            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6364                    owningUid, exported);
6365        }
6366
6367        @Override
6368        public Object getAMSLock() {
6369            return ActivityManagerService.this;
6370        }
6371    }
6372
6373    /**
6374     * This can be called with or without the global lock held.
6375     */
6376    int checkComponentPermission(String permission, int pid, int uid,
6377            int owningUid, boolean exported) {
6378        // We might be performing an operation on behalf of an indirect binder
6379        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6380        // client identity accordingly before proceeding.
6381        Identity tlsIdentity = sCallerIdentity.get();
6382        if (tlsIdentity != null) {
6383            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6384                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6385            uid = tlsIdentity.uid;
6386            pid = tlsIdentity.pid;
6387        }
6388
6389        if (pid == MY_PID) {
6390            return PackageManager.PERMISSION_GRANTED;
6391        }
6392
6393        return ActivityManager.checkComponentPermission(permission, uid,
6394                owningUid, exported);
6395    }
6396
6397    /**
6398     * As the only public entry point for permissions checking, this method
6399     * can enforce the semantic that requesting a check on a null global
6400     * permission is automatically denied.  (Internally a null permission
6401     * string is used when calling {@link #checkComponentPermission} in cases
6402     * when only uid-based security is needed.)
6403     *
6404     * This can be called with or without the global lock held.
6405     */
6406    @Override
6407    public int checkPermission(String permission, int pid, int uid) {
6408        if (permission == null) {
6409            return PackageManager.PERMISSION_DENIED;
6410        }
6411        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6412    }
6413
6414    /**
6415     * Binder IPC calls go through the public entry point.
6416     * This can be called with or without the global lock held.
6417     */
6418    int checkCallingPermission(String permission) {
6419        return checkPermission(permission,
6420                Binder.getCallingPid(),
6421                UserHandle.getAppId(Binder.getCallingUid()));
6422    }
6423
6424    /**
6425     * This can be called with or without the global lock held.
6426     */
6427    void enforceCallingPermission(String permission, String func) {
6428        if (checkCallingPermission(permission)
6429                == PackageManager.PERMISSION_GRANTED) {
6430            return;
6431        }
6432
6433        String msg = "Permission Denial: " + func + " from pid="
6434                + Binder.getCallingPid()
6435                + ", uid=" + Binder.getCallingUid()
6436                + " requires " + permission;
6437        Slog.w(TAG, msg);
6438        throw new SecurityException(msg);
6439    }
6440
6441    /**
6442     * Determine if UID is holding permissions required to access {@link Uri} in
6443     * the given {@link ProviderInfo}. Final permission checking is always done
6444     * in {@link ContentProvider}.
6445     */
6446    private final boolean checkHoldingPermissionsLocked(
6447            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6448        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6449                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6450        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6451            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6452                    != PERMISSION_GRANTED) {
6453                return false;
6454            }
6455        }
6456        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6457    }
6458
6459    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6460            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6461        if (pi.applicationInfo.uid == uid) {
6462            return true;
6463        } else if (!pi.exported) {
6464            return false;
6465        }
6466
6467        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6468        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6469        try {
6470            // check if target holds top-level <provider> permissions
6471            if (!readMet && pi.readPermission != null && considerUidPermissions
6472                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6473                readMet = true;
6474            }
6475            if (!writeMet && pi.writePermission != null && considerUidPermissions
6476                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6477                writeMet = true;
6478            }
6479
6480            // track if unprotected read/write is allowed; any denied
6481            // <path-permission> below removes this ability
6482            boolean allowDefaultRead = pi.readPermission == null;
6483            boolean allowDefaultWrite = pi.writePermission == null;
6484
6485            // check if target holds any <path-permission> that match uri
6486            final PathPermission[] pps = pi.pathPermissions;
6487            if (pps != null) {
6488                final String path = grantUri.uri.getPath();
6489                int i = pps.length;
6490                while (i > 0 && (!readMet || !writeMet)) {
6491                    i--;
6492                    PathPermission pp = pps[i];
6493                    if (pp.match(path)) {
6494                        if (!readMet) {
6495                            final String pprperm = pp.getReadPermission();
6496                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6497                                    + pprperm + " for " + pp.getPath()
6498                                    + ": match=" + pp.match(path)
6499                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6500                            if (pprperm != null) {
6501                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6502                                        == PERMISSION_GRANTED) {
6503                                    readMet = true;
6504                                } else {
6505                                    allowDefaultRead = false;
6506                                }
6507                            }
6508                        }
6509                        if (!writeMet) {
6510                            final String ppwperm = pp.getWritePermission();
6511                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6512                                    + ppwperm + " for " + pp.getPath()
6513                                    + ": match=" + pp.match(path)
6514                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6515                            if (ppwperm != null) {
6516                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6517                                        == PERMISSION_GRANTED) {
6518                                    writeMet = true;
6519                                } else {
6520                                    allowDefaultWrite = false;
6521                                }
6522                            }
6523                        }
6524                    }
6525                }
6526            }
6527
6528            // grant unprotected <provider> read/write, if not blocked by
6529            // <path-permission> above
6530            if (allowDefaultRead) readMet = true;
6531            if (allowDefaultWrite) writeMet = true;
6532
6533        } catch (RemoteException e) {
6534            return false;
6535        }
6536
6537        return readMet && writeMet;
6538    }
6539
6540    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6541        ProviderInfo pi = null;
6542        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6543        if (cpr != null) {
6544            pi = cpr.info;
6545        } else {
6546            try {
6547                pi = AppGlobals.getPackageManager().resolveContentProvider(
6548                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6549            } catch (RemoteException ex) {
6550            }
6551        }
6552        return pi;
6553    }
6554
6555    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6556        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6557        if (targetUris != null) {
6558            return targetUris.get(grantUri);
6559        }
6560        return null;
6561    }
6562
6563    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6564            String targetPkg, int targetUid, GrantUri grantUri) {
6565        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6566        if (targetUris == null) {
6567            targetUris = Maps.newArrayMap();
6568            mGrantedUriPermissions.put(targetUid, targetUris);
6569        }
6570
6571        UriPermission perm = targetUris.get(grantUri);
6572        if (perm == null) {
6573            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6574            targetUris.put(grantUri, perm);
6575        }
6576
6577        return perm;
6578    }
6579
6580    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6581            final int modeFlags) {
6582        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6583        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6584                : UriPermission.STRENGTH_OWNED;
6585
6586        // Root gets to do everything.
6587        if (uid == 0) {
6588            return true;
6589        }
6590
6591        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6592        if (perms == null) return false;
6593
6594        // First look for exact match
6595        final UriPermission exactPerm = perms.get(grantUri);
6596        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6597            return true;
6598        }
6599
6600        // No exact match, look for prefixes
6601        final int N = perms.size();
6602        for (int i = 0; i < N; i++) {
6603            final UriPermission perm = perms.valueAt(i);
6604            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6605                    && perm.getStrength(modeFlags) >= minStrength) {
6606                return true;
6607            }
6608        }
6609
6610        return false;
6611    }
6612
6613    @Override
6614    public int checkUriPermission(Uri uri, int pid, int uid,
6615            final int modeFlags, int userId) {
6616        enforceNotIsolatedCaller("checkUriPermission");
6617
6618        // Another redirected-binder-call permissions check as in
6619        // {@link checkComponentPermission}.
6620        Identity tlsIdentity = sCallerIdentity.get();
6621        if (tlsIdentity != null) {
6622            uid = tlsIdentity.uid;
6623            pid = tlsIdentity.pid;
6624        }
6625
6626        // Our own process gets to do everything.
6627        if (pid == MY_PID) {
6628            return PackageManager.PERMISSION_GRANTED;
6629        }
6630        synchronized (this) {
6631            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6632                    ? PackageManager.PERMISSION_GRANTED
6633                    : PackageManager.PERMISSION_DENIED;
6634        }
6635    }
6636
6637    /**
6638     * Check if the targetPkg can be granted permission to access uri by
6639     * the callingUid using the given modeFlags.  Throws a security exception
6640     * if callingUid is not allowed to do this.  Returns the uid of the target
6641     * if the URI permission grant should be performed; returns -1 if it is not
6642     * needed (for example targetPkg already has permission to access the URI).
6643     * If you already know the uid of the target, you can supply it in
6644     * lastTargetUid else set that to -1.
6645     */
6646    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6647            final int modeFlags, int lastTargetUid) {
6648        if (!Intent.isAccessUriMode(modeFlags)) {
6649            return -1;
6650        }
6651
6652        if (targetPkg != null) {
6653            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6654                    "Checking grant " + targetPkg + " permission to " + grantUri);
6655        }
6656
6657        final IPackageManager pm = AppGlobals.getPackageManager();
6658
6659        // If this is not a content: uri, we can't do anything with it.
6660        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6661            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6662                    "Can't grant URI permission for non-content URI: " + grantUri);
6663            return -1;
6664        }
6665
6666        final String authority = grantUri.uri.getAuthority();
6667        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6668        if (pi == null) {
6669            Slog.w(TAG, "No content provider found for permission check: " +
6670                    grantUri.uri.toSafeString());
6671            return -1;
6672        }
6673
6674        int targetUid = lastTargetUid;
6675        if (targetUid < 0 && targetPkg != null) {
6676            try {
6677                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6678                if (targetUid < 0) {
6679                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6680                            "Can't grant URI permission no uid for: " + targetPkg);
6681                    return -1;
6682                }
6683            } catch (RemoteException ex) {
6684                return -1;
6685            }
6686        }
6687
6688        if (targetUid >= 0) {
6689            // First...  does the target actually need this permission?
6690            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6691                // No need to grant the target this permission.
6692                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6693                        "Target " + targetPkg + " already has full permission to " + grantUri);
6694                return -1;
6695            }
6696        } else {
6697            // First...  there is no target package, so can anyone access it?
6698            boolean allowed = pi.exported;
6699            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6700                if (pi.readPermission != null) {
6701                    allowed = false;
6702                }
6703            }
6704            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6705                if (pi.writePermission != null) {
6706                    allowed = false;
6707                }
6708            }
6709            if (allowed) {
6710                return -1;
6711            }
6712        }
6713
6714        /* There is a special cross user grant if:
6715         * - The target is on another user.
6716         * - Apps on the current user can access the uri without any uid permissions.
6717         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6718         * grant uri permissions.
6719         */
6720        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6721                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6722                modeFlags, false /*without considering the uid permissions*/);
6723
6724        // Second...  is the provider allowing granting of URI permissions?
6725        if (!specialCrossUserGrant) {
6726            if (!pi.grantUriPermissions) {
6727                throw new SecurityException("Provider " + pi.packageName
6728                        + "/" + pi.name
6729                        + " does not allow granting of Uri permissions (uri "
6730                        + grantUri + ")");
6731            }
6732            if (pi.uriPermissionPatterns != null) {
6733                final int N = pi.uriPermissionPatterns.length;
6734                boolean allowed = false;
6735                for (int i=0; i<N; i++) {
6736                    if (pi.uriPermissionPatterns[i] != null
6737                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6738                        allowed = true;
6739                        break;
6740                    }
6741                }
6742                if (!allowed) {
6743                    throw new SecurityException("Provider " + pi.packageName
6744                            + "/" + pi.name
6745                            + " does not allow granting of permission to path of Uri "
6746                            + grantUri);
6747                }
6748            }
6749        }
6750
6751        // Third...  does the caller itself have permission to access
6752        // this uri?
6753        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6754            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6755                // Require they hold a strong enough Uri permission
6756                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6757                    throw new SecurityException("Uid " + callingUid
6758                            + " does not have permission to uri " + grantUri);
6759                }
6760            }
6761        }
6762        return targetUid;
6763    }
6764
6765    @Override
6766    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6767            final int modeFlags, int userId) {
6768        enforceNotIsolatedCaller("checkGrantUriPermission");
6769        synchronized(this) {
6770            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6771                    new GrantUri(userId, uri, false), modeFlags, -1);
6772        }
6773    }
6774
6775    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6776            final int modeFlags, UriPermissionOwner owner) {
6777        if (!Intent.isAccessUriMode(modeFlags)) {
6778            return;
6779        }
6780
6781        // So here we are: the caller has the assumed permission
6782        // to the uri, and the target doesn't.  Let's now give this to
6783        // the target.
6784
6785        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6786                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6787
6788        final String authority = grantUri.uri.getAuthority();
6789        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6790        if (pi == null) {
6791            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6792            return;
6793        }
6794
6795        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6796            grantUri.prefix = true;
6797        }
6798        final UriPermission perm = findOrCreateUriPermissionLocked(
6799                pi.packageName, targetPkg, targetUid, grantUri);
6800        perm.grantModes(modeFlags, owner);
6801    }
6802
6803    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6804            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6805        if (targetPkg == null) {
6806            throw new NullPointerException("targetPkg");
6807        }
6808        int targetUid;
6809        final IPackageManager pm = AppGlobals.getPackageManager();
6810        try {
6811            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6812        } catch (RemoteException ex) {
6813            return;
6814        }
6815
6816        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6817                targetUid);
6818        if (targetUid < 0) {
6819            return;
6820        }
6821
6822        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6823                owner);
6824    }
6825
6826    static class NeededUriGrants extends ArrayList<GrantUri> {
6827        final String targetPkg;
6828        final int targetUid;
6829        final int flags;
6830
6831        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6832            this.targetPkg = targetPkg;
6833            this.targetUid = targetUid;
6834            this.flags = flags;
6835        }
6836    }
6837
6838    /**
6839     * Like checkGrantUriPermissionLocked, but takes an Intent.
6840     */
6841    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6842            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6843        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6844                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6845                + " clip=" + (intent != null ? intent.getClipData() : null)
6846                + " from " + intent + "; flags=0x"
6847                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6848
6849        if (targetPkg == null) {
6850            throw new NullPointerException("targetPkg");
6851        }
6852
6853        if (intent == null) {
6854            return null;
6855        }
6856        Uri data = intent.getData();
6857        ClipData clip = intent.getClipData();
6858        if (data == null && clip == null) {
6859            return null;
6860        }
6861        // Default userId for uris in the intent (if they don't specify it themselves)
6862        int contentUserHint = intent.getContentUserHint();
6863        if (contentUserHint == UserHandle.USER_CURRENT) {
6864            contentUserHint = UserHandle.getUserId(callingUid);
6865        }
6866        final IPackageManager pm = AppGlobals.getPackageManager();
6867        int targetUid;
6868        if (needed != null) {
6869            targetUid = needed.targetUid;
6870        } else {
6871            try {
6872                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6873            } catch (RemoteException ex) {
6874                return null;
6875            }
6876            if (targetUid < 0) {
6877                if (DEBUG_URI_PERMISSION) {
6878                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6879                            + " on user " + targetUserId);
6880                }
6881                return null;
6882            }
6883        }
6884        if (data != null) {
6885            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6886            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6887                    targetUid);
6888            if (targetUid > 0) {
6889                if (needed == null) {
6890                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6891                }
6892                needed.add(grantUri);
6893            }
6894        }
6895        if (clip != null) {
6896            for (int i=0; i<clip.getItemCount(); i++) {
6897                Uri uri = clip.getItemAt(i).getUri();
6898                if (uri != null) {
6899                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6900                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6901                            targetUid);
6902                    if (targetUid > 0) {
6903                        if (needed == null) {
6904                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6905                        }
6906                        needed.add(grantUri);
6907                    }
6908                } else {
6909                    Intent clipIntent = clip.getItemAt(i).getIntent();
6910                    if (clipIntent != null) {
6911                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6912                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6913                        if (newNeeded != null) {
6914                            needed = newNeeded;
6915                        }
6916                    }
6917                }
6918            }
6919        }
6920
6921        return needed;
6922    }
6923
6924    /**
6925     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6926     */
6927    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6928            UriPermissionOwner owner) {
6929        if (needed != null) {
6930            for (int i=0; i<needed.size(); i++) {
6931                GrantUri grantUri = needed.get(i);
6932                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6933                        grantUri, needed.flags, owner);
6934            }
6935        }
6936    }
6937
6938    void grantUriPermissionFromIntentLocked(int callingUid,
6939            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6940        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6941                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6942        if (needed == null) {
6943            return;
6944        }
6945
6946        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6947    }
6948
6949    @Override
6950    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6951            final int modeFlags, int userId) {
6952        enforceNotIsolatedCaller("grantUriPermission");
6953        GrantUri grantUri = new GrantUri(userId, uri, false);
6954        synchronized(this) {
6955            final ProcessRecord r = getRecordForAppLocked(caller);
6956            if (r == null) {
6957                throw new SecurityException("Unable to find app for caller "
6958                        + caller
6959                        + " when granting permission to uri " + grantUri);
6960            }
6961            if (targetPkg == null) {
6962                throw new IllegalArgumentException("null target");
6963            }
6964            if (grantUri == null) {
6965                throw new IllegalArgumentException("null uri");
6966            }
6967
6968            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6969                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6970                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6971                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6972
6973            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6974                    UserHandle.getUserId(r.uid));
6975        }
6976    }
6977
6978    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6979        if (perm.modeFlags == 0) {
6980            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6981                    perm.targetUid);
6982            if (perms != null) {
6983                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6984                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6985
6986                perms.remove(perm.uri);
6987                if (perms.isEmpty()) {
6988                    mGrantedUriPermissions.remove(perm.targetUid);
6989                }
6990            }
6991        }
6992    }
6993
6994    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6995        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6996
6997        final IPackageManager pm = AppGlobals.getPackageManager();
6998        final String authority = grantUri.uri.getAuthority();
6999        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7000        if (pi == null) {
7001            Slog.w(TAG, "No content provider found for permission revoke: "
7002                    + grantUri.toSafeString());
7003            return;
7004        }
7005
7006        // Does the caller have this permission on the URI?
7007        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7008            // Right now, if you are not the original owner of the permission,
7009            // you are not allowed to revoke it.
7010            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7011                throw new SecurityException("Uid " + callingUid
7012                        + " does not have permission to uri " + grantUri);
7013            //}
7014        }
7015
7016        boolean persistChanged = false;
7017
7018        // Go through all of the permissions and remove any that match.
7019        int N = mGrantedUriPermissions.size();
7020        for (int i = 0; i < N; i++) {
7021            final int targetUid = mGrantedUriPermissions.keyAt(i);
7022            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7023
7024            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7025                final UriPermission perm = it.next();
7026                if (perm.uri.sourceUserId == grantUri.sourceUserId
7027                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7028                    if (DEBUG_URI_PERMISSION)
7029                        Slog.v(TAG,
7030                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7031                    persistChanged |= perm.revokeModes(
7032                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7033                    if (perm.modeFlags == 0) {
7034                        it.remove();
7035                    }
7036                }
7037            }
7038
7039            if (perms.isEmpty()) {
7040                mGrantedUriPermissions.remove(targetUid);
7041                N--;
7042                i--;
7043            }
7044        }
7045
7046        if (persistChanged) {
7047            schedulePersistUriGrants();
7048        }
7049    }
7050
7051    @Override
7052    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7053            int userId) {
7054        enforceNotIsolatedCaller("revokeUriPermission");
7055        synchronized(this) {
7056            final ProcessRecord r = getRecordForAppLocked(caller);
7057            if (r == null) {
7058                throw new SecurityException("Unable to find app for caller "
7059                        + caller
7060                        + " when revoking permission to uri " + uri);
7061            }
7062            if (uri == null) {
7063                Slog.w(TAG, "revokeUriPermission: null uri");
7064                return;
7065            }
7066
7067            if (!Intent.isAccessUriMode(modeFlags)) {
7068                return;
7069            }
7070
7071            final IPackageManager pm = AppGlobals.getPackageManager();
7072            final String authority = uri.getAuthority();
7073            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7074            if (pi == null) {
7075                Slog.w(TAG, "No content provider found for permission revoke: "
7076                        + uri.toSafeString());
7077                return;
7078            }
7079
7080            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7081        }
7082    }
7083
7084    /**
7085     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7086     * given package.
7087     *
7088     * @param packageName Package name to match, or {@code null} to apply to all
7089     *            packages.
7090     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7091     *            to all users.
7092     * @param persistable If persistable grants should be removed.
7093     */
7094    private void removeUriPermissionsForPackageLocked(
7095            String packageName, int userHandle, boolean persistable) {
7096        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7097            throw new IllegalArgumentException("Must narrow by either package or user");
7098        }
7099
7100        boolean persistChanged = false;
7101
7102        int N = mGrantedUriPermissions.size();
7103        for (int i = 0; i < N; i++) {
7104            final int targetUid = mGrantedUriPermissions.keyAt(i);
7105            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7106
7107            // Only inspect grants matching user
7108            if (userHandle == UserHandle.USER_ALL
7109                    || userHandle == UserHandle.getUserId(targetUid)) {
7110                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7111                    final UriPermission perm = it.next();
7112
7113                    // Only inspect grants matching package
7114                    if (packageName == null || perm.sourcePkg.equals(packageName)
7115                            || perm.targetPkg.equals(packageName)) {
7116                        persistChanged |= perm.revokeModes(
7117                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7118
7119                        // Only remove when no modes remain; any persisted grants
7120                        // will keep this alive.
7121                        if (perm.modeFlags == 0) {
7122                            it.remove();
7123                        }
7124                    }
7125                }
7126
7127                if (perms.isEmpty()) {
7128                    mGrantedUriPermissions.remove(targetUid);
7129                    N--;
7130                    i--;
7131                }
7132            }
7133        }
7134
7135        if (persistChanged) {
7136            schedulePersistUriGrants();
7137        }
7138    }
7139
7140    @Override
7141    public IBinder newUriPermissionOwner(String name) {
7142        enforceNotIsolatedCaller("newUriPermissionOwner");
7143        synchronized(this) {
7144            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7145            return owner.getExternalTokenLocked();
7146        }
7147    }
7148
7149    @Override
7150    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7151            final int modeFlags, int sourceUserId, int targetUserId) {
7152        synchronized(this) {
7153            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7154            if (owner == null) {
7155                throw new IllegalArgumentException("Unknown owner: " + token);
7156            }
7157            if (fromUid != Binder.getCallingUid()) {
7158                if (Binder.getCallingUid() != Process.myUid()) {
7159                    // Only system code can grant URI permissions on behalf
7160                    // of other users.
7161                    throw new SecurityException("nice try");
7162                }
7163            }
7164            if (targetPkg == null) {
7165                throw new IllegalArgumentException("null target");
7166            }
7167            if (uri == null) {
7168                throw new IllegalArgumentException("null uri");
7169            }
7170
7171            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7172                    modeFlags, owner, targetUserId);
7173        }
7174    }
7175
7176    @Override
7177    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7178        synchronized(this) {
7179            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7180            if (owner == null) {
7181                throw new IllegalArgumentException("Unknown owner: " + token);
7182            }
7183
7184            if (uri == null) {
7185                owner.removeUriPermissionsLocked(mode);
7186            } else {
7187                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7188            }
7189        }
7190    }
7191
7192    private void schedulePersistUriGrants() {
7193        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7194            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7195                    10 * DateUtils.SECOND_IN_MILLIS);
7196        }
7197    }
7198
7199    private void writeGrantedUriPermissions() {
7200        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7201
7202        // Snapshot permissions so we can persist without lock
7203        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7204        synchronized (this) {
7205            final int size = mGrantedUriPermissions.size();
7206            for (int i = 0; i < size; i++) {
7207                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7208                for (UriPermission perm : perms.values()) {
7209                    if (perm.persistedModeFlags != 0) {
7210                        persist.add(perm.snapshot());
7211                    }
7212                }
7213            }
7214        }
7215
7216        FileOutputStream fos = null;
7217        try {
7218            fos = mGrantFile.startWrite();
7219
7220            XmlSerializer out = new FastXmlSerializer();
7221            out.setOutput(fos, "utf-8");
7222            out.startDocument(null, true);
7223            out.startTag(null, TAG_URI_GRANTS);
7224            for (UriPermission.Snapshot perm : persist) {
7225                out.startTag(null, TAG_URI_GRANT);
7226                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7227                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7228                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7229                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7230                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7231                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7232                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7233                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7234                out.endTag(null, TAG_URI_GRANT);
7235            }
7236            out.endTag(null, TAG_URI_GRANTS);
7237            out.endDocument();
7238
7239            mGrantFile.finishWrite(fos);
7240        } catch (IOException e) {
7241            if (fos != null) {
7242                mGrantFile.failWrite(fos);
7243            }
7244        }
7245    }
7246
7247    private void readGrantedUriPermissionsLocked() {
7248        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7249
7250        final long now = System.currentTimeMillis();
7251
7252        FileInputStream fis = null;
7253        try {
7254            fis = mGrantFile.openRead();
7255            final XmlPullParser in = Xml.newPullParser();
7256            in.setInput(fis, null);
7257
7258            int type;
7259            while ((type = in.next()) != END_DOCUMENT) {
7260                final String tag = in.getName();
7261                if (type == START_TAG) {
7262                    if (TAG_URI_GRANT.equals(tag)) {
7263                        final int sourceUserId;
7264                        final int targetUserId;
7265                        final int userHandle = readIntAttribute(in,
7266                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7267                        if (userHandle != UserHandle.USER_NULL) {
7268                            // For backwards compatibility.
7269                            sourceUserId = userHandle;
7270                            targetUserId = userHandle;
7271                        } else {
7272                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7273                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7274                        }
7275                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7276                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7277                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7278                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7279                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7280                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7281
7282                        // Sanity check that provider still belongs to source package
7283                        final ProviderInfo pi = getProviderInfoLocked(
7284                                uri.getAuthority(), sourceUserId);
7285                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7286                            int targetUid = -1;
7287                            try {
7288                                targetUid = AppGlobals.getPackageManager()
7289                                        .getPackageUid(targetPkg, targetUserId);
7290                            } catch (RemoteException e) {
7291                            }
7292                            if (targetUid != -1) {
7293                                final UriPermission perm = findOrCreateUriPermissionLocked(
7294                                        sourcePkg, targetPkg, targetUid,
7295                                        new GrantUri(sourceUserId, uri, prefix));
7296                                perm.initPersistedModes(modeFlags, createdTime);
7297                            }
7298                        } else {
7299                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7300                                    + " but instead found " + pi);
7301                        }
7302                    }
7303                }
7304            }
7305        } catch (FileNotFoundException e) {
7306            // Missing grants is okay
7307        } catch (IOException e) {
7308            Log.wtf(TAG, "Failed reading Uri grants", e);
7309        } catch (XmlPullParserException e) {
7310            Log.wtf(TAG, "Failed reading Uri grants", e);
7311        } finally {
7312            IoUtils.closeQuietly(fis);
7313        }
7314    }
7315
7316    @Override
7317    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7318        enforceNotIsolatedCaller("takePersistableUriPermission");
7319
7320        Preconditions.checkFlagsArgument(modeFlags,
7321                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7322
7323        synchronized (this) {
7324            final int callingUid = Binder.getCallingUid();
7325            boolean persistChanged = false;
7326            GrantUri grantUri = new GrantUri(userId, uri, false);
7327
7328            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7329                    new GrantUri(userId, uri, false));
7330            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7331                    new GrantUri(userId, uri, true));
7332
7333            final boolean exactValid = (exactPerm != null)
7334                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7335            final boolean prefixValid = (prefixPerm != null)
7336                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7337
7338            if (!(exactValid || prefixValid)) {
7339                throw new SecurityException("No persistable permission grants found for UID "
7340                        + callingUid + " and Uri " + grantUri.toSafeString());
7341            }
7342
7343            if (exactValid) {
7344                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7345            }
7346            if (prefixValid) {
7347                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7348            }
7349
7350            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7351
7352            if (persistChanged) {
7353                schedulePersistUriGrants();
7354            }
7355        }
7356    }
7357
7358    @Override
7359    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7360        enforceNotIsolatedCaller("releasePersistableUriPermission");
7361
7362        Preconditions.checkFlagsArgument(modeFlags,
7363                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7364
7365        synchronized (this) {
7366            final int callingUid = Binder.getCallingUid();
7367            boolean persistChanged = false;
7368
7369            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7370                    new GrantUri(userId, uri, false));
7371            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7372                    new GrantUri(userId, uri, true));
7373            if (exactPerm == null && prefixPerm == null) {
7374                throw new SecurityException("No permission grants found for UID " + callingUid
7375                        + " and Uri " + uri.toSafeString());
7376            }
7377
7378            if (exactPerm != null) {
7379                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7380                removeUriPermissionIfNeededLocked(exactPerm);
7381            }
7382            if (prefixPerm != null) {
7383                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7384                removeUriPermissionIfNeededLocked(prefixPerm);
7385            }
7386
7387            if (persistChanged) {
7388                schedulePersistUriGrants();
7389            }
7390        }
7391    }
7392
7393    /**
7394     * Prune any older {@link UriPermission} for the given UID until outstanding
7395     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7396     *
7397     * @return if any mutations occured that require persisting.
7398     */
7399    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7400        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7401        if (perms == null) return false;
7402        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7403
7404        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7405        for (UriPermission perm : perms.values()) {
7406            if (perm.persistedModeFlags != 0) {
7407                persisted.add(perm);
7408            }
7409        }
7410
7411        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7412        if (trimCount <= 0) return false;
7413
7414        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7415        for (int i = 0; i < trimCount; i++) {
7416            final UriPermission perm = persisted.get(i);
7417
7418            if (DEBUG_URI_PERMISSION) {
7419                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7420            }
7421
7422            perm.releasePersistableModes(~0);
7423            removeUriPermissionIfNeededLocked(perm);
7424        }
7425
7426        return true;
7427    }
7428
7429    @Override
7430    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7431            String packageName, boolean incoming) {
7432        enforceNotIsolatedCaller("getPersistedUriPermissions");
7433        Preconditions.checkNotNull(packageName, "packageName");
7434
7435        final int callingUid = Binder.getCallingUid();
7436        final IPackageManager pm = AppGlobals.getPackageManager();
7437        try {
7438            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7439            if (packageUid != callingUid) {
7440                throw new SecurityException(
7441                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7442            }
7443        } catch (RemoteException e) {
7444            throw new SecurityException("Failed to verify package name ownership");
7445        }
7446
7447        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7448        synchronized (this) {
7449            if (incoming) {
7450                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7451                        callingUid);
7452                if (perms == null) {
7453                    Slog.w(TAG, "No permission grants found for " + packageName);
7454                } else {
7455                    for (UriPermission perm : perms.values()) {
7456                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7457                            result.add(perm.buildPersistedPublicApiObject());
7458                        }
7459                    }
7460                }
7461            } else {
7462                final int size = mGrantedUriPermissions.size();
7463                for (int i = 0; i < size; i++) {
7464                    final ArrayMap<GrantUri, UriPermission> perms =
7465                            mGrantedUriPermissions.valueAt(i);
7466                    for (UriPermission perm : perms.values()) {
7467                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7468                            result.add(perm.buildPersistedPublicApiObject());
7469                        }
7470                    }
7471                }
7472            }
7473        }
7474        return new ParceledListSlice<android.content.UriPermission>(result);
7475    }
7476
7477    @Override
7478    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7479        synchronized (this) {
7480            ProcessRecord app =
7481                who != null ? getRecordForAppLocked(who) : null;
7482            if (app == null) return;
7483
7484            Message msg = Message.obtain();
7485            msg.what = WAIT_FOR_DEBUGGER_MSG;
7486            msg.obj = app;
7487            msg.arg1 = waiting ? 1 : 0;
7488            mHandler.sendMessage(msg);
7489        }
7490    }
7491
7492    @Override
7493    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7494        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7495        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7496        outInfo.availMem = Process.getFreeMemory();
7497        outInfo.totalMem = Process.getTotalMemory();
7498        outInfo.threshold = homeAppMem;
7499        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7500        outInfo.hiddenAppThreshold = cachedAppMem;
7501        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7502                ProcessList.SERVICE_ADJ);
7503        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7504                ProcessList.VISIBLE_APP_ADJ);
7505        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7506                ProcessList.FOREGROUND_APP_ADJ);
7507    }
7508
7509    // =========================================================
7510    // TASK MANAGEMENT
7511    // =========================================================
7512
7513    @Override
7514    public List<IAppTask> getAppTasks() {
7515        final PackageManager pm = mContext.getPackageManager();
7516        int callingUid = Binder.getCallingUid();
7517        long ident = Binder.clearCallingIdentity();
7518
7519        // Compose the list of packages for this id to test against
7520        HashSet<String> packages = new HashSet<String>();
7521        String[] uidPackages = pm.getPackagesForUid(callingUid);
7522        for (int i = 0; i < uidPackages.length; i++) {
7523            packages.add(uidPackages[i]);
7524        }
7525
7526        synchronized(this) {
7527            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7528            try {
7529                if (localLOGV) Slog.v(TAG, "getAppTasks");
7530
7531                final int N = mRecentTasks.size();
7532                for (int i = 0; i < N; i++) {
7533                    TaskRecord tr = mRecentTasks.get(i);
7534                    // Skip tasks that do not match the package name
7535                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7536                        ActivityManager.RecentTaskInfo taskInfo =
7537                                createRecentTaskInfoFromTaskRecord(tr);
7538                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7539                        list.add(taskImpl);
7540                    }
7541                }
7542            } finally {
7543                Binder.restoreCallingIdentity(ident);
7544            }
7545            return list;
7546        }
7547    }
7548
7549    @Override
7550    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7551        final int callingUid = Binder.getCallingUid();
7552        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7553
7554        synchronized(this) {
7555            if (localLOGV) Slog.v(
7556                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7557
7558            final boolean allowed = checkCallingPermission(
7559                    android.Manifest.permission.GET_TASKS)
7560                    == PackageManager.PERMISSION_GRANTED;
7561            if (!allowed) {
7562                Slog.w(TAG, "getTasks: caller " + callingUid
7563                        + " does not hold GET_TASKS; limiting output");
7564            }
7565
7566            // TODO: Improve with MRU list from all ActivityStacks.
7567            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7568        }
7569
7570        return list;
7571    }
7572
7573    TaskRecord getMostRecentTask() {
7574        return mRecentTasks.get(0);
7575    }
7576
7577    /**
7578     * Creates a new RecentTaskInfo from a TaskRecord.
7579     */
7580    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7581        // Update the task description to reflect any changes in the task stack
7582        tr.updateTaskDescription();
7583
7584        // Compose the recent task info
7585        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7586        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7587        rti.persistentId = tr.taskId;
7588        rti.baseIntent = new Intent(tr.getBaseIntent());
7589        rti.origActivity = tr.origActivity;
7590        rti.description = tr.lastDescription;
7591        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7592        rti.userId = tr.userId;
7593        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7594        rti.firstActiveTime = tr.firstActiveTime;
7595        rti.lastActiveTime = tr.lastActiveTime;
7596        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7597        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7598        return rti;
7599    }
7600
7601    @Override
7602    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7603        final int callingUid = Binder.getCallingUid();
7604        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7605                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7606
7607        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7608        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7609        synchronized (this) {
7610            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7611                    == PackageManager.PERMISSION_GRANTED;
7612            if (!allowed) {
7613                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7614                        + " does not hold GET_TASKS; limiting output");
7615            }
7616            final boolean detailed = checkCallingPermission(
7617                    android.Manifest.permission.GET_DETAILED_TASKS)
7618                    == PackageManager.PERMISSION_GRANTED;
7619
7620            IPackageManager pm = AppGlobals.getPackageManager();
7621
7622            final int N = mRecentTasks.size();
7623            ArrayList<ActivityManager.RecentTaskInfo> res
7624                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7625                            maxNum < N ? maxNum : N);
7626
7627            final Set<Integer> includedUsers;
7628            if (includeProfiles) {
7629                includedUsers = getProfileIdsLocked(userId);
7630            } else {
7631                includedUsers = new HashSet<Integer>();
7632            }
7633            includedUsers.add(Integer.valueOf(userId));
7634
7635            // Regroup affiliated tasks together.
7636            for (int i = 0; i < N; ) {
7637                TaskRecord task = mRecentTasks.remove(i);
7638                if (mTmpRecents.contains(task)) {
7639                    continue;
7640                }
7641                int affiliatedTaskId = task.mAffiliatedTaskId;
7642                while (true) {
7643                    TaskRecord next = task.mNextAffiliate;
7644                    if (next == null) {
7645                        break;
7646                    }
7647                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7648                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7649                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7650                        task.setNextAffiliate(null);
7651                        if (next.mPrevAffiliate == task) {
7652                            next.setPrevAffiliate(null);
7653                        }
7654                        break;
7655                    }
7656                    if (next.mPrevAffiliate != task) {
7657                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7658                                next.mPrevAffiliate + " task=" + task);
7659                        next.setPrevAffiliate(null);
7660                        break;
7661                    }
7662                    if (!mRecentTasks.contains(next)) {
7663                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7664                        task.setNextAffiliate(null);
7665                        if (next.mPrevAffiliate == task) {
7666                            next.setPrevAffiliate(null);
7667                        }
7668                        break;
7669                    }
7670                    task = next;
7671                }
7672                // task is now the end of the list
7673                do {
7674                    mRecentTasks.remove(task);
7675                    mRecentTasks.add(i++, task);
7676                    mTmpRecents.add(task);
7677                } while ((task = task.mPrevAffiliate) != null);
7678            }
7679            mTmpRecents.clear();
7680            // mRecentTasks is now in sorted, affiliated order.
7681
7682            for (int i=0; i<N && maxNum > 0; i++) {
7683                TaskRecord tr = mRecentTasks.get(i);
7684                // Only add calling user or related users recent tasks
7685                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7686                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7687                    continue;
7688                }
7689
7690                // Return the entry if desired by the caller.  We always return
7691                // the first entry, because callers always expect this to be the
7692                // foreground app.  We may filter others if the caller has
7693                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7694                // we should exclude the entry.
7695
7696                if (i == 0
7697                        || withExcluded
7698                        || (tr.intent == null)
7699                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7700                                == 0)) {
7701                    if (!allowed) {
7702                        // If the caller doesn't have the GET_TASKS permission, then only
7703                        // allow them to see a small subset of tasks -- their own and home.
7704                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7705                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7706                            continue;
7707                        }
7708                    }
7709                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7710                        if (tr.stack != null && tr.stack.isHomeStack()) {
7711                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7712                            continue;
7713                        }
7714                    }
7715                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7716                        // Don't include auto remove tasks that are finished or finishing.
7717                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7718                                + tr);
7719                        continue;
7720                    }
7721
7722                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7723                    if (!detailed) {
7724                        rti.baseIntent.replaceExtras((Bundle)null);
7725                    }
7726
7727                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7728                        // Check whether this activity is currently available.
7729                        try {
7730                            if (rti.origActivity != null) {
7731                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7732                                        == null) {
7733                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail orig act: "
7734                                            + tr);
7735                                    continue;
7736                                }
7737                            } else if (rti.baseIntent != null) {
7738                                if (pm.queryIntentActivities(rti.baseIntent,
7739                                        null, 0, userId) == null) {
7740                                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail intent: "
7741                                            + tr);
7742                                    continue;
7743                                }
7744                            }
7745                        } catch (RemoteException e) {
7746                            // Will never happen.
7747                        }
7748                    }
7749
7750                    res.add(rti);
7751                    maxNum--;
7752                }
7753            }
7754            return res;
7755        }
7756    }
7757
7758    private TaskRecord recentTaskForIdLocked(int id) {
7759        final int N = mRecentTasks.size();
7760            for (int i=0; i<N; i++) {
7761                TaskRecord tr = mRecentTasks.get(i);
7762                if (tr.taskId == id) {
7763                    return tr;
7764                }
7765            }
7766            return null;
7767    }
7768
7769    @Override
7770    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7771        synchronized (this) {
7772            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7773                    "getTaskThumbnail()");
7774            TaskRecord tr = recentTaskForIdLocked(id);
7775            if (tr != null) {
7776                return tr.getTaskThumbnailLocked();
7777            }
7778        }
7779        return null;
7780    }
7781
7782    @Override
7783    public int addAppTask(IBinder activityToken, Intent intent,
7784            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7785        final int callingUid = Binder.getCallingUid();
7786        final long callingIdent = Binder.clearCallingIdentity();
7787
7788        try {
7789            synchronized (this) {
7790                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7791                if (r == null) {
7792                    throw new IllegalArgumentException("Activity does not exist; token="
7793                            + activityToken);
7794                }
7795                ComponentName comp = intent.getComponent();
7796                if (comp == null) {
7797                    throw new IllegalArgumentException("Intent " + intent
7798                            + " must specify explicit component");
7799                }
7800                if (thumbnail.getWidth() != mThumbnailWidth
7801                        || thumbnail.getHeight() != mThumbnailHeight) {
7802                    throw new IllegalArgumentException("Bad thumbnail size: got "
7803                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7804                            + mThumbnailWidth + "x" + mThumbnailHeight);
7805                }
7806                if (intent.getSelector() != null) {
7807                    intent.setSelector(null);
7808                }
7809                if (intent.getSourceBounds() != null) {
7810                    intent.setSourceBounds(null);
7811                }
7812                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7813                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7814                        // The caller has added this as an auto-remove task...  that makes no
7815                        // sense, so turn off auto-remove.
7816                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7817                    }
7818                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7819                    // Must be a new task.
7820                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7821                }
7822                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7823                    mLastAddedTaskActivity = null;
7824                }
7825                ActivityInfo ainfo = mLastAddedTaskActivity;
7826                if (ainfo == null) {
7827                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7828                            comp, 0, UserHandle.getUserId(callingUid));
7829                    if (ainfo.applicationInfo.uid != callingUid) {
7830                        throw new SecurityException(
7831                                "Can't add task for another application: target uid="
7832                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7833                    }
7834                }
7835
7836                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7837                        intent, description);
7838
7839                int trimIdx = trimRecentsForTask(task, false);
7840                if (trimIdx >= 0) {
7841                    // If this would have caused a trim, then we'll abort because that
7842                    // means it would be added at the end of the list but then just removed.
7843                    return -1;
7844                }
7845
7846                final int N = mRecentTasks.size();
7847                if (N >= (MAX_RECENT_TASKS-1)) {
7848                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7849                    tr.disposeThumbnail();
7850                    tr.closeRecentsChain();
7851                }
7852
7853                mRecentTasks.add(task);
7854                r.task.stack.addTask(task, false, false);
7855
7856                task.setLastThumbnail(thumbnail);
7857                task.freeLastThumbnail();
7858
7859                return task.taskId;
7860            }
7861        } finally {
7862            Binder.restoreCallingIdentity(callingIdent);
7863        }
7864    }
7865
7866    @Override
7867    public Point getAppTaskThumbnailSize() {
7868        synchronized (this) {
7869            return new Point(mThumbnailWidth,  mThumbnailHeight);
7870        }
7871    }
7872
7873    @Override
7874    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7875        synchronized (this) {
7876            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7877            if (r != null) {
7878                r.taskDescription = td;
7879                r.task.updateTaskDescription();
7880            }
7881        }
7882    }
7883
7884    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7885        if (!pr.killedByAm) {
7886            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7887            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7888                    pr.processName, pr.setAdj, reason);
7889            pr.killedByAm = true;
7890            Process.killProcessQuiet(pr.pid);
7891            Process.killProcessGroup(pr.info.uid, pr.pid);
7892        }
7893    }
7894
7895    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7896        tr.disposeThumbnail();
7897        mRecentTasks.remove(tr);
7898        tr.closeRecentsChain();
7899        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7900        Intent baseIntent = new Intent(
7901                tr.intent != null ? tr.intent : tr.affinityIntent);
7902        ComponentName component = baseIntent.getComponent();
7903        if (component == null) {
7904            Slog.w(TAG, "Now component for base intent of task: " + tr);
7905            return;
7906        }
7907
7908        // Find any running services associated with this app.
7909        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7910
7911        if (killProcesses) {
7912            // Find any running processes associated with this app.
7913            final String pkg = component.getPackageName();
7914            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7915            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7916            for (int i=0; i<pmap.size(); i++) {
7917                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7918                for (int j=0; j<uids.size(); j++) {
7919                    ProcessRecord proc = uids.valueAt(j);
7920                    if (proc.userId != tr.userId) {
7921                        continue;
7922                    }
7923                    if (!proc.pkgList.containsKey(pkg)) {
7924                        continue;
7925                    }
7926                    procs.add(proc);
7927                }
7928            }
7929
7930            // Kill the running processes.
7931            for (int i=0; i<procs.size(); i++) {
7932                ProcessRecord pr = procs.get(i);
7933                if (pr == mHomeProcess) {
7934                    // Don't kill the home process along with tasks from the same package.
7935                    continue;
7936                }
7937                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7938                    killUnneededProcessLocked(pr, "remove task");
7939                } else {
7940                    pr.waitingToKill = "remove task";
7941                }
7942            }
7943        }
7944    }
7945
7946    /**
7947     * Removes the task with the specified task id.
7948     *
7949     * @param taskId Identifier of the task to be removed.
7950     * @param flags Additional operational flags.  May be 0 or
7951     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7952     * @return Returns true if the given task was found and removed.
7953     */
7954    private boolean removeTaskByIdLocked(int taskId, int flags) {
7955        TaskRecord tr = recentTaskForIdLocked(taskId);
7956        if (tr != null) {
7957            tr.removeTaskActivitiesLocked();
7958            cleanUpRemovedTaskLocked(tr, flags);
7959            if (tr.isPersistable) {
7960                notifyTaskPersisterLocked(null, true);
7961            }
7962            return true;
7963        }
7964        return false;
7965    }
7966
7967    @Override
7968    public boolean removeTask(int taskId, int flags) {
7969        synchronized (this) {
7970            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7971                    "removeTask()");
7972            long ident = Binder.clearCallingIdentity();
7973            try {
7974                return removeTaskByIdLocked(taskId, flags);
7975            } finally {
7976                Binder.restoreCallingIdentity(ident);
7977            }
7978        }
7979    }
7980
7981    /**
7982     * TODO: Add mController hook
7983     */
7984    @Override
7985    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7986        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7987                "moveTaskToFront()");
7988
7989        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7990        synchronized(this) {
7991            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7992                    Binder.getCallingUid(), "Task to front")) {
7993                ActivityOptions.abort(options);
7994                return;
7995            }
7996            final long origId = Binder.clearCallingIdentity();
7997            try {
7998                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7999                if (task == null) {
8000                    return;
8001                }
8002                if (mStackSupervisor.isLockTaskModeViolation(task)) {
8003                    mStackSupervisor.showLockTaskToast();
8004                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8005                    return;
8006                }
8007                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8008                if (prev != null && prev.isRecentsActivity()) {
8009                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8010                }
8011                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8012            } finally {
8013                Binder.restoreCallingIdentity(origId);
8014            }
8015            ActivityOptions.abort(options);
8016        }
8017    }
8018
8019    @Override
8020    public void moveTaskToBack(int taskId) {
8021        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8022                "moveTaskToBack()");
8023
8024        synchronized(this) {
8025            TaskRecord tr = recentTaskForIdLocked(taskId);
8026            if (tr != null) {
8027                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8028                ActivityStack stack = tr.stack;
8029                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8030                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8031                            Binder.getCallingUid(), "Task to back")) {
8032                        return;
8033                    }
8034                }
8035                final long origId = Binder.clearCallingIdentity();
8036                try {
8037                    stack.moveTaskToBackLocked(taskId, null);
8038                } finally {
8039                    Binder.restoreCallingIdentity(origId);
8040                }
8041            }
8042        }
8043    }
8044
8045    /**
8046     * Moves an activity, and all of the other activities within the same task, to the bottom
8047     * of the history stack.  The activity's order within the task is unchanged.
8048     *
8049     * @param token A reference to the activity we wish to move
8050     * @param nonRoot If false then this only works if the activity is the root
8051     *                of a task; if true it will work for any activity in a task.
8052     * @return Returns true if the move completed, false if not.
8053     */
8054    @Override
8055    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8056        enforceNotIsolatedCaller("moveActivityTaskToBack");
8057        synchronized(this) {
8058            final long origId = Binder.clearCallingIdentity();
8059            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8060            if (taskId >= 0) {
8061                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8062            }
8063            Binder.restoreCallingIdentity(origId);
8064        }
8065        return false;
8066    }
8067
8068    @Override
8069    public void moveTaskBackwards(int task) {
8070        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8071                "moveTaskBackwards()");
8072
8073        synchronized(this) {
8074            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8075                    Binder.getCallingUid(), "Task backwards")) {
8076                return;
8077            }
8078            final long origId = Binder.clearCallingIdentity();
8079            moveTaskBackwardsLocked(task);
8080            Binder.restoreCallingIdentity(origId);
8081        }
8082    }
8083
8084    private final void moveTaskBackwardsLocked(int task) {
8085        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8086    }
8087
8088    @Override
8089    public IBinder getHomeActivityToken() throws RemoteException {
8090        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8091                "getHomeActivityToken()");
8092        synchronized (this) {
8093            return mStackSupervisor.getHomeActivityToken();
8094        }
8095    }
8096
8097    @Override
8098    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8099            IActivityContainerCallback callback) throws RemoteException {
8100        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8101                "createActivityContainer()");
8102        synchronized (this) {
8103            if (parentActivityToken == null) {
8104                throw new IllegalArgumentException("parent token must not be null");
8105            }
8106            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8107            if (r == null) {
8108                return null;
8109            }
8110            if (callback == null) {
8111                throw new IllegalArgumentException("callback must not be null");
8112            }
8113            return mStackSupervisor.createActivityContainer(r, callback);
8114        }
8115    }
8116
8117    @Override
8118    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8119        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8120                "deleteActivityContainer()");
8121        synchronized (this) {
8122            mStackSupervisor.deleteActivityContainer(container);
8123        }
8124    }
8125
8126    @Override
8127    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8128            throws RemoteException {
8129        synchronized (this) {
8130            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8131            if (stack != null) {
8132                return stack.mActivityContainer;
8133            }
8134            return null;
8135        }
8136    }
8137
8138    @Override
8139    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8140        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8141                "moveTaskToStack()");
8142        if (stackId == HOME_STACK_ID) {
8143            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8144                    new RuntimeException("here").fillInStackTrace());
8145        }
8146        synchronized (this) {
8147            long ident = Binder.clearCallingIdentity();
8148            try {
8149                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8150                        + stackId + " toTop=" + toTop);
8151                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8152            } finally {
8153                Binder.restoreCallingIdentity(ident);
8154            }
8155        }
8156    }
8157
8158    @Override
8159    public void resizeStack(int stackBoxId, Rect bounds) {
8160        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8161                "resizeStackBox()");
8162        long ident = Binder.clearCallingIdentity();
8163        try {
8164            mWindowManager.resizeStack(stackBoxId, bounds);
8165        } finally {
8166            Binder.restoreCallingIdentity(ident);
8167        }
8168    }
8169
8170    @Override
8171    public List<StackInfo> getAllStackInfos() {
8172        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8173                "getAllStackInfos()");
8174        long ident = Binder.clearCallingIdentity();
8175        try {
8176            synchronized (this) {
8177                return mStackSupervisor.getAllStackInfosLocked();
8178            }
8179        } finally {
8180            Binder.restoreCallingIdentity(ident);
8181        }
8182    }
8183
8184    @Override
8185    public StackInfo getStackInfo(int stackId) {
8186        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8187                "getStackInfo()");
8188        long ident = Binder.clearCallingIdentity();
8189        try {
8190            synchronized (this) {
8191                return mStackSupervisor.getStackInfoLocked(stackId);
8192            }
8193        } finally {
8194            Binder.restoreCallingIdentity(ident);
8195        }
8196    }
8197
8198    @Override
8199    public boolean isInHomeStack(int taskId) {
8200        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8201                "getStackInfo()");
8202        long ident = Binder.clearCallingIdentity();
8203        try {
8204            synchronized (this) {
8205                TaskRecord tr = recentTaskForIdLocked(taskId);
8206                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8207            }
8208        } finally {
8209            Binder.restoreCallingIdentity(ident);
8210        }
8211    }
8212
8213    @Override
8214    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8215        synchronized(this) {
8216            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8217        }
8218    }
8219
8220    private boolean isLockTaskAuthorized(String pkg) {
8221        final DevicePolicyManager dpm = (DevicePolicyManager)
8222                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8223        try {
8224            int uid = mContext.getPackageManager().getPackageUid(pkg,
8225                    Binder.getCallingUserHandle().getIdentifier());
8226            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8227        } catch (NameNotFoundException e) {
8228            return false;
8229        }
8230    }
8231
8232    void startLockTaskMode(TaskRecord task) {
8233        final String pkg;
8234        synchronized (this) {
8235            pkg = task.intent.getComponent().getPackageName();
8236        }
8237        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8238        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8239            final TaskRecord taskRecord = task;
8240            mHandler.post(new Runnable() {
8241                @Override
8242                public void run() {
8243                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8244                }
8245            });
8246            return;
8247        }
8248        long ident = Binder.clearCallingIdentity();
8249        try {
8250            synchronized (this) {
8251                // Since we lost lock on task, make sure it is still there.
8252                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8253                if (task != null) {
8254                    if (!isSystemInitiated
8255                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8256                        throw new IllegalArgumentException("Invalid task, not in foreground");
8257                    }
8258                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8259                }
8260            }
8261        } finally {
8262            Binder.restoreCallingIdentity(ident);
8263        }
8264    }
8265
8266    @Override
8267    public void startLockTaskMode(int taskId) {
8268        final TaskRecord task;
8269        long ident = Binder.clearCallingIdentity();
8270        try {
8271            synchronized (this) {
8272                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8273            }
8274        } finally {
8275            Binder.restoreCallingIdentity(ident);
8276        }
8277        if (task != null) {
8278            startLockTaskMode(task);
8279        }
8280    }
8281
8282    @Override
8283    public void startLockTaskMode(IBinder token) {
8284        final TaskRecord task;
8285        long ident = Binder.clearCallingIdentity();
8286        try {
8287            synchronized (this) {
8288                final ActivityRecord r = ActivityRecord.forToken(token);
8289                if (r == null) {
8290                    return;
8291                }
8292                task = r.task;
8293            }
8294        } finally {
8295            Binder.restoreCallingIdentity(ident);
8296        }
8297        if (task != null) {
8298            startLockTaskMode(task);
8299        }
8300    }
8301
8302    @Override
8303    public void startLockTaskModeOnCurrent() throws RemoteException {
8304        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8305        ActivityRecord r = null;
8306        synchronized (this) {
8307            r = mStackSupervisor.topRunningActivityLocked();
8308        }
8309        startLockTaskMode(r.task);
8310    }
8311
8312    @Override
8313    public void stopLockTaskMode() {
8314        // Verify that the user matches the package of the intent for the TaskRecord
8315        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8316        // and stopLockTaskMode.
8317        final int callingUid = Binder.getCallingUid();
8318        if (callingUid != Process.SYSTEM_UID) {
8319            try {
8320                String pkg =
8321                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8322                int uid = mContext.getPackageManager().getPackageUid(pkg,
8323                        Binder.getCallingUserHandle().getIdentifier());
8324                if (uid != callingUid) {
8325                    throw new SecurityException("Invalid uid, expected " + uid);
8326                }
8327            } catch (NameNotFoundException e) {
8328                Log.d(TAG, "stopLockTaskMode " + e);
8329                return;
8330            }
8331        }
8332        long ident = Binder.clearCallingIdentity();
8333        try {
8334            Log.d(TAG, "stopLockTaskMode");
8335            // Stop lock task
8336            synchronized (this) {
8337                mStackSupervisor.setLockTaskModeLocked(null, false);
8338            }
8339        } finally {
8340            Binder.restoreCallingIdentity(ident);
8341        }
8342    }
8343
8344    @Override
8345    public void stopLockTaskModeOnCurrent() throws RemoteException {
8346        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8347        long ident = Binder.clearCallingIdentity();
8348        try {
8349            stopLockTaskMode();
8350        } finally {
8351            Binder.restoreCallingIdentity(ident);
8352        }
8353    }
8354
8355    @Override
8356    public boolean isInLockTaskMode() {
8357        synchronized (this) {
8358            return mStackSupervisor.isInLockTaskMode();
8359        }
8360    }
8361
8362    // =========================================================
8363    // CONTENT PROVIDERS
8364    // =========================================================
8365
8366    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8367        List<ProviderInfo> providers = null;
8368        try {
8369            providers = AppGlobals.getPackageManager().
8370                queryContentProviders(app.processName, app.uid,
8371                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8372        } catch (RemoteException ex) {
8373        }
8374        if (DEBUG_MU)
8375            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8376        int userId = app.userId;
8377        if (providers != null) {
8378            int N = providers.size();
8379            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8380            for (int i=0; i<N; i++) {
8381                ProviderInfo cpi =
8382                    (ProviderInfo)providers.get(i);
8383                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8384                        cpi.name, cpi.flags);
8385                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8386                    // This is a singleton provider, but a user besides the
8387                    // default user is asking to initialize a process it runs
8388                    // in...  well, no, it doesn't actually run in this process,
8389                    // it runs in the process of the default user.  Get rid of it.
8390                    providers.remove(i);
8391                    N--;
8392                    i--;
8393                    continue;
8394                }
8395
8396                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8397                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8398                if (cpr == null) {
8399                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8400                    mProviderMap.putProviderByClass(comp, cpr);
8401                }
8402                if (DEBUG_MU)
8403                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8404                app.pubProviders.put(cpi.name, cpr);
8405                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8406                    // Don't add this if it is a platform component that is marked
8407                    // to run in multiple processes, because this is actually
8408                    // part of the framework so doesn't make sense to track as a
8409                    // separate apk in the process.
8410                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8411                            mProcessStats);
8412                }
8413                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8414            }
8415        }
8416        return providers;
8417    }
8418
8419    /**
8420     * Check if {@link ProcessRecord} has a possible chance at accessing the
8421     * given {@link ProviderInfo}. Final permission checking is always done
8422     * in {@link ContentProvider}.
8423     */
8424    private final String checkContentProviderPermissionLocked(
8425            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8426        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8427        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8428        boolean checkedGrants = false;
8429        if (checkUser) {
8430            // Looking for cross-user grants before enforcing the typical cross-users permissions
8431            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8432            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8433                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8434                    return null;
8435                }
8436                checkedGrants = true;
8437            }
8438            userId = handleIncomingUser(callingPid, callingUid, userId,
8439                    false, ALLOW_NON_FULL,
8440                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8441            if (userId != tmpTargetUserId) {
8442                // When we actually went to determine the final targer user ID, this ended
8443                // up different than our initial check for the authority.  This is because
8444                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8445                // SELF.  So we need to re-check the grants again.
8446                checkedGrants = false;
8447            }
8448        }
8449        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8450                cpi.applicationInfo.uid, cpi.exported)
8451                == PackageManager.PERMISSION_GRANTED) {
8452            return null;
8453        }
8454        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8455                cpi.applicationInfo.uid, cpi.exported)
8456                == PackageManager.PERMISSION_GRANTED) {
8457            return null;
8458        }
8459
8460        PathPermission[] pps = cpi.pathPermissions;
8461        if (pps != null) {
8462            int i = pps.length;
8463            while (i > 0) {
8464                i--;
8465                PathPermission pp = pps[i];
8466                String pprperm = pp.getReadPermission();
8467                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8468                        cpi.applicationInfo.uid, cpi.exported)
8469                        == PackageManager.PERMISSION_GRANTED) {
8470                    return null;
8471                }
8472                String ppwperm = pp.getWritePermission();
8473                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8474                        cpi.applicationInfo.uid, cpi.exported)
8475                        == PackageManager.PERMISSION_GRANTED) {
8476                    return null;
8477                }
8478            }
8479        }
8480        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8481            return null;
8482        }
8483
8484        String msg;
8485        if (!cpi.exported) {
8486            msg = "Permission Denial: opening provider " + cpi.name
8487                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8488                    + ", uid=" + callingUid + ") that is not exported from uid "
8489                    + cpi.applicationInfo.uid;
8490        } else {
8491            msg = "Permission Denial: opening provider " + cpi.name
8492                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8493                    + ", uid=" + callingUid + ") requires "
8494                    + cpi.readPermission + " or " + cpi.writePermission;
8495        }
8496        Slog.w(TAG, msg);
8497        return msg;
8498    }
8499
8500    /**
8501     * Returns if the ContentProvider has granted a uri to callingUid
8502     */
8503    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8504        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8505        if (perms != null) {
8506            for (int i=perms.size()-1; i>=0; i--) {
8507                GrantUri grantUri = perms.keyAt(i);
8508                if (grantUri.sourceUserId == userId || !checkUser) {
8509                    if (matchesProvider(grantUri.uri, cpi)) {
8510                        return true;
8511                    }
8512                }
8513            }
8514        }
8515        return false;
8516    }
8517
8518    /**
8519     * Returns true if the uri authority is one of the authorities specified in the provider.
8520     */
8521    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8522        String uriAuth = uri.getAuthority();
8523        String cpiAuth = cpi.authority;
8524        if (cpiAuth.indexOf(';') == -1) {
8525            return cpiAuth.equals(uriAuth);
8526        }
8527        String[] cpiAuths = cpiAuth.split(";");
8528        int length = cpiAuths.length;
8529        for (int i = 0; i < length; i++) {
8530            if (cpiAuths[i].equals(uriAuth)) return true;
8531        }
8532        return false;
8533    }
8534
8535    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8536            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8537        if (r != null) {
8538            for (int i=0; i<r.conProviders.size(); i++) {
8539                ContentProviderConnection conn = r.conProviders.get(i);
8540                if (conn.provider == cpr) {
8541                    if (DEBUG_PROVIDER) Slog.v(TAG,
8542                            "Adding provider requested by "
8543                            + r.processName + " from process "
8544                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8545                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8546                    if (stable) {
8547                        conn.stableCount++;
8548                        conn.numStableIncs++;
8549                    } else {
8550                        conn.unstableCount++;
8551                        conn.numUnstableIncs++;
8552                    }
8553                    return conn;
8554                }
8555            }
8556            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8557            if (stable) {
8558                conn.stableCount = 1;
8559                conn.numStableIncs = 1;
8560            } else {
8561                conn.unstableCount = 1;
8562                conn.numUnstableIncs = 1;
8563            }
8564            cpr.connections.add(conn);
8565            r.conProviders.add(conn);
8566            return conn;
8567        }
8568        cpr.addExternalProcessHandleLocked(externalProcessToken);
8569        return null;
8570    }
8571
8572    boolean decProviderCountLocked(ContentProviderConnection conn,
8573            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8574        if (conn != null) {
8575            cpr = conn.provider;
8576            if (DEBUG_PROVIDER) Slog.v(TAG,
8577                    "Removing provider requested by "
8578                    + conn.client.processName + " from process "
8579                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8580                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8581            if (stable) {
8582                conn.stableCount--;
8583            } else {
8584                conn.unstableCount--;
8585            }
8586            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8587                cpr.connections.remove(conn);
8588                conn.client.conProviders.remove(conn);
8589                return true;
8590            }
8591            return false;
8592        }
8593        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8594        return false;
8595    }
8596
8597    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8598            String name, IBinder token, boolean stable, int userId) {
8599        ContentProviderRecord cpr;
8600        ContentProviderConnection conn = null;
8601        ProviderInfo cpi = null;
8602
8603        synchronized(this) {
8604            ProcessRecord r = null;
8605            if (caller != null) {
8606                r = getRecordForAppLocked(caller);
8607                if (r == null) {
8608                    throw new SecurityException(
8609                            "Unable to find app for caller " + caller
8610                          + " (pid=" + Binder.getCallingPid()
8611                          + ") when getting content provider " + name);
8612                }
8613            }
8614
8615            boolean checkCrossUser = true;
8616
8617            // First check if this content provider has been published...
8618            cpr = mProviderMap.getProviderByName(name, userId);
8619            // If that didn't work, check if it exists for user 0 and then
8620            // verify that it's a singleton provider before using it.
8621            if (cpr == null && userId != UserHandle.USER_OWNER) {
8622                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8623                if (cpr != null) {
8624                    cpi = cpr.info;
8625                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8626                            cpi.name, cpi.flags)
8627                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8628                        userId = UserHandle.USER_OWNER;
8629                        checkCrossUser = false;
8630                    } else {
8631                        cpr = null;
8632                        cpi = null;
8633                    }
8634                }
8635            }
8636
8637            boolean providerRunning = cpr != null;
8638            if (providerRunning) {
8639                cpi = cpr.info;
8640                String msg;
8641                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8642                        != null) {
8643                    throw new SecurityException(msg);
8644                }
8645
8646                if (r != null && cpr.canRunHere(r)) {
8647                    // This provider has been published or is in the process
8648                    // of being published...  but it is also allowed to run
8649                    // in the caller's process, so don't make a connection
8650                    // and just let the caller instantiate its own instance.
8651                    ContentProviderHolder holder = cpr.newHolder(null);
8652                    // don't give caller the provider object, it needs
8653                    // to make its own.
8654                    holder.provider = null;
8655                    return holder;
8656                }
8657
8658                final long origId = Binder.clearCallingIdentity();
8659
8660                // In this case the provider instance already exists, so we can
8661                // return it right away.
8662                conn = incProviderCountLocked(r, cpr, token, stable);
8663                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8664                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8665                        // If this is a perceptible app accessing the provider,
8666                        // make sure to count it as being accessed and thus
8667                        // back up on the LRU list.  This is good because
8668                        // content providers are often expensive to start.
8669                        updateLruProcessLocked(cpr.proc, false, null);
8670                    }
8671                }
8672
8673                if (cpr.proc != null) {
8674                    if (false) {
8675                        if (cpr.name.flattenToShortString().equals(
8676                                "com.android.providers.calendar/.CalendarProvider2")) {
8677                            Slog.v(TAG, "****************** KILLING "
8678                                + cpr.name.flattenToShortString());
8679                            Process.killProcess(cpr.proc.pid);
8680                        }
8681                    }
8682                    boolean success = updateOomAdjLocked(cpr.proc);
8683                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8684                    // NOTE: there is still a race here where a signal could be
8685                    // pending on the process even though we managed to update its
8686                    // adj level.  Not sure what to do about this, but at least
8687                    // the race is now smaller.
8688                    if (!success) {
8689                        // Uh oh...  it looks like the provider's process
8690                        // has been killed on us.  We need to wait for a new
8691                        // process to be started, and make sure its death
8692                        // doesn't kill our process.
8693                        Slog.i(TAG,
8694                                "Existing provider " + cpr.name.flattenToShortString()
8695                                + " is crashing; detaching " + r);
8696                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8697                        appDiedLocked(cpr.proc);
8698                        if (!lastRef) {
8699                            // This wasn't the last ref our process had on
8700                            // the provider...  we have now been killed, bail.
8701                            return null;
8702                        }
8703                        providerRunning = false;
8704                        conn = null;
8705                    }
8706                }
8707
8708                Binder.restoreCallingIdentity(origId);
8709            }
8710
8711            boolean singleton;
8712            if (!providerRunning) {
8713                try {
8714                    cpi = AppGlobals.getPackageManager().
8715                        resolveContentProvider(name,
8716                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8717                } catch (RemoteException ex) {
8718                }
8719                if (cpi == null) {
8720                    return null;
8721                }
8722                // If the provider is a singleton AND
8723                // (it's a call within the same user || the provider is a
8724                // privileged app)
8725                // Then allow connecting to the singleton provider
8726                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8727                        cpi.name, cpi.flags)
8728                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8729                if (singleton) {
8730                    userId = UserHandle.USER_OWNER;
8731                }
8732                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8733
8734                String msg;
8735                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8736                        != null) {
8737                    throw new SecurityException(msg);
8738                }
8739
8740                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8741                        && !cpi.processName.equals("system")) {
8742                    // If this content provider does not run in the system
8743                    // process, and the system is not yet ready to run other
8744                    // processes, then fail fast instead of hanging.
8745                    throw new IllegalArgumentException(
8746                            "Attempt to launch content provider before system ready");
8747                }
8748
8749                // Make sure that the user who owns this provider is started.  If not,
8750                // we don't want to allow it to run.
8751                if (mStartedUsers.get(userId) == null) {
8752                    Slog.w(TAG, "Unable to launch app "
8753                            + cpi.applicationInfo.packageName + "/"
8754                            + cpi.applicationInfo.uid + " for provider "
8755                            + name + ": user " + userId + " is stopped");
8756                    return null;
8757                }
8758
8759                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8760                cpr = mProviderMap.getProviderByClass(comp, userId);
8761                final boolean firstClass = cpr == null;
8762                if (firstClass) {
8763                    try {
8764                        ApplicationInfo ai =
8765                            AppGlobals.getPackageManager().
8766                                getApplicationInfo(
8767                                        cpi.applicationInfo.packageName,
8768                                        STOCK_PM_FLAGS, userId);
8769                        if (ai == null) {
8770                            Slog.w(TAG, "No package info for content provider "
8771                                    + cpi.name);
8772                            return null;
8773                        }
8774                        ai = getAppInfoForUser(ai, userId);
8775                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8776                    } catch (RemoteException ex) {
8777                        // pm is in same process, this will never happen.
8778                    }
8779                }
8780
8781                if (r != null && cpr.canRunHere(r)) {
8782                    // If this is a multiprocess provider, then just return its
8783                    // info and allow the caller to instantiate it.  Only do
8784                    // this if the provider is the same user as the caller's
8785                    // process, or can run as root (so can be in any process).
8786                    return cpr.newHolder(null);
8787                }
8788
8789                if (DEBUG_PROVIDER) {
8790                    RuntimeException e = new RuntimeException("here");
8791                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8792                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8793                }
8794
8795                // This is single process, and our app is now connecting to it.
8796                // See if we are already in the process of launching this
8797                // provider.
8798                final int N = mLaunchingProviders.size();
8799                int i;
8800                for (i=0; i<N; i++) {
8801                    if (mLaunchingProviders.get(i) == cpr) {
8802                        break;
8803                    }
8804                }
8805
8806                // If the provider is not already being launched, then get it
8807                // started.
8808                if (i >= N) {
8809                    final long origId = Binder.clearCallingIdentity();
8810
8811                    try {
8812                        // Content provider is now in use, its package can't be stopped.
8813                        try {
8814                            AppGlobals.getPackageManager().setPackageStoppedState(
8815                                    cpr.appInfo.packageName, false, userId);
8816                        } catch (RemoteException e) {
8817                        } catch (IllegalArgumentException e) {
8818                            Slog.w(TAG, "Failed trying to unstop package "
8819                                    + cpr.appInfo.packageName + ": " + e);
8820                        }
8821
8822                        // Use existing process if already started
8823                        ProcessRecord proc = getProcessRecordLocked(
8824                                cpi.processName, cpr.appInfo.uid, false);
8825                        if (proc != null && proc.thread != null) {
8826                            if (DEBUG_PROVIDER) {
8827                                Slog.d(TAG, "Installing in existing process " + proc);
8828                            }
8829                            proc.pubProviders.put(cpi.name, cpr);
8830                            try {
8831                                proc.thread.scheduleInstallProvider(cpi);
8832                            } catch (RemoteException e) {
8833                            }
8834                        } else {
8835                            proc = startProcessLocked(cpi.processName,
8836                                    cpr.appInfo, false, 0, "content provider",
8837                                    new ComponentName(cpi.applicationInfo.packageName,
8838                                            cpi.name), false, false, false);
8839                            if (proc == null) {
8840                                Slog.w(TAG, "Unable to launch app "
8841                                        + cpi.applicationInfo.packageName + "/"
8842                                        + cpi.applicationInfo.uid + " for provider "
8843                                        + name + ": process is bad");
8844                                return null;
8845                            }
8846                        }
8847                        cpr.launchingApp = proc;
8848                        mLaunchingProviders.add(cpr);
8849                    } finally {
8850                        Binder.restoreCallingIdentity(origId);
8851                    }
8852                }
8853
8854                // Make sure the provider is published (the same provider class
8855                // may be published under multiple names).
8856                if (firstClass) {
8857                    mProviderMap.putProviderByClass(comp, cpr);
8858                }
8859
8860                mProviderMap.putProviderByName(name, cpr);
8861                conn = incProviderCountLocked(r, cpr, token, stable);
8862                if (conn != null) {
8863                    conn.waiting = true;
8864                }
8865            }
8866        }
8867
8868        // Wait for the provider to be published...
8869        synchronized (cpr) {
8870            while (cpr.provider == null) {
8871                if (cpr.launchingApp == null) {
8872                    Slog.w(TAG, "Unable to launch app "
8873                            + cpi.applicationInfo.packageName + "/"
8874                            + cpi.applicationInfo.uid + " for provider "
8875                            + name + ": launching app became null");
8876                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8877                            UserHandle.getUserId(cpi.applicationInfo.uid),
8878                            cpi.applicationInfo.packageName,
8879                            cpi.applicationInfo.uid, name);
8880                    return null;
8881                }
8882                try {
8883                    if (DEBUG_MU) {
8884                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8885                                + cpr.launchingApp);
8886                    }
8887                    if (conn != null) {
8888                        conn.waiting = true;
8889                    }
8890                    cpr.wait();
8891                } catch (InterruptedException ex) {
8892                } finally {
8893                    if (conn != null) {
8894                        conn.waiting = false;
8895                    }
8896                }
8897            }
8898        }
8899        return cpr != null ? cpr.newHolder(conn) : null;
8900    }
8901
8902    @Override
8903    public final ContentProviderHolder getContentProvider(
8904            IApplicationThread caller, String name, int userId, boolean stable) {
8905        enforceNotIsolatedCaller("getContentProvider");
8906        if (caller == null) {
8907            String msg = "null IApplicationThread when getting content provider "
8908                    + name;
8909            Slog.w(TAG, msg);
8910            throw new SecurityException(msg);
8911        }
8912        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8913        // with cross-user grant.
8914        return getContentProviderImpl(caller, name, null, stable, userId);
8915    }
8916
8917    public ContentProviderHolder getContentProviderExternal(
8918            String name, int userId, IBinder token) {
8919        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8920            "Do not have permission in call getContentProviderExternal()");
8921        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8922                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8923        return getContentProviderExternalUnchecked(name, token, userId);
8924    }
8925
8926    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8927            IBinder token, int userId) {
8928        return getContentProviderImpl(null, name, token, true, userId);
8929    }
8930
8931    /**
8932     * Drop a content provider from a ProcessRecord's bookkeeping
8933     */
8934    public void removeContentProvider(IBinder connection, boolean stable) {
8935        enforceNotIsolatedCaller("removeContentProvider");
8936        long ident = Binder.clearCallingIdentity();
8937        try {
8938            synchronized (this) {
8939                ContentProviderConnection conn;
8940                try {
8941                    conn = (ContentProviderConnection)connection;
8942                } catch (ClassCastException e) {
8943                    String msg ="removeContentProvider: " + connection
8944                            + " not a ContentProviderConnection";
8945                    Slog.w(TAG, msg);
8946                    throw new IllegalArgumentException(msg);
8947                }
8948                if (conn == null) {
8949                    throw new NullPointerException("connection is null");
8950                }
8951                if (decProviderCountLocked(conn, null, null, stable)) {
8952                    updateOomAdjLocked();
8953                }
8954            }
8955        } finally {
8956            Binder.restoreCallingIdentity(ident);
8957        }
8958    }
8959
8960    public void removeContentProviderExternal(String name, IBinder token) {
8961        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8962            "Do not have permission in call removeContentProviderExternal()");
8963        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8964    }
8965
8966    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8967        synchronized (this) {
8968            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8969            if(cpr == null) {
8970                //remove from mProvidersByClass
8971                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8972                return;
8973            }
8974
8975            //update content provider record entry info
8976            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8977            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8978            if (localCpr.hasExternalProcessHandles()) {
8979                if (localCpr.removeExternalProcessHandleLocked(token)) {
8980                    updateOomAdjLocked();
8981                } else {
8982                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8983                            + " with no external reference for token: "
8984                            + token + ".");
8985                }
8986            } else {
8987                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8988                        + " with no external references.");
8989            }
8990        }
8991    }
8992
8993    public final void publishContentProviders(IApplicationThread caller,
8994            List<ContentProviderHolder> providers) {
8995        if (providers == null) {
8996            return;
8997        }
8998
8999        enforceNotIsolatedCaller("publishContentProviders");
9000        synchronized (this) {
9001            final ProcessRecord r = getRecordForAppLocked(caller);
9002            if (DEBUG_MU)
9003                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9004            if (r == null) {
9005                throw new SecurityException(
9006                        "Unable to find app for caller " + caller
9007                      + " (pid=" + Binder.getCallingPid()
9008                      + ") when publishing content providers");
9009            }
9010
9011            final long origId = Binder.clearCallingIdentity();
9012
9013            final int N = providers.size();
9014            for (int i=0; i<N; i++) {
9015                ContentProviderHolder src = providers.get(i);
9016                if (src == null || src.info == null || src.provider == null) {
9017                    continue;
9018                }
9019                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9020                if (DEBUG_MU)
9021                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9022                if (dst != null) {
9023                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9024                    mProviderMap.putProviderByClass(comp, dst);
9025                    String names[] = dst.info.authority.split(";");
9026                    for (int j = 0; j < names.length; j++) {
9027                        mProviderMap.putProviderByName(names[j], dst);
9028                    }
9029
9030                    int NL = mLaunchingProviders.size();
9031                    int j;
9032                    for (j=0; j<NL; j++) {
9033                        if (mLaunchingProviders.get(j) == dst) {
9034                            mLaunchingProviders.remove(j);
9035                            j--;
9036                            NL--;
9037                        }
9038                    }
9039                    synchronized (dst) {
9040                        dst.provider = src.provider;
9041                        dst.proc = r;
9042                        dst.notifyAll();
9043                    }
9044                    updateOomAdjLocked(r);
9045                }
9046            }
9047
9048            Binder.restoreCallingIdentity(origId);
9049        }
9050    }
9051
9052    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9053        ContentProviderConnection conn;
9054        try {
9055            conn = (ContentProviderConnection)connection;
9056        } catch (ClassCastException e) {
9057            String msg ="refContentProvider: " + connection
9058                    + " not a ContentProviderConnection";
9059            Slog.w(TAG, msg);
9060            throw new IllegalArgumentException(msg);
9061        }
9062        if (conn == null) {
9063            throw new NullPointerException("connection is null");
9064        }
9065
9066        synchronized (this) {
9067            if (stable > 0) {
9068                conn.numStableIncs += stable;
9069            }
9070            stable = conn.stableCount + stable;
9071            if (stable < 0) {
9072                throw new IllegalStateException("stableCount < 0: " + stable);
9073            }
9074
9075            if (unstable > 0) {
9076                conn.numUnstableIncs += unstable;
9077            }
9078            unstable = conn.unstableCount + unstable;
9079            if (unstable < 0) {
9080                throw new IllegalStateException("unstableCount < 0: " + unstable);
9081            }
9082
9083            if ((stable+unstable) <= 0) {
9084                throw new IllegalStateException("ref counts can't go to zero here: stable="
9085                        + stable + " unstable=" + unstable);
9086            }
9087            conn.stableCount = stable;
9088            conn.unstableCount = unstable;
9089            return !conn.dead;
9090        }
9091    }
9092
9093    public void unstableProviderDied(IBinder connection) {
9094        ContentProviderConnection conn;
9095        try {
9096            conn = (ContentProviderConnection)connection;
9097        } catch (ClassCastException e) {
9098            String msg ="refContentProvider: " + connection
9099                    + " not a ContentProviderConnection";
9100            Slog.w(TAG, msg);
9101            throw new IllegalArgumentException(msg);
9102        }
9103        if (conn == null) {
9104            throw new NullPointerException("connection is null");
9105        }
9106
9107        // Safely retrieve the content provider associated with the connection.
9108        IContentProvider provider;
9109        synchronized (this) {
9110            provider = conn.provider.provider;
9111        }
9112
9113        if (provider == null) {
9114            // Um, yeah, we're way ahead of you.
9115            return;
9116        }
9117
9118        // Make sure the caller is being honest with us.
9119        if (provider.asBinder().pingBinder()) {
9120            // Er, no, still looks good to us.
9121            synchronized (this) {
9122                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9123                        + " says " + conn + " died, but we don't agree");
9124                return;
9125            }
9126        }
9127
9128        // Well look at that!  It's dead!
9129        synchronized (this) {
9130            if (conn.provider.provider != provider) {
9131                // But something changed...  good enough.
9132                return;
9133            }
9134
9135            ProcessRecord proc = conn.provider.proc;
9136            if (proc == null || proc.thread == null) {
9137                // Seems like the process is already cleaned up.
9138                return;
9139            }
9140
9141            // As far as we're concerned, this is just like receiving a
9142            // death notification...  just a bit prematurely.
9143            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9144                    + ") early provider death");
9145            final long ident = Binder.clearCallingIdentity();
9146            try {
9147                appDiedLocked(proc);
9148            } finally {
9149                Binder.restoreCallingIdentity(ident);
9150            }
9151        }
9152    }
9153
9154    @Override
9155    public void appNotRespondingViaProvider(IBinder connection) {
9156        enforceCallingPermission(
9157                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9158
9159        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9160        if (conn == null) {
9161            Slog.w(TAG, "ContentProviderConnection is null");
9162            return;
9163        }
9164
9165        final ProcessRecord host = conn.provider.proc;
9166        if (host == null) {
9167            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9168            return;
9169        }
9170
9171        final long token = Binder.clearCallingIdentity();
9172        try {
9173            appNotResponding(host, null, null, false, "ContentProvider not responding");
9174        } finally {
9175            Binder.restoreCallingIdentity(token);
9176        }
9177    }
9178
9179    public final void installSystemProviders() {
9180        List<ProviderInfo> providers;
9181        synchronized (this) {
9182            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9183            providers = generateApplicationProvidersLocked(app);
9184            if (providers != null) {
9185                for (int i=providers.size()-1; i>=0; i--) {
9186                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9187                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9188                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9189                                + ": not system .apk");
9190                        providers.remove(i);
9191                    }
9192                }
9193            }
9194        }
9195        if (providers != null) {
9196            mSystemThread.installSystemProviders(providers);
9197        }
9198
9199        mCoreSettingsObserver = new CoreSettingsObserver(this);
9200
9201        //mUsageStatsService.monitorPackages();
9202    }
9203
9204    /**
9205     * Allows apps to retrieve the MIME type of a URI.
9206     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9207     * users, then it does not need permission to access the ContentProvider.
9208     * Either, it needs cross-user uri grants.
9209     *
9210     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9211     *
9212     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9213     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9214     */
9215    public String getProviderMimeType(Uri uri, int userId) {
9216        enforceNotIsolatedCaller("getProviderMimeType");
9217        final String name = uri.getAuthority();
9218        int callingUid = Binder.getCallingUid();
9219        int callingPid = Binder.getCallingPid();
9220        long ident = 0;
9221        boolean clearedIdentity = false;
9222        userId = unsafeConvertIncomingUser(userId);
9223        if (UserHandle.getUserId(callingUid) != userId) {
9224            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9225                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9226                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9227                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9228                clearedIdentity = true;
9229                ident = Binder.clearCallingIdentity();
9230            }
9231        }
9232        ContentProviderHolder holder = null;
9233        try {
9234            holder = getContentProviderExternalUnchecked(name, null, userId);
9235            if (holder != null) {
9236                return holder.provider.getType(uri);
9237            }
9238        } catch (RemoteException e) {
9239            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9240            return null;
9241        } finally {
9242            // We need to clear the identity to call removeContentProviderExternalUnchecked
9243            if (!clearedIdentity) {
9244                ident = Binder.clearCallingIdentity();
9245            }
9246            try {
9247                if (holder != null) {
9248                    removeContentProviderExternalUnchecked(name, null, userId);
9249                }
9250            } finally {
9251                Binder.restoreCallingIdentity(ident);
9252            }
9253        }
9254
9255        return null;
9256    }
9257
9258    // =========================================================
9259    // GLOBAL MANAGEMENT
9260    // =========================================================
9261
9262    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9263            boolean isolated, int isolatedUid) {
9264        String proc = customProcess != null ? customProcess : info.processName;
9265        BatteryStatsImpl.Uid.Proc ps = null;
9266        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9267        int uid = info.uid;
9268        if (isolated) {
9269            if (isolatedUid == 0) {
9270                int userId = UserHandle.getUserId(uid);
9271                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9272                while (true) {
9273                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9274                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9275                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9276                    }
9277                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9278                    mNextIsolatedProcessUid++;
9279                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9280                        // No process for this uid, use it.
9281                        break;
9282                    }
9283                    stepsLeft--;
9284                    if (stepsLeft <= 0) {
9285                        return null;
9286                    }
9287                }
9288            } else {
9289                // Special case for startIsolatedProcess (internal only), where
9290                // the uid of the isolated process is specified by the caller.
9291                uid = isolatedUid;
9292            }
9293        }
9294        return new ProcessRecord(stats, info, proc, uid);
9295    }
9296
9297    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9298            String abiOverride) {
9299        ProcessRecord app;
9300        if (!isolated) {
9301            app = getProcessRecordLocked(info.processName, info.uid, true);
9302        } else {
9303            app = null;
9304        }
9305
9306        if (app == null) {
9307            app = newProcessRecordLocked(info, null, isolated, 0);
9308            mProcessNames.put(info.processName, app.uid, app);
9309            if (isolated) {
9310                mIsolatedProcesses.put(app.uid, app);
9311            }
9312            updateLruProcessLocked(app, false, null);
9313            updateOomAdjLocked();
9314        }
9315
9316        // This package really, really can not be stopped.
9317        try {
9318            AppGlobals.getPackageManager().setPackageStoppedState(
9319                    info.packageName, false, UserHandle.getUserId(app.uid));
9320        } catch (RemoteException e) {
9321        } catch (IllegalArgumentException e) {
9322            Slog.w(TAG, "Failed trying to unstop package "
9323                    + info.packageName + ": " + e);
9324        }
9325
9326        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9327                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9328            app.persistent = true;
9329            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9330        }
9331        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9332            mPersistentStartingProcesses.add(app);
9333            startProcessLocked(app, "added application", app.processName, abiOverride,
9334                    null /* entryPoint */, null /* entryPointArgs */);
9335        }
9336
9337        return app;
9338    }
9339
9340    public void unhandledBack() {
9341        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9342                "unhandledBack()");
9343
9344        synchronized(this) {
9345            final long origId = Binder.clearCallingIdentity();
9346            try {
9347                getFocusedStack().unhandledBackLocked();
9348            } finally {
9349                Binder.restoreCallingIdentity(origId);
9350            }
9351        }
9352    }
9353
9354    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9355        enforceNotIsolatedCaller("openContentUri");
9356        final int userId = UserHandle.getCallingUserId();
9357        String name = uri.getAuthority();
9358        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9359        ParcelFileDescriptor pfd = null;
9360        if (cph != null) {
9361            // We record the binder invoker's uid in thread-local storage before
9362            // going to the content provider to open the file.  Later, in the code
9363            // that handles all permissions checks, we look for this uid and use
9364            // that rather than the Activity Manager's own uid.  The effect is that
9365            // we do the check against the caller's permissions even though it looks
9366            // to the content provider like the Activity Manager itself is making
9367            // the request.
9368            sCallerIdentity.set(new Identity(
9369                    Binder.getCallingPid(), Binder.getCallingUid()));
9370            try {
9371                pfd = cph.provider.openFile(null, uri, "r", null);
9372            } catch (FileNotFoundException e) {
9373                // do nothing; pfd will be returned null
9374            } finally {
9375                // Ensure that whatever happens, we clean up the identity state
9376                sCallerIdentity.remove();
9377            }
9378
9379            // We've got the fd now, so we're done with the provider.
9380            removeContentProviderExternalUnchecked(name, null, userId);
9381        } else {
9382            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9383        }
9384        return pfd;
9385    }
9386
9387    // Actually is sleeping or shutting down or whatever else in the future
9388    // is an inactive state.
9389    public boolean isSleepingOrShuttingDown() {
9390        return mSleeping || mShuttingDown;
9391    }
9392
9393    public boolean isSleeping() {
9394        return mSleeping;
9395    }
9396
9397    void goingToSleep() {
9398        synchronized(this) {
9399            mWentToSleep = true;
9400            updateEventDispatchingLocked();
9401            goToSleepIfNeededLocked();
9402        }
9403    }
9404
9405    void finishRunningVoiceLocked() {
9406        if (mRunningVoice) {
9407            mRunningVoice = false;
9408            goToSleepIfNeededLocked();
9409        }
9410    }
9411
9412    void goToSleepIfNeededLocked() {
9413        if (mWentToSleep && !mRunningVoice) {
9414            if (!mSleeping) {
9415                mSleeping = true;
9416                mStackSupervisor.goingToSleepLocked();
9417
9418                // Initialize the wake times of all processes.
9419                checkExcessivePowerUsageLocked(false);
9420                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9421                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9422                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9423            }
9424        }
9425    }
9426
9427    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9428        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9429            // Never persist the home stack.
9430            return;
9431        }
9432        mTaskPersister.wakeup(task, flush);
9433    }
9434
9435    @Override
9436    public boolean shutdown(int timeout) {
9437        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9438                != PackageManager.PERMISSION_GRANTED) {
9439            throw new SecurityException("Requires permission "
9440                    + android.Manifest.permission.SHUTDOWN);
9441        }
9442
9443        boolean timedout = false;
9444
9445        synchronized(this) {
9446            mShuttingDown = true;
9447            updateEventDispatchingLocked();
9448            timedout = mStackSupervisor.shutdownLocked(timeout);
9449        }
9450
9451        mAppOpsService.shutdown();
9452        if (mUsageStatsService != null) {
9453            mUsageStatsService.prepareShutdown();
9454        }
9455        mBatteryStatsService.shutdown();
9456        synchronized (this) {
9457            mProcessStats.shutdownLocked();
9458        }
9459        notifyTaskPersisterLocked(null, true);
9460
9461        return timedout;
9462    }
9463
9464    public final void activitySlept(IBinder token) {
9465        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9466
9467        final long origId = Binder.clearCallingIdentity();
9468
9469        synchronized (this) {
9470            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9471            if (r != null) {
9472                mStackSupervisor.activitySleptLocked(r);
9473            }
9474        }
9475
9476        Binder.restoreCallingIdentity(origId);
9477    }
9478
9479    void logLockScreen(String msg) {
9480        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9481                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9482                mWentToSleep + " mSleeping=" + mSleeping);
9483    }
9484
9485    private void comeOutOfSleepIfNeededLocked() {
9486        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9487            if (mSleeping) {
9488                mSleeping = false;
9489                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9490            }
9491        }
9492    }
9493
9494    void wakingUp() {
9495        synchronized(this) {
9496            mWentToSleep = false;
9497            updateEventDispatchingLocked();
9498            comeOutOfSleepIfNeededLocked();
9499        }
9500    }
9501
9502    void startRunningVoiceLocked() {
9503        if (!mRunningVoice) {
9504            mRunningVoice = true;
9505            comeOutOfSleepIfNeededLocked();
9506        }
9507    }
9508
9509    private void updateEventDispatchingLocked() {
9510        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9511    }
9512
9513    public void setLockScreenShown(boolean shown) {
9514        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9515                != PackageManager.PERMISSION_GRANTED) {
9516            throw new SecurityException("Requires permission "
9517                    + android.Manifest.permission.DEVICE_POWER);
9518        }
9519
9520        synchronized(this) {
9521            long ident = Binder.clearCallingIdentity();
9522            try {
9523                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9524                mLockScreenShown = shown;
9525                comeOutOfSleepIfNeededLocked();
9526            } finally {
9527                Binder.restoreCallingIdentity(ident);
9528            }
9529        }
9530    }
9531
9532    @Override
9533    public void stopAppSwitches() {
9534        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9535                != PackageManager.PERMISSION_GRANTED) {
9536            throw new SecurityException("Requires permission "
9537                    + android.Manifest.permission.STOP_APP_SWITCHES);
9538        }
9539
9540        synchronized(this) {
9541            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9542                    + APP_SWITCH_DELAY_TIME;
9543            mDidAppSwitch = false;
9544            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9545            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9546            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9547        }
9548    }
9549
9550    public void resumeAppSwitches() {
9551        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9552                != PackageManager.PERMISSION_GRANTED) {
9553            throw new SecurityException("Requires permission "
9554                    + android.Manifest.permission.STOP_APP_SWITCHES);
9555        }
9556
9557        synchronized(this) {
9558            // Note that we don't execute any pending app switches... we will
9559            // let those wait until either the timeout, or the next start
9560            // activity request.
9561            mAppSwitchesAllowedTime = 0;
9562        }
9563    }
9564
9565    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9566            String name) {
9567        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9568            return true;
9569        }
9570
9571        final int perm = checkComponentPermission(
9572                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9573                callingUid, -1, true);
9574        if (perm == PackageManager.PERMISSION_GRANTED) {
9575            return true;
9576        }
9577
9578        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9579        return false;
9580    }
9581
9582    public void setDebugApp(String packageName, boolean waitForDebugger,
9583            boolean persistent) {
9584        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9585                "setDebugApp()");
9586
9587        long ident = Binder.clearCallingIdentity();
9588        try {
9589            // Note that this is not really thread safe if there are multiple
9590            // callers into it at the same time, but that's not a situation we
9591            // care about.
9592            if (persistent) {
9593                final ContentResolver resolver = mContext.getContentResolver();
9594                Settings.Global.putString(
9595                    resolver, Settings.Global.DEBUG_APP,
9596                    packageName);
9597                Settings.Global.putInt(
9598                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9599                    waitForDebugger ? 1 : 0);
9600            }
9601
9602            synchronized (this) {
9603                if (!persistent) {
9604                    mOrigDebugApp = mDebugApp;
9605                    mOrigWaitForDebugger = mWaitForDebugger;
9606                }
9607                mDebugApp = packageName;
9608                mWaitForDebugger = waitForDebugger;
9609                mDebugTransient = !persistent;
9610                if (packageName != null) {
9611                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9612                            false, UserHandle.USER_ALL, "set debug app");
9613                }
9614            }
9615        } finally {
9616            Binder.restoreCallingIdentity(ident);
9617        }
9618    }
9619
9620    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9621        synchronized (this) {
9622            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9623            if (!isDebuggable) {
9624                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9625                    throw new SecurityException("Process not debuggable: " + app.packageName);
9626                }
9627            }
9628
9629            mOpenGlTraceApp = processName;
9630        }
9631    }
9632
9633    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9634            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9635        synchronized (this) {
9636            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9637            if (!isDebuggable) {
9638                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9639                    throw new SecurityException("Process not debuggable: " + app.packageName);
9640                }
9641            }
9642            mProfileApp = processName;
9643            mProfileFile = profileFile;
9644            if (mProfileFd != null) {
9645                try {
9646                    mProfileFd.close();
9647                } catch (IOException e) {
9648                }
9649                mProfileFd = null;
9650            }
9651            mProfileFd = profileFd;
9652            mProfileType = 0;
9653            mAutoStopProfiler = autoStopProfiler;
9654        }
9655    }
9656
9657    @Override
9658    public void setAlwaysFinish(boolean enabled) {
9659        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9660                "setAlwaysFinish()");
9661
9662        Settings.Global.putInt(
9663                mContext.getContentResolver(),
9664                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9665
9666        synchronized (this) {
9667            mAlwaysFinishActivities = enabled;
9668        }
9669    }
9670
9671    @Override
9672    public void setActivityController(IActivityController controller) {
9673        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9674                "setActivityController()");
9675        synchronized (this) {
9676            mController = controller;
9677            Watchdog.getInstance().setActivityController(controller);
9678        }
9679    }
9680
9681    @Override
9682    public void setUserIsMonkey(boolean userIsMonkey) {
9683        synchronized (this) {
9684            synchronized (mPidsSelfLocked) {
9685                final int callingPid = Binder.getCallingPid();
9686                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9687                if (precessRecord == null) {
9688                    throw new SecurityException("Unknown process: " + callingPid);
9689                }
9690                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9691                    throw new SecurityException("Only an instrumentation process "
9692                            + "with a UiAutomation can call setUserIsMonkey");
9693                }
9694            }
9695            mUserIsMonkey = userIsMonkey;
9696        }
9697    }
9698
9699    @Override
9700    public boolean isUserAMonkey() {
9701        synchronized (this) {
9702            // If there is a controller also implies the user is a monkey.
9703            return (mUserIsMonkey || mController != null);
9704        }
9705    }
9706
9707    public void requestBugReport() {
9708        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9709        SystemProperties.set("ctl.start", "bugreport");
9710    }
9711
9712    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9713        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9714    }
9715
9716    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9717        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9718            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9719        }
9720        return KEY_DISPATCHING_TIMEOUT;
9721    }
9722
9723    @Override
9724    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9725        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9726                != PackageManager.PERMISSION_GRANTED) {
9727            throw new SecurityException("Requires permission "
9728                    + android.Manifest.permission.FILTER_EVENTS);
9729        }
9730        ProcessRecord proc;
9731        long timeout;
9732        synchronized (this) {
9733            synchronized (mPidsSelfLocked) {
9734                proc = mPidsSelfLocked.get(pid);
9735            }
9736            timeout = getInputDispatchingTimeoutLocked(proc);
9737        }
9738
9739        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9740            return -1;
9741        }
9742
9743        return timeout;
9744    }
9745
9746    /**
9747     * Handle input dispatching timeouts.
9748     * Returns whether input dispatching should be aborted or not.
9749     */
9750    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9751            final ActivityRecord activity, final ActivityRecord parent,
9752            final boolean aboveSystem, String reason) {
9753        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9754                != PackageManager.PERMISSION_GRANTED) {
9755            throw new SecurityException("Requires permission "
9756                    + android.Manifest.permission.FILTER_EVENTS);
9757        }
9758
9759        final String annotation;
9760        if (reason == null) {
9761            annotation = "Input dispatching timed out";
9762        } else {
9763            annotation = "Input dispatching timed out (" + reason + ")";
9764        }
9765
9766        if (proc != null) {
9767            synchronized (this) {
9768                if (proc.debugging) {
9769                    return false;
9770                }
9771
9772                if (mDidDexOpt) {
9773                    // Give more time since we were dexopting.
9774                    mDidDexOpt = false;
9775                    return false;
9776                }
9777
9778                if (proc.instrumentationClass != null) {
9779                    Bundle info = new Bundle();
9780                    info.putString("shortMsg", "keyDispatchingTimedOut");
9781                    info.putString("longMsg", annotation);
9782                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9783                    return true;
9784                }
9785            }
9786            mHandler.post(new Runnable() {
9787                @Override
9788                public void run() {
9789                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9790                }
9791            });
9792        }
9793
9794        return true;
9795    }
9796
9797    public Bundle getAssistContextExtras(int requestType) {
9798        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9799                "getAssistContextExtras()");
9800        PendingAssistExtras pae;
9801        Bundle extras = new Bundle();
9802        synchronized (this) {
9803            ActivityRecord activity = getFocusedStack().mResumedActivity;
9804            if (activity == null) {
9805                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9806                return null;
9807            }
9808            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9809            if (activity.app == null || activity.app.thread == null) {
9810                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9811                return extras;
9812            }
9813            if (activity.app.pid == Binder.getCallingPid()) {
9814                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9815                return extras;
9816            }
9817            pae = new PendingAssistExtras(activity);
9818            try {
9819                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9820                        requestType);
9821                mPendingAssistExtras.add(pae);
9822                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9823            } catch (RemoteException e) {
9824                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9825                return extras;
9826            }
9827        }
9828        synchronized (pae) {
9829            while (!pae.haveResult) {
9830                try {
9831                    pae.wait();
9832                } catch (InterruptedException e) {
9833                }
9834            }
9835            if (pae.result != null) {
9836                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9837            }
9838        }
9839        synchronized (this) {
9840            mPendingAssistExtras.remove(pae);
9841            mHandler.removeCallbacks(pae);
9842        }
9843        return extras;
9844    }
9845
9846    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9847        PendingAssistExtras pae = (PendingAssistExtras)token;
9848        synchronized (pae) {
9849            pae.result = extras;
9850            pae.haveResult = true;
9851            pae.notifyAll();
9852        }
9853    }
9854
9855    public void registerProcessObserver(IProcessObserver observer) {
9856        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9857                "registerProcessObserver()");
9858        synchronized (this) {
9859            mProcessObservers.register(observer);
9860        }
9861    }
9862
9863    @Override
9864    public void unregisterProcessObserver(IProcessObserver observer) {
9865        synchronized (this) {
9866            mProcessObservers.unregister(observer);
9867        }
9868    }
9869
9870    @Override
9871    public boolean convertFromTranslucent(IBinder token) {
9872        final long origId = Binder.clearCallingIdentity();
9873        try {
9874            synchronized (this) {
9875                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9876                if (r == null) {
9877                    return false;
9878                }
9879                if (r.changeWindowTranslucency(true)) {
9880                    mWindowManager.setAppFullscreen(token, true);
9881                    r.task.stack.releaseBackgroundResources();
9882                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9883                    return true;
9884                }
9885                return false;
9886            }
9887        } finally {
9888            Binder.restoreCallingIdentity(origId);
9889        }
9890    }
9891
9892    @Override
9893    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9894        final long origId = Binder.clearCallingIdentity();
9895        try {
9896            synchronized (this) {
9897                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9898                if (r == null) {
9899                    return false;
9900                }
9901                int index = r.task.mActivities.lastIndexOf(r);
9902                if (index > 0) {
9903                    ActivityRecord under = r.task.mActivities.get(index - 1);
9904                    under.returningOptions = options;
9905                }
9906                if (r.changeWindowTranslucency(false)) {
9907                    r.task.stack.convertToTranslucent(r);
9908                    mWindowManager.setAppFullscreen(token, false);
9909                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9910                    return true;
9911                } else {
9912                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9913                    return false;
9914                }
9915            }
9916        } finally {
9917            Binder.restoreCallingIdentity(origId);
9918        }
9919    }
9920
9921    @Override
9922    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9923        final long origId = Binder.clearCallingIdentity();
9924        try {
9925            synchronized (this) {
9926                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9927                if (r != null) {
9928                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9929                }
9930            }
9931            return false;
9932        } finally {
9933            Binder.restoreCallingIdentity(origId);
9934        }
9935    }
9936
9937    @Override
9938    public boolean isBackgroundVisibleBehind(IBinder token) {
9939        final long origId = Binder.clearCallingIdentity();
9940        try {
9941            synchronized (this) {
9942                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9943                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
9944                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
9945                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
9946                return visible;
9947            }
9948        } finally {
9949            Binder.restoreCallingIdentity(origId);
9950        }
9951    }
9952
9953    @Override
9954    public ActivityOptions getActivityOptions(IBinder token) {
9955        final long origId = Binder.clearCallingIdentity();
9956        try {
9957            synchronized (this) {
9958                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9959                if (r != null) {
9960                    final ActivityOptions activityOptions = r.pendingOptions;
9961                    r.pendingOptions = null;
9962                    return activityOptions;
9963                }
9964                return null;
9965            }
9966        } finally {
9967            Binder.restoreCallingIdentity(origId);
9968        }
9969    }
9970
9971    @Override
9972    public void setImmersive(IBinder token, boolean immersive) {
9973        synchronized(this) {
9974            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9975            if (r == null) {
9976                throw new IllegalArgumentException();
9977            }
9978            r.immersive = immersive;
9979
9980            // update associated state if we're frontmost
9981            if (r == mFocusedActivity) {
9982                if (DEBUG_IMMERSIVE) {
9983                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9984                }
9985                applyUpdateLockStateLocked(r);
9986            }
9987        }
9988    }
9989
9990    @Override
9991    public boolean isImmersive(IBinder token) {
9992        synchronized (this) {
9993            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9994            if (r == null) {
9995                throw new IllegalArgumentException();
9996            }
9997            return r.immersive;
9998        }
9999    }
10000
10001    public boolean isTopActivityImmersive() {
10002        enforceNotIsolatedCaller("startActivity");
10003        synchronized (this) {
10004            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10005            return (r != null) ? r.immersive : false;
10006        }
10007    }
10008
10009    @Override
10010    public boolean isTopOfTask(IBinder token) {
10011        synchronized (this) {
10012            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10013            if (r == null) {
10014                throw new IllegalArgumentException();
10015            }
10016            return r.task.getTopActivity() == r;
10017        }
10018    }
10019
10020    public final void enterSafeMode() {
10021        synchronized(this) {
10022            // It only makes sense to do this before the system is ready
10023            // and started launching other packages.
10024            if (!mSystemReady) {
10025                try {
10026                    AppGlobals.getPackageManager().enterSafeMode();
10027                } catch (RemoteException e) {
10028                }
10029            }
10030
10031            mSafeMode = true;
10032        }
10033    }
10034
10035    public final void showSafeModeOverlay() {
10036        View v = LayoutInflater.from(mContext).inflate(
10037                com.android.internal.R.layout.safe_mode, null);
10038        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10039        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10040        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10041        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10042        lp.gravity = Gravity.BOTTOM | Gravity.START;
10043        lp.format = v.getBackground().getOpacity();
10044        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10045                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10046        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10047        ((WindowManager)mContext.getSystemService(
10048                Context.WINDOW_SERVICE)).addView(v, lp);
10049    }
10050
10051    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10052        if (!(sender instanceof PendingIntentRecord)) {
10053            return;
10054        }
10055        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10056        synchronized (stats) {
10057            if (mBatteryStatsService.isOnBattery()) {
10058                mBatteryStatsService.enforceCallingPermission();
10059                PendingIntentRecord rec = (PendingIntentRecord)sender;
10060                int MY_UID = Binder.getCallingUid();
10061                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10062                BatteryStatsImpl.Uid.Pkg pkg =
10063                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10064                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10065                pkg.incWakeupsLocked();
10066            }
10067        }
10068    }
10069
10070    public boolean killPids(int[] pids, String pReason, boolean secure) {
10071        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10072            throw new SecurityException("killPids only available to the system");
10073        }
10074        String reason = (pReason == null) ? "Unknown" : pReason;
10075        // XXX Note: don't acquire main activity lock here, because the window
10076        // manager calls in with its locks held.
10077
10078        boolean killed = false;
10079        synchronized (mPidsSelfLocked) {
10080            int[] types = new int[pids.length];
10081            int worstType = 0;
10082            for (int i=0; i<pids.length; i++) {
10083                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10084                if (proc != null) {
10085                    int type = proc.setAdj;
10086                    types[i] = type;
10087                    if (type > worstType) {
10088                        worstType = type;
10089                    }
10090                }
10091            }
10092
10093            // If the worst oom_adj is somewhere in the cached proc LRU range,
10094            // then constrain it so we will kill all cached procs.
10095            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10096                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10097                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10098            }
10099
10100            // If this is not a secure call, don't let it kill processes that
10101            // are important.
10102            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10103                worstType = ProcessList.SERVICE_ADJ;
10104            }
10105
10106            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10107            for (int i=0; i<pids.length; i++) {
10108                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10109                if (proc == null) {
10110                    continue;
10111                }
10112                int adj = proc.setAdj;
10113                if (adj >= worstType && !proc.killedByAm) {
10114                    killUnneededProcessLocked(proc, reason);
10115                    killed = true;
10116                }
10117            }
10118        }
10119        return killed;
10120    }
10121
10122    @Override
10123    public void killUid(int uid, String reason) {
10124        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10125            throw new SecurityException("killUid only available to the system");
10126        }
10127        synchronized (this) {
10128            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10129                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10130                    reason != null ? reason : "kill uid");
10131        }
10132    }
10133
10134    @Override
10135    public boolean killProcessesBelowForeground(String reason) {
10136        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10137            throw new SecurityException("killProcessesBelowForeground() only available to system");
10138        }
10139
10140        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10141    }
10142
10143    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10144        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10145            throw new SecurityException("killProcessesBelowAdj() only available to system");
10146        }
10147
10148        boolean killed = false;
10149        synchronized (mPidsSelfLocked) {
10150            final int size = mPidsSelfLocked.size();
10151            for (int i = 0; i < size; i++) {
10152                final int pid = mPidsSelfLocked.keyAt(i);
10153                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10154                if (proc == null) continue;
10155
10156                final int adj = proc.setAdj;
10157                if (adj > belowAdj && !proc.killedByAm) {
10158                    killUnneededProcessLocked(proc, reason);
10159                    killed = true;
10160                }
10161            }
10162        }
10163        return killed;
10164    }
10165
10166    @Override
10167    public void hang(final IBinder who, boolean allowRestart) {
10168        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10169                != PackageManager.PERMISSION_GRANTED) {
10170            throw new SecurityException("Requires permission "
10171                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10172        }
10173
10174        final IBinder.DeathRecipient death = new DeathRecipient() {
10175            @Override
10176            public void binderDied() {
10177                synchronized (this) {
10178                    notifyAll();
10179                }
10180            }
10181        };
10182
10183        try {
10184            who.linkToDeath(death, 0);
10185        } catch (RemoteException e) {
10186            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10187            return;
10188        }
10189
10190        synchronized (this) {
10191            Watchdog.getInstance().setAllowRestart(allowRestart);
10192            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10193            synchronized (death) {
10194                while (who.isBinderAlive()) {
10195                    try {
10196                        death.wait();
10197                    } catch (InterruptedException e) {
10198                    }
10199                }
10200            }
10201            Watchdog.getInstance().setAllowRestart(true);
10202        }
10203    }
10204
10205    @Override
10206    public void restart() {
10207        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10208                != PackageManager.PERMISSION_GRANTED) {
10209            throw new SecurityException("Requires permission "
10210                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10211        }
10212
10213        Log.i(TAG, "Sending shutdown broadcast...");
10214
10215        BroadcastReceiver br = new BroadcastReceiver() {
10216            @Override public void onReceive(Context context, Intent intent) {
10217                // Now the broadcast is done, finish up the low-level shutdown.
10218                Log.i(TAG, "Shutting down activity manager...");
10219                shutdown(10000);
10220                Log.i(TAG, "Shutdown complete, restarting!");
10221                Process.killProcess(Process.myPid());
10222                System.exit(10);
10223            }
10224        };
10225
10226        // First send the high-level shut down broadcast.
10227        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10228        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10229        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10230        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10231        mContext.sendOrderedBroadcastAsUser(intent,
10232                UserHandle.ALL, null, br, mHandler, 0, null, null);
10233        */
10234        br.onReceive(mContext, intent);
10235    }
10236
10237    private long getLowRamTimeSinceIdle(long now) {
10238        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10239    }
10240
10241    @Override
10242    public void performIdleMaintenance() {
10243        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10244                != PackageManager.PERMISSION_GRANTED) {
10245            throw new SecurityException("Requires permission "
10246                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10247        }
10248
10249        synchronized (this) {
10250            final long now = SystemClock.uptimeMillis();
10251            final long timeSinceLastIdle = now - mLastIdleTime;
10252            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10253            mLastIdleTime = now;
10254            mLowRamTimeSinceLastIdle = 0;
10255            if (mLowRamStartTime != 0) {
10256                mLowRamStartTime = now;
10257            }
10258
10259            StringBuilder sb = new StringBuilder(128);
10260            sb.append("Idle maintenance over ");
10261            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10262            sb.append(" low RAM for ");
10263            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10264            Slog.i(TAG, sb.toString());
10265
10266            // If at least 1/3 of our time since the last idle period has been spent
10267            // with RAM low, then we want to kill processes.
10268            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10269
10270            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10271                ProcessRecord proc = mLruProcesses.get(i);
10272                if (proc.notCachedSinceIdle) {
10273                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10274                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10275                        if (doKilling && proc.initialIdlePss != 0
10276                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10277                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10278                                    + " from " + proc.initialIdlePss + ")");
10279                        }
10280                    }
10281                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10282                    proc.notCachedSinceIdle = true;
10283                    proc.initialIdlePss = 0;
10284                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10285                            isSleeping(), now);
10286                }
10287            }
10288
10289            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10290            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10291        }
10292    }
10293
10294    private void retrieveSettings() {
10295        final ContentResolver resolver = mContext.getContentResolver();
10296        String debugApp = Settings.Global.getString(
10297            resolver, Settings.Global.DEBUG_APP);
10298        boolean waitForDebugger = Settings.Global.getInt(
10299            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10300        boolean alwaysFinishActivities = Settings.Global.getInt(
10301            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10302        boolean forceRtl = Settings.Global.getInt(
10303                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10304        // Transfer any global setting for forcing RTL layout, into a System Property
10305        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10306
10307        Configuration configuration = new Configuration();
10308        Settings.System.getConfiguration(resolver, configuration);
10309        if (forceRtl) {
10310            // This will take care of setting the correct layout direction flags
10311            configuration.setLayoutDirection(configuration.locale);
10312        }
10313
10314        synchronized (this) {
10315            mDebugApp = mOrigDebugApp = debugApp;
10316            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10317            mAlwaysFinishActivities = alwaysFinishActivities;
10318            // This happens before any activities are started, so we can
10319            // change mConfiguration in-place.
10320            updateConfigurationLocked(configuration, null, false, true);
10321            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10322        }
10323    }
10324
10325    public boolean testIsSystemReady() {
10326        // no need to synchronize(this) just to read & return the value
10327        return mSystemReady;
10328    }
10329
10330    private static File getCalledPreBootReceiversFile() {
10331        File dataDir = Environment.getDataDirectory();
10332        File systemDir = new File(dataDir, "system");
10333        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10334        return fname;
10335    }
10336
10337    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10338        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10339        File file = getCalledPreBootReceiversFile();
10340        FileInputStream fis = null;
10341        try {
10342            fis = new FileInputStream(file);
10343            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10344            int fvers = dis.readInt();
10345            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10346                String vers = dis.readUTF();
10347                String codename = dis.readUTF();
10348                String build = dis.readUTF();
10349                if (android.os.Build.VERSION.RELEASE.equals(vers)
10350                        && android.os.Build.VERSION.CODENAME.equals(codename)
10351                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10352                    int num = dis.readInt();
10353                    while (num > 0) {
10354                        num--;
10355                        String pkg = dis.readUTF();
10356                        String cls = dis.readUTF();
10357                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10358                    }
10359                }
10360            }
10361        } catch (FileNotFoundException e) {
10362        } catch (IOException e) {
10363            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10364        } finally {
10365            if (fis != null) {
10366                try {
10367                    fis.close();
10368                } catch (IOException e) {
10369                }
10370            }
10371        }
10372        return lastDoneReceivers;
10373    }
10374
10375    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10376        File file = getCalledPreBootReceiversFile();
10377        FileOutputStream fos = null;
10378        DataOutputStream dos = null;
10379        try {
10380            fos = new FileOutputStream(file);
10381            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10382            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10383            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10384            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10385            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10386            dos.writeInt(list.size());
10387            for (int i=0; i<list.size(); i++) {
10388                dos.writeUTF(list.get(i).getPackageName());
10389                dos.writeUTF(list.get(i).getClassName());
10390            }
10391        } catch (IOException e) {
10392            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10393            file.delete();
10394        } finally {
10395            FileUtils.sync(fos);
10396            if (dos != null) {
10397                try {
10398                    dos.close();
10399                } catch (IOException e) {
10400                    // TODO Auto-generated catch block
10401                    e.printStackTrace();
10402                }
10403            }
10404        }
10405    }
10406
10407    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10408            ArrayList<ComponentName> doneReceivers, int userId) {
10409        boolean waitingUpdate = false;
10410        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10411        List<ResolveInfo> ris = null;
10412        try {
10413            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10414                    intent, null, 0, userId);
10415        } catch (RemoteException e) {
10416        }
10417        if (ris != null) {
10418            for (int i=ris.size()-1; i>=0; i--) {
10419                if ((ris.get(i).activityInfo.applicationInfo.flags
10420                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10421                    ris.remove(i);
10422                }
10423            }
10424            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10425
10426            // For User 0, load the version number. When delivering to a new user, deliver
10427            // to all receivers.
10428            if (userId == UserHandle.USER_OWNER) {
10429                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10430                for (int i=0; i<ris.size(); i++) {
10431                    ActivityInfo ai = ris.get(i).activityInfo;
10432                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10433                    if (lastDoneReceivers.contains(comp)) {
10434                        // We already did the pre boot receiver for this app with the current
10435                        // platform version, so don't do it again...
10436                        ris.remove(i);
10437                        i--;
10438                        // ...however, do keep it as one that has been done, so we don't
10439                        // forget about it when rewriting the file of last done receivers.
10440                        doneReceivers.add(comp);
10441                    }
10442                }
10443            }
10444
10445            // If primary user, send broadcast to all available users, else just to userId
10446            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10447                    : new int[] { userId };
10448            for (int i = 0; i < ris.size(); i++) {
10449                ActivityInfo ai = ris.get(i).activityInfo;
10450                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10451                doneReceivers.add(comp);
10452                intent.setComponent(comp);
10453                for (int j=0; j<users.length; j++) {
10454                    IIntentReceiver finisher = null;
10455                    // On last receiver and user, set up a completion callback
10456                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10457                        finisher = new IIntentReceiver.Stub() {
10458                            public void performReceive(Intent intent, int resultCode,
10459                                    String data, Bundle extras, boolean ordered,
10460                                    boolean sticky, int sendingUser) {
10461                                // The raw IIntentReceiver interface is called
10462                                // with the AM lock held, so redispatch to
10463                                // execute our code without the lock.
10464                                mHandler.post(onFinishCallback);
10465                            }
10466                        };
10467                    }
10468                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10469                            + " for user " + users[j]);
10470                    broadcastIntentLocked(null, null, intent, null, finisher,
10471                            0, null, null, null, AppOpsManager.OP_NONE,
10472                            true, false, MY_PID, Process.SYSTEM_UID,
10473                            users[j]);
10474                    if (finisher != null) {
10475                        waitingUpdate = true;
10476                    }
10477                }
10478            }
10479        }
10480
10481        return waitingUpdate;
10482    }
10483
10484    public void systemReady(final Runnable goingCallback) {
10485        synchronized(this) {
10486            if (mSystemReady) {
10487                // If we're done calling all the receivers, run the next "boot phase" passed in
10488                // by the SystemServer
10489                if (goingCallback != null) {
10490                    goingCallback.run();
10491                }
10492                return;
10493            }
10494
10495            // Make sure we have the current profile info, since it is needed for
10496            // security checks.
10497            updateCurrentProfileIdsLocked();
10498
10499            if (mRecentTasks == null) {
10500                mRecentTasks = mTaskPersister.restoreTasksLocked();
10501                if (!mRecentTasks.isEmpty()) {
10502                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10503                }
10504                mTaskPersister.startPersisting();
10505            }
10506
10507            // Check to see if there are any update receivers to run.
10508            if (!mDidUpdate) {
10509                if (mWaitingUpdate) {
10510                    return;
10511                }
10512                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10513                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10514                    public void run() {
10515                        synchronized (ActivityManagerService.this) {
10516                            mDidUpdate = true;
10517                        }
10518                        writeLastDonePreBootReceivers(doneReceivers);
10519                        showBootMessage(mContext.getText(
10520                                R.string.android_upgrading_complete),
10521                                false);
10522                        systemReady(goingCallback);
10523                    }
10524                }, doneReceivers, UserHandle.USER_OWNER);
10525
10526                if (mWaitingUpdate) {
10527                    return;
10528                }
10529                mDidUpdate = true;
10530            }
10531
10532            mAppOpsService.systemReady();
10533            mSystemReady = true;
10534        }
10535
10536        ArrayList<ProcessRecord> procsToKill = null;
10537        synchronized(mPidsSelfLocked) {
10538            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10539                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10540                if (!isAllowedWhileBooting(proc.info)){
10541                    if (procsToKill == null) {
10542                        procsToKill = new ArrayList<ProcessRecord>();
10543                    }
10544                    procsToKill.add(proc);
10545                }
10546            }
10547        }
10548
10549        synchronized(this) {
10550            if (procsToKill != null) {
10551                for (int i=procsToKill.size()-1; i>=0; i--) {
10552                    ProcessRecord proc = procsToKill.get(i);
10553                    Slog.i(TAG, "Removing system update proc: " + proc);
10554                    removeProcessLocked(proc, true, false, "system update done");
10555                }
10556            }
10557
10558            // Now that we have cleaned up any update processes, we
10559            // are ready to start launching real processes and know that
10560            // we won't trample on them any more.
10561            mProcessesReady = true;
10562        }
10563
10564        Slog.i(TAG, "System now ready");
10565        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10566            SystemClock.uptimeMillis());
10567
10568        synchronized(this) {
10569            // Make sure we have no pre-ready processes sitting around.
10570
10571            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10572                ResolveInfo ri = mContext.getPackageManager()
10573                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10574                                STOCK_PM_FLAGS);
10575                CharSequence errorMsg = null;
10576                if (ri != null) {
10577                    ActivityInfo ai = ri.activityInfo;
10578                    ApplicationInfo app = ai.applicationInfo;
10579                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10580                        mTopAction = Intent.ACTION_FACTORY_TEST;
10581                        mTopData = null;
10582                        mTopComponent = new ComponentName(app.packageName,
10583                                ai.name);
10584                    } else {
10585                        errorMsg = mContext.getResources().getText(
10586                                com.android.internal.R.string.factorytest_not_system);
10587                    }
10588                } else {
10589                    errorMsg = mContext.getResources().getText(
10590                            com.android.internal.R.string.factorytest_no_action);
10591                }
10592                if (errorMsg != null) {
10593                    mTopAction = null;
10594                    mTopData = null;
10595                    mTopComponent = null;
10596                    Message msg = Message.obtain();
10597                    msg.what = SHOW_FACTORY_ERROR_MSG;
10598                    msg.getData().putCharSequence("msg", errorMsg);
10599                    mHandler.sendMessage(msg);
10600                }
10601            }
10602        }
10603
10604        retrieveSettings();
10605
10606        synchronized (this) {
10607            readGrantedUriPermissionsLocked();
10608        }
10609
10610        if (goingCallback != null) goingCallback.run();
10611
10612        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10613                Integer.toString(mCurrentUserId), mCurrentUserId);
10614        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10615                Integer.toString(mCurrentUserId), mCurrentUserId);
10616        mSystemServiceManager.startUser(mCurrentUserId);
10617
10618        synchronized (this) {
10619            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10620                try {
10621                    List apps = AppGlobals.getPackageManager().
10622                        getPersistentApplications(STOCK_PM_FLAGS);
10623                    if (apps != null) {
10624                        int N = apps.size();
10625                        int i;
10626                        for (i=0; i<N; i++) {
10627                            ApplicationInfo info
10628                                = (ApplicationInfo)apps.get(i);
10629                            if (info != null &&
10630                                    !info.packageName.equals("android")) {
10631                                addAppLocked(info, false, null /* ABI override */);
10632                            }
10633                        }
10634                    }
10635                } catch (RemoteException ex) {
10636                    // pm is in same process, this will never happen.
10637                }
10638            }
10639
10640            // Start up initial activity.
10641            mBooting = true;
10642
10643            try {
10644                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10645                    Message msg = Message.obtain();
10646                    msg.what = SHOW_UID_ERROR_MSG;
10647                    mHandler.sendMessage(msg);
10648                }
10649            } catch (RemoteException e) {
10650            }
10651
10652            long ident = Binder.clearCallingIdentity();
10653            try {
10654                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10655                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10656                        | Intent.FLAG_RECEIVER_FOREGROUND);
10657                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10658                broadcastIntentLocked(null, null, intent,
10659                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10660                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10661                intent = new Intent(Intent.ACTION_USER_STARTING);
10662                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10663                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10664                broadcastIntentLocked(null, null, intent,
10665                        null, new IIntentReceiver.Stub() {
10666                            @Override
10667                            public void performReceive(Intent intent, int resultCode, String data,
10668                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10669                                    throws RemoteException {
10670                            }
10671                        }, 0, null, null,
10672                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10673                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10674            } catch (Throwable t) {
10675                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10676            } finally {
10677                Binder.restoreCallingIdentity(ident);
10678            }
10679            mStackSupervisor.resumeTopActivitiesLocked();
10680            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10681        }
10682    }
10683
10684    private boolean makeAppCrashingLocked(ProcessRecord app,
10685            String shortMsg, String longMsg, String stackTrace) {
10686        app.crashing = true;
10687        app.crashingReport = generateProcessError(app,
10688                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10689        startAppProblemLocked(app);
10690        app.stopFreezingAllLocked();
10691        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10692    }
10693
10694    private void makeAppNotRespondingLocked(ProcessRecord app,
10695            String activity, String shortMsg, String longMsg) {
10696        app.notResponding = true;
10697        app.notRespondingReport = generateProcessError(app,
10698                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10699                activity, shortMsg, longMsg, null);
10700        startAppProblemLocked(app);
10701        app.stopFreezingAllLocked();
10702    }
10703
10704    /**
10705     * Generate a process error record, suitable for attachment to a ProcessRecord.
10706     *
10707     * @param app The ProcessRecord in which the error occurred.
10708     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10709     *                      ActivityManager.AppErrorStateInfo
10710     * @param activity The activity associated with the crash, if known.
10711     * @param shortMsg Short message describing the crash.
10712     * @param longMsg Long message describing the crash.
10713     * @param stackTrace Full crash stack trace, may be null.
10714     *
10715     * @return Returns a fully-formed AppErrorStateInfo record.
10716     */
10717    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10718            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10719        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10720
10721        report.condition = condition;
10722        report.processName = app.processName;
10723        report.pid = app.pid;
10724        report.uid = app.info.uid;
10725        report.tag = activity;
10726        report.shortMsg = shortMsg;
10727        report.longMsg = longMsg;
10728        report.stackTrace = stackTrace;
10729
10730        return report;
10731    }
10732
10733    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10734        synchronized (this) {
10735            app.crashing = false;
10736            app.crashingReport = null;
10737            app.notResponding = false;
10738            app.notRespondingReport = null;
10739            if (app.anrDialog == fromDialog) {
10740                app.anrDialog = null;
10741            }
10742            if (app.waitDialog == fromDialog) {
10743                app.waitDialog = null;
10744            }
10745            if (app.pid > 0 && app.pid != MY_PID) {
10746                handleAppCrashLocked(app, null, null, null);
10747                killUnneededProcessLocked(app, "user request after error");
10748            }
10749        }
10750    }
10751
10752    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10753            String stackTrace) {
10754        long now = SystemClock.uptimeMillis();
10755
10756        Long crashTime;
10757        if (!app.isolated) {
10758            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10759        } else {
10760            crashTime = null;
10761        }
10762        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10763            // This process loses!
10764            Slog.w(TAG, "Process " + app.info.processName
10765                    + " has crashed too many times: killing!");
10766            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10767                    app.userId, app.info.processName, app.uid);
10768            mStackSupervisor.handleAppCrashLocked(app);
10769            if (!app.persistent) {
10770                // We don't want to start this process again until the user
10771                // explicitly does so...  but for persistent process, we really
10772                // need to keep it running.  If a persistent process is actually
10773                // repeatedly crashing, then badness for everyone.
10774                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10775                        app.info.processName);
10776                if (!app.isolated) {
10777                    // XXX We don't have a way to mark isolated processes
10778                    // as bad, since they don't have a peristent identity.
10779                    mBadProcesses.put(app.info.processName, app.uid,
10780                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10781                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10782                }
10783                app.bad = true;
10784                app.removed = true;
10785                // Don't let services in this process be restarted and potentially
10786                // annoy the user repeatedly.  Unless it is persistent, since those
10787                // processes run critical code.
10788                removeProcessLocked(app, false, false, "crash");
10789                mStackSupervisor.resumeTopActivitiesLocked();
10790                return false;
10791            }
10792            mStackSupervisor.resumeTopActivitiesLocked();
10793        } else {
10794            mStackSupervisor.finishTopRunningActivityLocked(app);
10795        }
10796
10797        // Bump up the crash count of any services currently running in the proc.
10798        for (int i=app.services.size()-1; i>=0; i--) {
10799            // Any services running in the application need to be placed
10800            // back in the pending list.
10801            ServiceRecord sr = app.services.valueAt(i);
10802            sr.crashCount++;
10803        }
10804
10805        // If the crashing process is what we consider to be the "home process" and it has been
10806        // replaced by a third-party app, clear the package preferred activities from packages
10807        // with a home activity running in the process to prevent a repeatedly crashing app
10808        // from blocking the user to manually clear the list.
10809        final ArrayList<ActivityRecord> activities = app.activities;
10810        if (app == mHomeProcess && activities.size() > 0
10811                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10812            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10813                final ActivityRecord r = activities.get(activityNdx);
10814                if (r.isHomeActivity()) {
10815                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10816                    try {
10817                        ActivityThread.getPackageManager()
10818                                .clearPackagePreferredActivities(r.packageName);
10819                    } catch (RemoteException c) {
10820                        // pm is in same process, this will never happen.
10821                    }
10822                }
10823            }
10824        }
10825
10826        if (!app.isolated) {
10827            // XXX Can't keep track of crash times for isolated processes,
10828            // because they don't have a perisistent identity.
10829            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10830        }
10831
10832        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10833        return true;
10834    }
10835
10836    void startAppProblemLocked(ProcessRecord app) {
10837        // If this app is not running under the current user, then we
10838        // can't give it a report button because that would require
10839        // launching the report UI under a different user.
10840        app.errorReportReceiver = null;
10841
10842        for (int userId : mCurrentProfileIds) {
10843            if (app.userId == userId) {
10844                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10845                        mContext, app.info.packageName, app.info.flags);
10846            }
10847        }
10848        skipCurrentReceiverLocked(app);
10849    }
10850
10851    void skipCurrentReceiverLocked(ProcessRecord app) {
10852        for (BroadcastQueue queue : mBroadcastQueues) {
10853            queue.skipCurrentReceiverLocked(app);
10854        }
10855    }
10856
10857    /**
10858     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10859     * The application process will exit immediately after this call returns.
10860     * @param app object of the crashing app, null for the system server
10861     * @param crashInfo describing the exception
10862     */
10863    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10864        ProcessRecord r = findAppProcess(app, "Crash");
10865        final String processName = app == null ? "system_server"
10866                : (r == null ? "unknown" : r.processName);
10867
10868        handleApplicationCrashInner("crash", r, processName, crashInfo);
10869    }
10870
10871    /* Native crash reporting uses this inner version because it needs to be somewhat
10872     * decoupled from the AM-managed cleanup lifecycle
10873     */
10874    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10875            ApplicationErrorReport.CrashInfo crashInfo) {
10876        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10877                UserHandle.getUserId(Binder.getCallingUid()), processName,
10878                r == null ? -1 : r.info.flags,
10879                crashInfo.exceptionClassName,
10880                crashInfo.exceptionMessage,
10881                crashInfo.throwFileName,
10882                crashInfo.throwLineNumber);
10883
10884        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10885
10886        crashApplication(r, crashInfo);
10887    }
10888
10889    public void handleApplicationStrictModeViolation(
10890            IBinder app,
10891            int violationMask,
10892            StrictMode.ViolationInfo info) {
10893        ProcessRecord r = findAppProcess(app, "StrictMode");
10894        if (r == null) {
10895            return;
10896        }
10897
10898        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10899            Integer stackFingerprint = info.hashCode();
10900            boolean logIt = true;
10901            synchronized (mAlreadyLoggedViolatedStacks) {
10902                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10903                    logIt = false;
10904                    // TODO: sub-sample into EventLog for these, with
10905                    // the info.durationMillis?  Then we'd get
10906                    // the relative pain numbers, without logging all
10907                    // the stack traces repeatedly.  We'd want to do
10908                    // likewise in the client code, which also does
10909                    // dup suppression, before the Binder call.
10910                } else {
10911                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10912                        mAlreadyLoggedViolatedStacks.clear();
10913                    }
10914                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10915                }
10916            }
10917            if (logIt) {
10918                logStrictModeViolationToDropBox(r, info);
10919            }
10920        }
10921
10922        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10923            AppErrorResult result = new AppErrorResult();
10924            synchronized (this) {
10925                final long origId = Binder.clearCallingIdentity();
10926
10927                Message msg = Message.obtain();
10928                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10929                HashMap<String, Object> data = new HashMap<String, Object>();
10930                data.put("result", result);
10931                data.put("app", r);
10932                data.put("violationMask", violationMask);
10933                data.put("info", info);
10934                msg.obj = data;
10935                mHandler.sendMessage(msg);
10936
10937                Binder.restoreCallingIdentity(origId);
10938            }
10939            int res = result.get();
10940            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10941        }
10942    }
10943
10944    // Depending on the policy in effect, there could be a bunch of
10945    // these in quick succession so we try to batch these together to
10946    // minimize disk writes, number of dropbox entries, and maximize
10947    // compression, by having more fewer, larger records.
10948    private void logStrictModeViolationToDropBox(
10949            ProcessRecord process,
10950            StrictMode.ViolationInfo info) {
10951        if (info == null) {
10952            return;
10953        }
10954        final boolean isSystemApp = process == null ||
10955                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10956                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10957        final String processName = process == null ? "unknown" : process.processName;
10958        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10959        final DropBoxManager dbox = (DropBoxManager)
10960                mContext.getSystemService(Context.DROPBOX_SERVICE);
10961
10962        // Exit early if the dropbox isn't configured to accept this report type.
10963        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10964
10965        boolean bufferWasEmpty;
10966        boolean needsFlush;
10967        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10968        synchronized (sb) {
10969            bufferWasEmpty = sb.length() == 0;
10970            appendDropBoxProcessHeaders(process, processName, sb);
10971            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10972            sb.append("System-App: ").append(isSystemApp).append("\n");
10973            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10974            if (info.violationNumThisLoop != 0) {
10975                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10976            }
10977            if (info.numAnimationsRunning != 0) {
10978                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10979            }
10980            if (info.broadcastIntentAction != null) {
10981                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10982            }
10983            if (info.durationMillis != -1) {
10984                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10985            }
10986            if (info.numInstances != -1) {
10987                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10988            }
10989            if (info.tags != null) {
10990                for (String tag : info.tags) {
10991                    sb.append("Span-Tag: ").append(tag).append("\n");
10992                }
10993            }
10994            sb.append("\n");
10995            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10996                sb.append(info.crashInfo.stackTrace);
10997            }
10998            sb.append("\n");
10999
11000            // Only buffer up to ~64k.  Various logging bits truncate
11001            // things at 128k.
11002            needsFlush = (sb.length() > 64 * 1024);
11003        }
11004
11005        // Flush immediately if the buffer's grown too large, or this
11006        // is a non-system app.  Non-system apps are isolated with a
11007        // different tag & policy and not batched.
11008        //
11009        // Batching is useful during internal testing with
11010        // StrictMode settings turned up high.  Without batching,
11011        // thousands of separate files could be created on boot.
11012        if (!isSystemApp || needsFlush) {
11013            new Thread("Error dump: " + dropboxTag) {
11014                @Override
11015                public void run() {
11016                    String report;
11017                    synchronized (sb) {
11018                        report = sb.toString();
11019                        sb.delete(0, sb.length());
11020                        sb.trimToSize();
11021                    }
11022                    if (report.length() != 0) {
11023                        dbox.addText(dropboxTag, report);
11024                    }
11025                }
11026            }.start();
11027            return;
11028        }
11029
11030        // System app batching:
11031        if (!bufferWasEmpty) {
11032            // An existing dropbox-writing thread is outstanding, so
11033            // we don't need to start it up.  The existing thread will
11034            // catch the buffer appends we just did.
11035            return;
11036        }
11037
11038        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11039        // (After this point, we shouldn't access AMS internal data structures.)
11040        new Thread("Error dump: " + dropboxTag) {
11041            @Override
11042            public void run() {
11043                // 5 second sleep to let stacks arrive and be batched together
11044                try {
11045                    Thread.sleep(5000);  // 5 seconds
11046                } catch (InterruptedException e) {}
11047
11048                String errorReport;
11049                synchronized (mStrictModeBuffer) {
11050                    errorReport = mStrictModeBuffer.toString();
11051                    if (errorReport.length() == 0) {
11052                        return;
11053                    }
11054                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11055                    mStrictModeBuffer.trimToSize();
11056                }
11057                dbox.addText(dropboxTag, errorReport);
11058            }
11059        }.start();
11060    }
11061
11062    /**
11063     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11064     * @param app object of the crashing app, null for the system server
11065     * @param tag reported by the caller
11066     * @param crashInfo describing the context of the error
11067     * @return true if the process should exit immediately (WTF is fatal)
11068     */
11069    public boolean handleApplicationWtf(IBinder app, String tag,
11070            ApplicationErrorReport.CrashInfo crashInfo) {
11071        ProcessRecord r = findAppProcess(app, "WTF");
11072        final String processName = app == null ? "system_server"
11073                : (r == null ? "unknown" : r.processName);
11074
11075        EventLog.writeEvent(EventLogTags.AM_WTF,
11076                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11077                processName,
11078                r == null ? -1 : r.info.flags,
11079                tag, crashInfo.exceptionMessage);
11080
11081        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11082
11083        if (r != null && r.pid != Process.myPid() &&
11084                Settings.Global.getInt(mContext.getContentResolver(),
11085                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11086            crashApplication(r, crashInfo);
11087            return true;
11088        } else {
11089            return false;
11090        }
11091    }
11092
11093    /**
11094     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11095     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11096     */
11097    private ProcessRecord findAppProcess(IBinder app, String reason) {
11098        if (app == null) {
11099            return null;
11100        }
11101
11102        synchronized (this) {
11103            final int NP = mProcessNames.getMap().size();
11104            for (int ip=0; ip<NP; ip++) {
11105                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11106                final int NA = apps.size();
11107                for (int ia=0; ia<NA; ia++) {
11108                    ProcessRecord p = apps.valueAt(ia);
11109                    if (p.thread != null && p.thread.asBinder() == app) {
11110                        return p;
11111                    }
11112                }
11113            }
11114
11115            Slog.w(TAG, "Can't find mystery application for " + reason
11116                    + " from pid=" + Binder.getCallingPid()
11117                    + " uid=" + Binder.getCallingUid() + ": " + app);
11118            return null;
11119        }
11120    }
11121
11122    /**
11123     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11124     * to append various headers to the dropbox log text.
11125     */
11126    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11127            StringBuilder sb) {
11128        // Watchdog thread ends up invoking this function (with
11129        // a null ProcessRecord) to add the stack file to dropbox.
11130        // Do not acquire a lock on this (am) in such cases, as it
11131        // could cause a potential deadlock, if and when watchdog
11132        // is invoked due to unavailability of lock on am and it
11133        // would prevent watchdog from killing system_server.
11134        if (process == null) {
11135            sb.append("Process: ").append(processName).append("\n");
11136            return;
11137        }
11138        // Note: ProcessRecord 'process' is guarded by the service
11139        // instance.  (notably process.pkgList, which could otherwise change
11140        // concurrently during execution of this method)
11141        synchronized (this) {
11142            sb.append("Process: ").append(processName).append("\n");
11143            int flags = process.info.flags;
11144            IPackageManager pm = AppGlobals.getPackageManager();
11145            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11146            for (int ip=0; ip<process.pkgList.size(); ip++) {
11147                String pkg = process.pkgList.keyAt(ip);
11148                sb.append("Package: ").append(pkg);
11149                try {
11150                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11151                    if (pi != null) {
11152                        sb.append(" v").append(pi.versionCode);
11153                        if (pi.versionName != null) {
11154                            sb.append(" (").append(pi.versionName).append(")");
11155                        }
11156                    }
11157                } catch (RemoteException e) {
11158                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11159                }
11160                sb.append("\n");
11161            }
11162        }
11163    }
11164
11165    private static String processClass(ProcessRecord process) {
11166        if (process == null || process.pid == MY_PID) {
11167            return "system_server";
11168        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11169            return "system_app";
11170        } else {
11171            return "data_app";
11172        }
11173    }
11174
11175    /**
11176     * Write a description of an error (crash, WTF, ANR) to the drop box.
11177     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11178     * @param process which caused the error, null means the system server
11179     * @param activity which triggered the error, null if unknown
11180     * @param parent activity related to the error, null if unknown
11181     * @param subject line related to the error, null if absent
11182     * @param report in long form describing the error, null if absent
11183     * @param logFile to include in the report, null if none
11184     * @param crashInfo giving an application stack trace, null if absent
11185     */
11186    public void addErrorToDropBox(String eventType,
11187            ProcessRecord process, String processName, ActivityRecord activity,
11188            ActivityRecord parent, String subject,
11189            final String report, final File logFile,
11190            final ApplicationErrorReport.CrashInfo crashInfo) {
11191        // NOTE -- this must never acquire the ActivityManagerService lock,
11192        // otherwise the watchdog may be prevented from resetting the system.
11193
11194        final String dropboxTag = processClass(process) + "_" + eventType;
11195        final DropBoxManager dbox = (DropBoxManager)
11196                mContext.getSystemService(Context.DROPBOX_SERVICE);
11197
11198        // Exit early if the dropbox isn't configured to accept this report type.
11199        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11200
11201        final StringBuilder sb = new StringBuilder(1024);
11202        appendDropBoxProcessHeaders(process, processName, sb);
11203        if (activity != null) {
11204            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11205        }
11206        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11207            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11208        }
11209        if (parent != null && parent != activity) {
11210            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11211        }
11212        if (subject != null) {
11213            sb.append("Subject: ").append(subject).append("\n");
11214        }
11215        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11216        if (Debug.isDebuggerConnected()) {
11217            sb.append("Debugger: Connected\n");
11218        }
11219        sb.append("\n");
11220
11221        // Do the rest in a worker thread to avoid blocking the caller on I/O
11222        // (After this point, we shouldn't access AMS internal data structures.)
11223        Thread worker = new Thread("Error dump: " + dropboxTag) {
11224            @Override
11225            public void run() {
11226                if (report != null) {
11227                    sb.append(report);
11228                }
11229                if (logFile != null) {
11230                    try {
11231                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11232                                    "\n\n[[TRUNCATED]]"));
11233                    } catch (IOException e) {
11234                        Slog.e(TAG, "Error reading " + logFile, e);
11235                    }
11236                }
11237                if (crashInfo != null && crashInfo.stackTrace != null) {
11238                    sb.append(crashInfo.stackTrace);
11239                }
11240
11241                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11242                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11243                if (lines > 0) {
11244                    sb.append("\n");
11245
11246                    // Merge several logcat streams, and take the last N lines
11247                    InputStreamReader input = null;
11248                    try {
11249                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11250                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11251                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11252
11253                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11254                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11255                        input = new InputStreamReader(logcat.getInputStream());
11256
11257                        int num;
11258                        char[] buf = new char[8192];
11259                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11260                    } catch (IOException e) {
11261                        Slog.e(TAG, "Error running logcat", e);
11262                    } finally {
11263                        if (input != null) try { input.close(); } catch (IOException e) {}
11264                    }
11265                }
11266
11267                dbox.addText(dropboxTag, sb.toString());
11268            }
11269        };
11270
11271        if (process == null) {
11272            // If process is null, we are being called from some internal code
11273            // and may be about to die -- run this synchronously.
11274            worker.run();
11275        } else {
11276            worker.start();
11277        }
11278    }
11279
11280    /**
11281     * Bring up the "unexpected error" dialog box for a crashing app.
11282     * Deal with edge cases (intercepts from instrumented applications,
11283     * ActivityController, error intent receivers, that sort of thing).
11284     * @param r the application crashing
11285     * @param crashInfo describing the failure
11286     */
11287    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11288        long timeMillis = System.currentTimeMillis();
11289        String shortMsg = crashInfo.exceptionClassName;
11290        String longMsg = crashInfo.exceptionMessage;
11291        String stackTrace = crashInfo.stackTrace;
11292        if (shortMsg != null && longMsg != null) {
11293            longMsg = shortMsg + ": " + longMsg;
11294        } else if (shortMsg != null) {
11295            longMsg = shortMsg;
11296        }
11297
11298        AppErrorResult result = new AppErrorResult();
11299        synchronized (this) {
11300            if (mController != null) {
11301                try {
11302                    String name = r != null ? r.processName : null;
11303                    int pid = r != null ? r.pid : Binder.getCallingPid();
11304                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11305                    if (!mController.appCrashed(name, pid,
11306                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11307                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11308                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11309                            Slog.w(TAG, "Skip killing native crashed app " + name
11310                                    + "(" + pid + ") during testing");
11311                        } else {
11312                            Slog.w(TAG, "Force-killing crashed app " + name
11313                                    + " at watcher's request");
11314                            Process.killProcess(pid);
11315                            if (r != null) {
11316                                Process.killProcessGroup(uid, pid);
11317                            }
11318                        }
11319                        return;
11320                    }
11321                } catch (RemoteException e) {
11322                    mController = null;
11323                    Watchdog.getInstance().setActivityController(null);
11324                }
11325            }
11326
11327            final long origId = Binder.clearCallingIdentity();
11328
11329            // If this process is running instrumentation, finish it.
11330            if (r != null && r.instrumentationClass != null) {
11331                Slog.w(TAG, "Error in app " + r.processName
11332                      + " running instrumentation " + r.instrumentationClass + ":");
11333                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11334                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11335                Bundle info = new Bundle();
11336                info.putString("shortMsg", shortMsg);
11337                info.putString("longMsg", longMsg);
11338                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11339                Binder.restoreCallingIdentity(origId);
11340                return;
11341            }
11342
11343            // If we can't identify the process or it's already exceeded its crash quota,
11344            // quit right away without showing a crash dialog.
11345            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11346                Binder.restoreCallingIdentity(origId);
11347                return;
11348            }
11349
11350            Message msg = Message.obtain();
11351            msg.what = SHOW_ERROR_MSG;
11352            HashMap data = new HashMap();
11353            data.put("result", result);
11354            data.put("app", r);
11355            msg.obj = data;
11356            mHandler.sendMessage(msg);
11357
11358            Binder.restoreCallingIdentity(origId);
11359        }
11360
11361        int res = result.get();
11362
11363        Intent appErrorIntent = null;
11364        synchronized (this) {
11365            if (r != null && !r.isolated) {
11366                // XXX Can't keep track of crash time for isolated processes,
11367                // since they don't have a persistent identity.
11368                mProcessCrashTimes.put(r.info.processName, r.uid,
11369                        SystemClock.uptimeMillis());
11370            }
11371            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11372                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11373            }
11374        }
11375
11376        if (appErrorIntent != null) {
11377            try {
11378                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11379            } catch (ActivityNotFoundException e) {
11380                Slog.w(TAG, "bug report receiver dissappeared", e);
11381            }
11382        }
11383    }
11384
11385    Intent createAppErrorIntentLocked(ProcessRecord r,
11386            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11387        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11388        if (report == null) {
11389            return null;
11390        }
11391        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11392        result.setComponent(r.errorReportReceiver);
11393        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11394        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11395        return result;
11396    }
11397
11398    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11399            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11400        if (r.errorReportReceiver == null) {
11401            return null;
11402        }
11403
11404        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11405            return null;
11406        }
11407
11408        ApplicationErrorReport report = new ApplicationErrorReport();
11409        report.packageName = r.info.packageName;
11410        report.installerPackageName = r.errorReportReceiver.getPackageName();
11411        report.processName = r.processName;
11412        report.time = timeMillis;
11413        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11414
11415        if (r.crashing || r.forceCrashReport) {
11416            report.type = ApplicationErrorReport.TYPE_CRASH;
11417            report.crashInfo = crashInfo;
11418        } else if (r.notResponding) {
11419            report.type = ApplicationErrorReport.TYPE_ANR;
11420            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11421
11422            report.anrInfo.activity = r.notRespondingReport.tag;
11423            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11424            report.anrInfo.info = r.notRespondingReport.longMsg;
11425        }
11426
11427        return report;
11428    }
11429
11430    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11431        enforceNotIsolatedCaller("getProcessesInErrorState");
11432        // assume our apps are happy - lazy create the list
11433        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11434
11435        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11436                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11437        int userId = UserHandle.getUserId(Binder.getCallingUid());
11438
11439        synchronized (this) {
11440
11441            // iterate across all processes
11442            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11443                ProcessRecord app = mLruProcesses.get(i);
11444                if (!allUsers && app.userId != userId) {
11445                    continue;
11446                }
11447                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11448                    // This one's in trouble, so we'll generate a report for it
11449                    // crashes are higher priority (in case there's a crash *and* an anr)
11450                    ActivityManager.ProcessErrorStateInfo report = null;
11451                    if (app.crashing) {
11452                        report = app.crashingReport;
11453                    } else if (app.notResponding) {
11454                        report = app.notRespondingReport;
11455                    }
11456
11457                    if (report != null) {
11458                        if (errList == null) {
11459                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11460                        }
11461                        errList.add(report);
11462                    } else {
11463                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11464                                " crashing = " + app.crashing +
11465                                " notResponding = " + app.notResponding);
11466                    }
11467                }
11468            }
11469        }
11470
11471        return errList;
11472    }
11473
11474    static int procStateToImportance(int procState, int memAdj,
11475            ActivityManager.RunningAppProcessInfo currApp) {
11476        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11477        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11478            currApp.lru = memAdj;
11479        } else {
11480            currApp.lru = 0;
11481        }
11482        return imp;
11483    }
11484
11485    private void fillInProcMemInfo(ProcessRecord app,
11486            ActivityManager.RunningAppProcessInfo outInfo) {
11487        outInfo.pid = app.pid;
11488        outInfo.uid = app.info.uid;
11489        if (mHeavyWeightProcess == app) {
11490            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11491        }
11492        if (app.persistent) {
11493            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11494        }
11495        if (app.activities.size() > 0) {
11496            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11497        }
11498        outInfo.lastTrimLevel = app.trimMemoryLevel;
11499        int adj = app.curAdj;
11500        int procState = app.curProcState;
11501        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11502        outInfo.importanceReasonCode = app.adjTypeCode;
11503        outInfo.processState = app.curProcState;
11504    }
11505
11506    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11507        enforceNotIsolatedCaller("getRunningAppProcesses");
11508        // Lazy instantiation of list
11509        List<ActivityManager.RunningAppProcessInfo> runList = null;
11510        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11511                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11512        int userId = UserHandle.getUserId(Binder.getCallingUid());
11513        synchronized (this) {
11514            // Iterate across all processes
11515            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11516                ProcessRecord app = mLruProcesses.get(i);
11517                if (!allUsers && app.userId != userId) {
11518                    continue;
11519                }
11520                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11521                    // Generate process state info for running application
11522                    ActivityManager.RunningAppProcessInfo currApp =
11523                        new ActivityManager.RunningAppProcessInfo(app.processName,
11524                                app.pid, app.getPackageList());
11525                    fillInProcMemInfo(app, currApp);
11526                    if (app.adjSource instanceof ProcessRecord) {
11527                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11528                        currApp.importanceReasonImportance =
11529                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11530                                        app.adjSourceProcState);
11531                    } else if (app.adjSource instanceof ActivityRecord) {
11532                        ActivityRecord r = (ActivityRecord)app.adjSource;
11533                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11534                    }
11535                    if (app.adjTarget instanceof ComponentName) {
11536                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11537                    }
11538                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11539                    //        + " lru=" + currApp.lru);
11540                    if (runList == null) {
11541                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11542                    }
11543                    runList.add(currApp);
11544                }
11545            }
11546        }
11547        return runList;
11548    }
11549
11550    public List<ApplicationInfo> getRunningExternalApplications() {
11551        enforceNotIsolatedCaller("getRunningExternalApplications");
11552        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11553        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11554        if (runningApps != null && runningApps.size() > 0) {
11555            Set<String> extList = new HashSet<String>();
11556            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11557                if (app.pkgList != null) {
11558                    for (String pkg : app.pkgList) {
11559                        extList.add(pkg);
11560                    }
11561                }
11562            }
11563            IPackageManager pm = AppGlobals.getPackageManager();
11564            for (String pkg : extList) {
11565                try {
11566                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11567                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11568                        retList.add(info);
11569                    }
11570                } catch (RemoteException e) {
11571                }
11572            }
11573        }
11574        return retList;
11575    }
11576
11577    @Override
11578    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11579        enforceNotIsolatedCaller("getMyMemoryState");
11580        synchronized (this) {
11581            ProcessRecord proc;
11582            synchronized (mPidsSelfLocked) {
11583                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11584            }
11585            fillInProcMemInfo(proc, outInfo);
11586        }
11587    }
11588
11589    @Override
11590    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11591        if (checkCallingPermission(android.Manifest.permission.DUMP)
11592                != PackageManager.PERMISSION_GRANTED) {
11593            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11594                    + Binder.getCallingPid()
11595                    + ", uid=" + Binder.getCallingUid()
11596                    + " without permission "
11597                    + android.Manifest.permission.DUMP);
11598            return;
11599        }
11600
11601        boolean dumpAll = false;
11602        boolean dumpClient = false;
11603        String dumpPackage = null;
11604
11605        int opti = 0;
11606        while (opti < args.length) {
11607            String opt = args[opti];
11608            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11609                break;
11610            }
11611            opti++;
11612            if ("-a".equals(opt)) {
11613                dumpAll = true;
11614            } else if ("-c".equals(opt)) {
11615                dumpClient = true;
11616            } else if ("-h".equals(opt)) {
11617                pw.println("Activity manager dump options:");
11618                pw.println("  [-a] [-c] [-h] [cmd] ...");
11619                pw.println("  cmd may be one of:");
11620                pw.println("    a[ctivities]: activity stack state");
11621                pw.println("    r[recents]: recent activities state");
11622                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11623                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11624                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11625                pw.println("    o[om]: out of memory management");
11626                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11627                pw.println("    provider [COMP_SPEC]: provider client-side state");
11628                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11629                pw.println("    service [COMP_SPEC]: service client-side state");
11630                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11631                pw.println("    all: dump all activities");
11632                pw.println("    top: dump the top activity");
11633                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11634                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11635                pw.println("    a partial substring in a component name, a");
11636                pw.println("    hex object identifier.");
11637                pw.println("  -a: include all available server state.");
11638                pw.println("  -c: include client state.");
11639                return;
11640            } else {
11641                pw.println("Unknown argument: " + opt + "; use -h for help");
11642            }
11643        }
11644
11645        long origId = Binder.clearCallingIdentity();
11646        boolean more = false;
11647        // Is the caller requesting to dump a particular piece of data?
11648        if (opti < args.length) {
11649            String cmd = args[opti];
11650            opti++;
11651            if ("activities".equals(cmd) || "a".equals(cmd)) {
11652                synchronized (this) {
11653                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11654                }
11655            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11656                synchronized (this) {
11657                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11658                }
11659            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11660                String[] newArgs;
11661                String name;
11662                if (opti >= args.length) {
11663                    name = null;
11664                    newArgs = EMPTY_STRING_ARRAY;
11665                } else {
11666                    name = args[opti];
11667                    opti++;
11668                    newArgs = new String[args.length - opti];
11669                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11670                            args.length - opti);
11671                }
11672                synchronized (this) {
11673                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11674                }
11675            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11676                String[] newArgs;
11677                String name;
11678                if (opti >= args.length) {
11679                    name = null;
11680                    newArgs = EMPTY_STRING_ARRAY;
11681                } else {
11682                    name = args[opti];
11683                    opti++;
11684                    newArgs = new String[args.length - opti];
11685                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11686                            args.length - opti);
11687                }
11688                synchronized (this) {
11689                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11690                }
11691            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11692                String[] newArgs;
11693                String name;
11694                if (opti >= args.length) {
11695                    name = null;
11696                    newArgs = EMPTY_STRING_ARRAY;
11697                } else {
11698                    name = args[opti];
11699                    opti++;
11700                    newArgs = new String[args.length - opti];
11701                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11702                            args.length - opti);
11703                }
11704                synchronized (this) {
11705                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11706                }
11707            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11708                synchronized (this) {
11709                    dumpOomLocked(fd, pw, args, opti, true);
11710                }
11711            } else if ("provider".equals(cmd)) {
11712                String[] newArgs;
11713                String name;
11714                if (opti >= args.length) {
11715                    name = null;
11716                    newArgs = EMPTY_STRING_ARRAY;
11717                } else {
11718                    name = args[opti];
11719                    opti++;
11720                    newArgs = new String[args.length - opti];
11721                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11722                }
11723                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11724                    pw.println("No providers match: " + name);
11725                    pw.println("Use -h for help.");
11726                }
11727            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11728                synchronized (this) {
11729                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11730                }
11731            } else if ("service".equals(cmd)) {
11732                String[] newArgs;
11733                String name;
11734                if (opti >= args.length) {
11735                    name = null;
11736                    newArgs = EMPTY_STRING_ARRAY;
11737                } else {
11738                    name = args[opti];
11739                    opti++;
11740                    newArgs = new String[args.length - opti];
11741                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11742                            args.length - opti);
11743                }
11744                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11745                    pw.println("No services match: " + name);
11746                    pw.println("Use -h for help.");
11747                }
11748            } else if ("package".equals(cmd)) {
11749                String[] newArgs;
11750                if (opti >= args.length) {
11751                    pw.println("package: no package name specified");
11752                    pw.println("Use -h for help.");
11753                } else {
11754                    dumpPackage = args[opti];
11755                    opti++;
11756                    newArgs = new String[args.length - opti];
11757                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11758                            args.length - opti);
11759                    args = newArgs;
11760                    opti = 0;
11761                    more = true;
11762                }
11763            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11764                synchronized (this) {
11765                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11766                }
11767            } else {
11768                // Dumping a single activity?
11769                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11770                    pw.println("Bad activity command, or no activities match: " + cmd);
11771                    pw.println("Use -h for help.");
11772                }
11773            }
11774            if (!more) {
11775                Binder.restoreCallingIdentity(origId);
11776                return;
11777            }
11778        }
11779
11780        // No piece of data specified, dump everything.
11781        synchronized (this) {
11782            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11783            pw.println();
11784            if (dumpAll) {
11785                pw.println("-------------------------------------------------------------------------------");
11786            }
11787            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11788            pw.println();
11789            if (dumpAll) {
11790                pw.println("-------------------------------------------------------------------------------");
11791            }
11792            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11793            pw.println();
11794            if (dumpAll) {
11795                pw.println("-------------------------------------------------------------------------------");
11796            }
11797            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11798            pw.println();
11799            if (dumpAll) {
11800                pw.println("-------------------------------------------------------------------------------");
11801            }
11802            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11803            pw.println();
11804            if (dumpAll) {
11805                pw.println("-------------------------------------------------------------------------------");
11806            }
11807            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11808            pw.println();
11809            if (dumpAll) {
11810                pw.println("-------------------------------------------------------------------------------");
11811            }
11812            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11813        }
11814        Binder.restoreCallingIdentity(origId);
11815    }
11816
11817    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11818            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11819        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11820
11821        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11822                dumpPackage);
11823        boolean needSep = printedAnything;
11824
11825        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11826                dumpPackage, needSep, "  mFocusedActivity: ");
11827        if (printed) {
11828            printedAnything = true;
11829            needSep = false;
11830        }
11831
11832        if (dumpPackage == null) {
11833            if (needSep) {
11834                pw.println();
11835            }
11836            needSep = true;
11837            printedAnything = true;
11838            mStackSupervisor.dump(pw, "  ");
11839        }
11840
11841        if (!printedAnything) {
11842            pw.println("  (nothing)");
11843        }
11844    }
11845
11846    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11847            int opti, boolean dumpAll, String dumpPackage) {
11848        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11849
11850        boolean printedAnything = false;
11851
11852        if (mRecentTasks.size() > 0) {
11853            boolean printedHeader = false;
11854
11855            final int N = mRecentTasks.size();
11856            for (int i=0; i<N; i++) {
11857                TaskRecord tr = mRecentTasks.get(i);
11858                if (dumpPackage != null) {
11859                    if (tr.realActivity == null ||
11860                            !dumpPackage.equals(tr.realActivity)) {
11861                        continue;
11862                    }
11863                }
11864                if (!printedHeader) {
11865                    pw.println("  Recent tasks:");
11866                    printedHeader = true;
11867                    printedAnything = true;
11868                }
11869                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11870                        pw.println(tr);
11871                if (dumpAll) {
11872                    mRecentTasks.get(i).dump(pw, "    ");
11873                }
11874            }
11875        }
11876
11877        if (!printedAnything) {
11878            pw.println("  (nothing)");
11879        }
11880    }
11881
11882    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11883            int opti, boolean dumpAll, String dumpPackage) {
11884        boolean needSep = false;
11885        boolean printedAnything = false;
11886        int numPers = 0;
11887
11888        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11889
11890        if (dumpAll) {
11891            final int NP = mProcessNames.getMap().size();
11892            for (int ip=0; ip<NP; ip++) {
11893                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11894                final int NA = procs.size();
11895                for (int ia=0; ia<NA; ia++) {
11896                    ProcessRecord r = procs.valueAt(ia);
11897                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11898                        continue;
11899                    }
11900                    if (!needSep) {
11901                        pw.println("  All known processes:");
11902                        needSep = true;
11903                        printedAnything = true;
11904                    }
11905                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11906                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11907                        pw.print(" "); pw.println(r);
11908                    r.dump(pw, "    ");
11909                    if (r.persistent) {
11910                        numPers++;
11911                    }
11912                }
11913            }
11914        }
11915
11916        if (mIsolatedProcesses.size() > 0) {
11917            boolean printed = false;
11918            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11919                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11920                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11921                    continue;
11922                }
11923                if (!printed) {
11924                    if (needSep) {
11925                        pw.println();
11926                    }
11927                    pw.println("  Isolated process list (sorted by uid):");
11928                    printedAnything = true;
11929                    printed = true;
11930                    needSep = true;
11931                }
11932                pw.println(String.format("%sIsolated #%2d: %s",
11933                        "    ", i, r.toString()));
11934            }
11935        }
11936
11937        if (mLruProcesses.size() > 0) {
11938            if (needSep) {
11939                pw.println();
11940            }
11941            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11942                    pw.print(" total, non-act at ");
11943                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11944                    pw.print(", non-svc at ");
11945                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11946                    pw.println("):");
11947            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11948            needSep = true;
11949            printedAnything = true;
11950        }
11951
11952        if (dumpAll || dumpPackage != null) {
11953            synchronized (mPidsSelfLocked) {
11954                boolean printed = false;
11955                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11956                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11957                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11958                        continue;
11959                    }
11960                    if (!printed) {
11961                        if (needSep) pw.println();
11962                        needSep = true;
11963                        pw.println("  PID mappings:");
11964                        printed = true;
11965                        printedAnything = true;
11966                    }
11967                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11968                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11969                }
11970            }
11971        }
11972
11973        if (mForegroundProcesses.size() > 0) {
11974            synchronized (mPidsSelfLocked) {
11975                boolean printed = false;
11976                for (int i=0; i<mForegroundProcesses.size(); i++) {
11977                    ProcessRecord r = mPidsSelfLocked.get(
11978                            mForegroundProcesses.valueAt(i).pid);
11979                    if (dumpPackage != null && (r == null
11980                            || !r.pkgList.containsKey(dumpPackage))) {
11981                        continue;
11982                    }
11983                    if (!printed) {
11984                        if (needSep) pw.println();
11985                        needSep = true;
11986                        pw.println("  Foreground Processes:");
11987                        printed = true;
11988                        printedAnything = true;
11989                    }
11990                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11991                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11992                }
11993            }
11994        }
11995
11996        if (mPersistentStartingProcesses.size() > 0) {
11997            if (needSep) pw.println();
11998            needSep = true;
11999            printedAnything = true;
12000            pw.println("  Persisent processes that are starting:");
12001            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12002                    "Starting Norm", "Restarting PERS", dumpPackage);
12003        }
12004
12005        if (mRemovedProcesses.size() > 0) {
12006            if (needSep) pw.println();
12007            needSep = true;
12008            printedAnything = true;
12009            pw.println("  Processes that are being removed:");
12010            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12011                    "Removed Norm", "Removed PERS", dumpPackage);
12012        }
12013
12014        if (mProcessesOnHold.size() > 0) {
12015            if (needSep) pw.println();
12016            needSep = true;
12017            printedAnything = true;
12018            pw.println("  Processes that are on old until the system is ready:");
12019            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12020                    "OnHold Norm", "OnHold PERS", dumpPackage);
12021        }
12022
12023        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12024
12025        if (mProcessCrashTimes.getMap().size() > 0) {
12026            boolean printed = false;
12027            long now = SystemClock.uptimeMillis();
12028            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12029            final int NP = pmap.size();
12030            for (int ip=0; ip<NP; ip++) {
12031                String pname = pmap.keyAt(ip);
12032                SparseArray<Long> uids = pmap.valueAt(ip);
12033                final int N = uids.size();
12034                for (int i=0; i<N; i++) {
12035                    int puid = uids.keyAt(i);
12036                    ProcessRecord r = mProcessNames.get(pname, puid);
12037                    if (dumpPackage != null && (r == null
12038                            || !r.pkgList.containsKey(dumpPackage))) {
12039                        continue;
12040                    }
12041                    if (!printed) {
12042                        if (needSep) pw.println();
12043                        needSep = true;
12044                        pw.println("  Time since processes crashed:");
12045                        printed = true;
12046                        printedAnything = true;
12047                    }
12048                    pw.print("    Process "); pw.print(pname);
12049                            pw.print(" uid "); pw.print(puid);
12050                            pw.print(": last crashed ");
12051                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12052                            pw.println(" ago");
12053                }
12054            }
12055        }
12056
12057        if (mBadProcesses.getMap().size() > 0) {
12058            boolean printed = false;
12059            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12060            final int NP = pmap.size();
12061            for (int ip=0; ip<NP; ip++) {
12062                String pname = pmap.keyAt(ip);
12063                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12064                final int N = uids.size();
12065                for (int i=0; i<N; i++) {
12066                    int puid = uids.keyAt(i);
12067                    ProcessRecord r = mProcessNames.get(pname, puid);
12068                    if (dumpPackage != null && (r == null
12069                            || !r.pkgList.containsKey(dumpPackage))) {
12070                        continue;
12071                    }
12072                    if (!printed) {
12073                        if (needSep) pw.println();
12074                        needSep = true;
12075                        pw.println("  Bad processes:");
12076                        printedAnything = true;
12077                    }
12078                    BadProcessInfo info = uids.valueAt(i);
12079                    pw.print("    Bad process "); pw.print(pname);
12080                            pw.print(" uid "); pw.print(puid);
12081                            pw.print(": crashed at time "); pw.println(info.time);
12082                    if (info.shortMsg != null) {
12083                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12084                    }
12085                    if (info.longMsg != null) {
12086                        pw.print("      Long msg: "); pw.println(info.longMsg);
12087                    }
12088                    if (info.stack != null) {
12089                        pw.println("      Stack:");
12090                        int lastPos = 0;
12091                        for (int pos=0; pos<info.stack.length(); pos++) {
12092                            if (info.stack.charAt(pos) == '\n') {
12093                                pw.print("        ");
12094                                pw.write(info.stack, lastPos, pos-lastPos);
12095                                pw.println();
12096                                lastPos = pos+1;
12097                            }
12098                        }
12099                        if (lastPos < info.stack.length()) {
12100                            pw.print("        ");
12101                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12102                            pw.println();
12103                        }
12104                    }
12105                }
12106            }
12107        }
12108
12109        if (dumpPackage == null) {
12110            pw.println();
12111            needSep = false;
12112            pw.println("  mStartedUsers:");
12113            for (int i=0; i<mStartedUsers.size(); i++) {
12114                UserStartedState uss = mStartedUsers.valueAt(i);
12115                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12116                        pw.print(": "); uss.dump("", pw);
12117            }
12118            pw.print("  mStartedUserArray: [");
12119            for (int i=0; i<mStartedUserArray.length; i++) {
12120                if (i > 0) pw.print(", ");
12121                pw.print(mStartedUserArray[i]);
12122            }
12123            pw.println("]");
12124            pw.print("  mUserLru: [");
12125            for (int i=0; i<mUserLru.size(); i++) {
12126                if (i > 0) pw.print(", ");
12127                pw.print(mUserLru.get(i));
12128            }
12129            pw.println("]");
12130            if (dumpAll) {
12131                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12132            }
12133            synchronized (mUserProfileGroupIdsSelfLocked) {
12134                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12135                    pw.println("  mUserProfileGroupIds:");
12136                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12137                        pw.print("    User #");
12138                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12139                        pw.print(" -> profile #");
12140                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12141                    }
12142                }
12143            }
12144        }
12145        if (mHomeProcess != null && (dumpPackage == null
12146                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12147            if (needSep) {
12148                pw.println();
12149                needSep = false;
12150            }
12151            pw.println("  mHomeProcess: " + mHomeProcess);
12152        }
12153        if (mPreviousProcess != null && (dumpPackage == null
12154                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12155            if (needSep) {
12156                pw.println();
12157                needSep = false;
12158            }
12159            pw.println("  mPreviousProcess: " + mPreviousProcess);
12160        }
12161        if (dumpAll) {
12162            StringBuilder sb = new StringBuilder(128);
12163            sb.append("  mPreviousProcessVisibleTime: ");
12164            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12165            pw.println(sb);
12166        }
12167        if (mHeavyWeightProcess != null && (dumpPackage == null
12168                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12169            if (needSep) {
12170                pw.println();
12171                needSep = false;
12172            }
12173            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12174        }
12175        if (dumpPackage == null) {
12176            pw.println("  mConfiguration: " + mConfiguration);
12177        }
12178        if (dumpAll) {
12179            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12180            if (mCompatModePackages.getPackages().size() > 0) {
12181                boolean printed = false;
12182                for (Map.Entry<String, Integer> entry
12183                        : mCompatModePackages.getPackages().entrySet()) {
12184                    String pkg = entry.getKey();
12185                    int mode = entry.getValue();
12186                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12187                        continue;
12188                    }
12189                    if (!printed) {
12190                        pw.println("  mScreenCompatPackages:");
12191                        printed = true;
12192                    }
12193                    pw.print("    "); pw.print(pkg); pw.print(": ");
12194                            pw.print(mode); pw.println();
12195                }
12196            }
12197        }
12198        if (dumpPackage == null) {
12199            if (mSleeping || mWentToSleep || mLockScreenShown) {
12200                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12201                        + " mLockScreenShown " + mLockScreenShown);
12202            }
12203            if (mShuttingDown || mRunningVoice) {
12204                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12205            }
12206        }
12207        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12208                || mOrigWaitForDebugger) {
12209            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12210                    || dumpPackage.equals(mOrigDebugApp)) {
12211                if (needSep) {
12212                    pw.println();
12213                    needSep = false;
12214                }
12215                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12216                        + " mDebugTransient=" + mDebugTransient
12217                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12218            }
12219        }
12220        if (mOpenGlTraceApp != null) {
12221            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12222                if (needSep) {
12223                    pw.println();
12224                    needSep = false;
12225                }
12226                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12227            }
12228        }
12229        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12230                || mProfileFd != null) {
12231            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12232                if (needSep) {
12233                    pw.println();
12234                    needSep = false;
12235                }
12236                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12237                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12238                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12239                        + mAutoStopProfiler);
12240            }
12241        }
12242        if (dumpPackage == null) {
12243            if (mAlwaysFinishActivities || mController != null) {
12244                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12245                        + " mController=" + mController);
12246            }
12247            if (dumpAll) {
12248                pw.println("  Total persistent processes: " + numPers);
12249                pw.println("  mProcessesReady=" + mProcessesReady
12250                        + " mSystemReady=" + mSystemReady);
12251                pw.println("  mBooting=" + mBooting
12252                        + " mBooted=" + mBooted
12253                        + " mFactoryTest=" + mFactoryTest);
12254                pw.print("  mLastPowerCheckRealtime=");
12255                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12256                        pw.println("");
12257                pw.print("  mLastPowerCheckUptime=");
12258                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12259                        pw.println("");
12260                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12261                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12262                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12263                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12264                        + " (" + mLruProcesses.size() + " total)"
12265                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12266                        + " mNumServiceProcs=" + mNumServiceProcs
12267                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12268                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12269                        + " mLastMemoryLevel" + mLastMemoryLevel
12270                        + " mLastNumProcesses" + mLastNumProcesses);
12271                long now = SystemClock.uptimeMillis();
12272                pw.print("  mLastIdleTime=");
12273                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12274                        pw.print(" mLowRamSinceLastIdle=");
12275                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12276                        pw.println();
12277            }
12278        }
12279
12280        if (!printedAnything) {
12281            pw.println("  (nothing)");
12282        }
12283    }
12284
12285    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12286            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12287        if (mProcessesToGc.size() > 0) {
12288            boolean printed = false;
12289            long now = SystemClock.uptimeMillis();
12290            for (int i=0; i<mProcessesToGc.size(); i++) {
12291                ProcessRecord proc = mProcessesToGc.get(i);
12292                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12293                    continue;
12294                }
12295                if (!printed) {
12296                    if (needSep) pw.println();
12297                    needSep = true;
12298                    pw.println("  Processes that are waiting to GC:");
12299                    printed = true;
12300                }
12301                pw.print("    Process "); pw.println(proc);
12302                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12303                        pw.print(", last gced=");
12304                        pw.print(now-proc.lastRequestedGc);
12305                        pw.print(" ms ago, last lowMem=");
12306                        pw.print(now-proc.lastLowMemory);
12307                        pw.println(" ms ago");
12308
12309            }
12310        }
12311        return needSep;
12312    }
12313
12314    void printOomLevel(PrintWriter pw, String name, int adj) {
12315        pw.print("    ");
12316        if (adj >= 0) {
12317            pw.print(' ');
12318            if (adj < 10) pw.print(' ');
12319        } else {
12320            if (adj > -10) pw.print(' ');
12321        }
12322        pw.print(adj);
12323        pw.print(": ");
12324        pw.print(name);
12325        pw.print(" (");
12326        pw.print(mProcessList.getMemLevel(adj)/1024);
12327        pw.println(" kB)");
12328    }
12329
12330    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12331            int opti, boolean dumpAll) {
12332        boolean needSep = false;
12333
12334        if (mLruProcesses.size() > 0) {
12335            if (needSep) pw.println();
12336            needSep = true;
12337            pw.println("  OOM levels:");
12338            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12339            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12340            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12341            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12342            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12343            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12344            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12345            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12346            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12347            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12348            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12349            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12350            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12351
12352            if (needSep) pw.println();
12353            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12354                    pw.print(" total, non-act at ");
12355                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12356                    pw.print(", non-svc at ");
12357                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12358                    pw.println("):");
12359            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12360            needSep = true;
12361        }
12362
12363        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12364
12365        pw.println();
12366        pw.println("  mHomeProcess: " + mHomeProcess);
12367        pw.println("  mPreviousProcess: " + mPreviousProcess);
12368        if (mHeavyWeightProcess != null) {
12369            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12370        }
12371
12372        return true;
12373    }
12374
12375    /**
12376     * There are three ways to call this:
12377     *  - no provider specified: dump all the providers
12378     *  - a flattened component name that matched an existing provider was specified as the
12379     *    first arg: dump that one provider
12380     *  - the first arg isn't the flattened component name of an existing provider:
12381     *    dump all providers whose component contains the first arg as a substring
12382     */
12383    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12384            int opti, boolean dumpAll) {
12385        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12386    }
12387
12388    static class ItemMatcher {
12389        ArrayList<ComponentName> components;
12390        ArrayList<String> strings;
12391        ArrayList<Integer> objects;
12392        boolean all;
12393
12394        ItemMatcher() {
12395            all = true;
12396        }
12397
12398        void build(String name) {
12399            ComponentName componentName = ComponentName.unflattenFromString(name);
12400            if (componentName != null) {
12401                if (components == null) {
12402                    components = new ArrayList<ComponentName>();
12403                }
12404                components.add(componentName);
12405                all = false;
12406            } else {
12407                int objectId = 0;
12408                // Not a '/' separated full component name; maybe an object ID?
12409                try {
12410                    objectId = Integer.parseInt(name, 16);
12411                    if (objects == null) {
12412                        objects = new ArrayList<Integer>();
12413                    }
12414                    objects.add(objectId);
12415                    all = false;
12416                } catch (RuntimeException e) {
12417                    // Not an integer; just do string match.
12418                    if (strings == null) {
12419                        strings = new ArrayList<String>();
12420                    }
12421                    strings.add(name);
12422                    all = false;
12423                }
12424            }
12425        }
12426
12427        int build(String[] args, int opti) {
12428            for (; opti<args.length; opti++) {
12429                String name = args[opti];
12430                if ("--".equals(name)) {
12431                    return opti+1;
12432                }
12433                build(name);
12434            }
12435            return opti;
12436        }
12437
12438        boolean match(Object object, ComponentName comp) {
12439            if (all) {
12440                return true;
12441            }
12442            if (components != null) {
12443                for (int i=0; i<components.size(); i++) {
12444                    if (components.get(i).equals(comp)) {
12445                        return true;
12446                    }
12447                }
12448            }
12449            if (objects != null) {
12450                for (int i=0; i<objects.size(); i++) {
12451                    if (System.identityHashCode(object) == objects.get(i)) {
12452                        return true;
12453                    }
12454                }
12455            }
12456            if (strings != null) {
12457                String flat = comp.flattenToString();
12458                for (int i=0; i<strings.size(); i++) {
12459                    if (flat.contains(strings.get(i))) {
12460                        return true;
12461                    }
12462                }
12463            }
12464            return false;
12465        }
12466    }
12467
12468    /**
12469     * There are three things that cmd can be:
12470     *  - a flattened component name that matches an existing activity
12471     *  - the cmd arg isn't the flattened component name of an existing activity:
12472     *    dump all activity whose component contains the cmd as a substring
12473     *  - A hex number of the ActivityRecord object instance.
12474     */
12475    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12476            int opti, boolean dumpAll) {
12477        ArrayList<ActivityRecord> activities;
12478
12479        synchronized (this) {
12480            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12481        }
12482
12483        if (activities.size() <= 0) {
12484            return false;
12485        }
12486
12487        String[] newArgs = new String[args.length - opti];
12488        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12489
12490        TaskRecord lastTask = null;
12491        boolean needSep = false;
12492        for (int i=activities.size()-1; i>=0; i--) {
12493            ActivityRecord r = activities.get(i);
12494            if (needSep) {
12495                pw.println();
12496            }
12497            needSep = true;
12498            synchronized (this) {
12499                if (lastTask != r.task) {
12500                    lastTask = r.task;
12501                    pw.print("TASK "); pw.print(lastTask.affinity);
12502                            pw.print(" id="); pw.println(lastTask.taskId);
12503                    if (dumpAll) {
12504                        lastTask.dump(pw, "  ");
12505                    }
12506                }
12507            }
12508            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12509        }
12510        return true;
12511    }
12512
12513    /**
12514     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12515     * there is a thread associated with the activity.
12516     */
12517    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12518            final ActivityRecord r, String[] args, boolean dumpAll) {
12519        String innerPrefix = prefix + "  ";
12520        synchronized (this) {
12521            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12522                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12523                    pw.print(" pid=");
12524                    if (r.app != null) pw.println(r.app.pid);
12525                    else pw.println("(not running)");
12526            if (dumpAll) {
12527                r.dump(pw, innerPrefix);
12528            }
12529        }
12530        if (r.app != null && r.app.thread != null) {
12531            // flush anything that is already in the PrintWriter since the thread is going
12532            // to write to the file descriptor directly
12533            pw.flush();
12534            try {
12535                TransferPipe tp = new TransferPipe();
12536                try {
12537                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12538                            r.appToken, innerPrefix, args);
12539                    tp.go(fd);
12540                } finally {
12541                    tp.kill();
12542                }
12543            } catch (IOException e) {
12544                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12545            } catch (RemoteException e) {
12546                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12547            }
12548        }
12549    }
12550
12551    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12552            int opti, boolean dumpAll, String dumpPackage) {
12553        boolean needSep = false;
12554        boolean onlyHistory = false;
12555        boolean printedAnything = false;
12556
12557        if ("history".equals(dumpPackage)) {
12558            if (opti < args.length && "-s".equals(args[opti])) {
12559                dumpAll = false;
12560            }
12561            onlyHistory = true;
12562            dumpPackage = null;
12563        }
12564
12565        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12566        if (!onlyHistory && dumpAll) {
12567            if (mRegisteredReceivers.size() > 0) {
12568                boolean printed = false;
12569                Iterator it = mRegisteredReceivers.values().iterator();
12570                while (it.hasNext()) {
12571                    ReceiverList r = (ReceiverList)it.next();
12572                    if (dumpPackage != null && (r.app == null ||
12573                            !dumpPackage.equals(r.app.info.packageName))) {
12574                        continue;
12575                    }
12576                    if (!printed) {
12577                        pw.println("  Registered Receivers:");
12578                        needSep = true;
12579                        printed = true;
12580                        printedAnything = true;
12581                    }
12582                    pw.print("  * "); pw.println(r);
12583                    r.dump(pw, "    ");
12584                }
12585            }
12586
12587            if (mReceiverResolver.dump(pw, needSep ?
12588                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12589                    "    ", dumpPackage, false)) {
12590                needSep = true;
12591                printedAnything = true;
12592            }
12593        }
12594
12595        for (BroadcastQueue q : mBroadcastQueues) {
12596            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12597            printedAnything |= needSep;
12598        }
12599
12600        needSep = true;
12601
12602        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12603            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12604                if (needSep) {
12605                    pw.println();
12606                }
12607                needSep = true;
12608                printedAnything = true;
12609                pw.print("  Sticky broadcasts for user ");
12610                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12611                StringBuilder sb = new StringBuilder(128);
12612                for (Map.Entry<String, ArrayList<Intent>> ent
12613                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12614                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12615                    if (dumpAll) {
12616                        pw.println(":");
12617                        ArrayList<Intent> intents = ent.getValue();
12618                        final int N = intents.size();
12619                        for (int i=0; i<N; i++) {
12620                            sb.setLength(0);
12621                            sb.append("    Intent: ");
12622                            intents.get(i).toShortString(sb, false, true, false, false);
12623                            pw.println(sb.toString());
12624                            Bundle bundle = intents.get(i).getExtras();
12625                            if (bundle != null) {
12626                                pw.print("      ");
12627                                pw.println(bundle.toString());
12628                            }
12629                        }
12630                    } else {
12631                        pw.println("");
12632                    }
12633                }
12634            }
12635        }
12636
12637        if (!onlyHistory && dumpAll) {
12638            pw.println();
12639            for (BroadcastQueue queue : mBroadcastQueues) {
12640                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12641                        + queue.mBroadcastsScheduled);
12642            }
12643            pw.println("  mHandler:");
12644            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12645            needSep = true;
12646            printedAnything = true;
12647        }
12648
12649        if (!printedAnything) {
12650            pw.println("  (nothing)");
12651        }
12652    }
12653
12654    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12655            int opti, boolean dumpAll, String dumpPackage) {
12656        boolean needSep;
12657        boolean printedAnything = false;
12658
12659        ItemMatcher matcher = new ItemMatcher();
12660        matcher.build(args, opti);
12661
12662        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12663
12664        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12665        printedAnything |= needSep;
12666
12667        if (mLaunchingProviders.size() > 0) {
12668            boolean printed = false;
12669            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12670                ContentProviderRecord r = mLaunchingProviders.get(i);
12671                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12672                    continue;
12673                }
12674                if (!printed) {
12675                    if (needSep) pw.println();
12676                    needSep = true;
12677                    pw.println("  Launching content providers:");
12678                    printed = true;
12679                    printedAnything = true;
12680                }
12681                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12682                        pw.println(r);
12683            }
12684        }
12685
12686        if (mGrantedUriPermissions.size() > 0) {
12687            boolean printed = false;
12688            int dumpUid = -2;
12689            if (dumpPackage != null) {
12690                try {
12691                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12692                } catch (NameNotFoundException e) {
12693                    dumpUid = -1;
12694                }
12695            }
12696            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12697                int uid = mGrantedUriPermissions.keyAt(i);
12698                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12699                    continue;
12700                }
12701                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12702                if (!printed) {
12703                    if (needSep) pw.println();
12704                    needSep = true;
12705                    pw.println("  Granted Uri Permissions:");
12706                    printed = true;
12707                    printedAnything = true;
12708                }
12709                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12710                for (UriPermission perm : perms.values()) {
12711                    pw.print("    "); pw.println(perm);
12712                    if (dumpAll) {
12713                        perm.dump(pw, "      ");
12714                    }
12715                }
12716            }
12717        }
12718
12719        if (!printedAnything) {
12720            pw.println("  (nothing)");
12721        }
12722    }
12723
12724    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12725            int opti, boolean dumpAll, String dumpPackage) {
12726        boolean printed = false;
12727
12728        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12729
12730        if (mIntentSenderRecords.size() > 0) {
12731            Iterator<WeakReference<PendingIntentRecord>> it
12732                    = mIntentSenderRecords.values().iterator();
12733            while (it.hasNext()) {
12734                WeakReference<PendingIntentRecord> ref = it.next();
12735                PendingIntentRecord rec = ref != null ? ref.get(): null;
12736                if (dumpPackage != null && (rec == null
12737                        || !dumpPackage.equals(rec.key.packageName))) {
12738                    continue;
12739                }
12740                printed = true;
12741                if (rec != null) {
12742                    pw.print("  * "); pw.println(rec);
12743                    if (dumpAll) {
12744                        rec.dump(pw, "    ");
12745                    }
12746                } else {
12747                    pw.print("  * "); pw.println(ref);
12748                }
12749            }
12750        }
12751
12752        if (!printed) {
12753            pw.println("  (nothing)");
12754        }
12755    }
12756
12757    private static final int dumpProcessList(PrintWriter pw,
12758            ActivityManagerService service, List list,
12759            String prefix, String normalLabel, String persistentLabel,
12760            String dumpPackage) {
12761        int numPers = 0;
12762        final int N = list.size()-1;
12763        for (int i=N; i>=0; i--) {
12764            ProcessRecord r = (ProcessRecord)list.get(i);
12765            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12766                continue;
12767            }
12768            pw.println(String.format("%s%s #%2d: %s",
12769                    prefix, (r.persistent ? persistentLabel : normalLabel),
12770                    i, r.toString()));
12771            if (r.persistent) {
12772                numPers++;
12773            }
12774        }
12775        return numPers;
12776    }
12777
12778    private static final boolean dumpProcessOomList(PrintWriter pw,
12779            ActivityManagerService service, List<ProcessRecord> origList,
12780            String prefix, String normalLabel, String persistentLabel,
12781            boolean inclDetails, String dumpPackage) {
12782
12783        ArrayList<Pair<ProcessRecord, Integer>> list
12784                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12785        for (int i=0; i<origList.size(); i++) {
12786            ProcessRecord r = origList.get(i);
12787            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12788                continue;
12789            }
12790            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12791        }
12792
12793        if (list.size() <= 0) {
12794            return false;
12795        }
12796
12797        Comparator<Pair<ProcessRecord, Integer>> comparator
12798                = new Comparator<Pair<ProcessRecord, Integer>>() {
12799            @Override
12800            public int compare(Pair<ProcessRecord, Integer> object1,
12801                    Pair<ProcessRecord, Integer> object2) {
12802                if (object1.first.setAdj != object2.first.setAdj) {
12803                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12804                }
12805                if (object1.second.intValue() != object2.second.intValue()) {
12806                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12807                }
12808                return 0;
12809            }
12810        };
12811
12812        Collections.sort(list, comparator);
12813
12814        final long curRealtime = SystemClock.elapsedRealtime();
12815        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12816        final long curUptime = SystemClock.uptimeMillis();
12817        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12818
12819        for (int i=list.size()-1; i>=0; i--) {
12820            ProcessRecord r = list.get(i).first;
12821            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12822            char schedGroup;
12823            switch (r.setSchedGroup) {
12824                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12825                    schedGroup = 'B';
12826                    break;
12827                case Process.THREAD_GROUP_DEFAULT:
12828                    schedGroup = 'F';
12829                    break;
12830                default:
12831                    schedGroup = '?';
12832                    break;
12833            }
12834            char foreground;
12835            if (r.foregroundActivities) {
12836                foreground = 'A';
12837            } else if (r.foregroundServices) {
12838                foreground = 'S';
12839            } else {
12840                foreground = ' ';
12841            }
12842            String procState = ProcessList.makeProcStateString(r.curProcState);
12843            pw.print(prefix);
12844            pw.print(r.persistent ? persistentLabel : normalLabel);
12845            pw.print(" #");
12846            int num = (origList.size()-1)-list.get(i).second;
12847            if (num < 10) pw.print(' ');
12848            pw.print(num);
12849            pw.print(": ");
12850            pw.print(oomAdj);
12851            pw.print(' ');
12852            pw.print(schedGroup);
12853            pw.print('/');
12854            pw.print(foreground);
12855            pw.print('/');
12856            pw.print(procState);
12857            pw.print(" trm:");
12858            if (r.trimMemoryLevel < 10) pw.print(' ');
12859            pw.print(r.trimMemoryLevel);
12860            pw.print(' ');
12861            pw.print(r.toShortString());
12862            pw.print(" (");
12863            pw.print(r.adjType);
12864            pw.println(')');
12865            if (r.adjSource != null || r.adjTarget != null) {
12866                pw.print(prefix);
12867                pw.print("    ");
12868                if (r.adjTarget instanceof ComponentName) {
12869                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12870                } else if (r.adjTarget != null) {
12871                    pw.print(r.adjTarget.toString());
12872                } else {
12873                    pw.print("{null}");
12874                }
12875                pw.print("<=");
12876                if (r.adjSource instanceof ProcessRecord) {
12877                    pw.print("Proc{");
12878                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12879                    pw.println("}");
12880                } else if (r.adjSource != null) {
12881                    pw.println(r.adjSource.toString());
12882                } else {
12883                    pw.println("{null}");
12884                }
12885            }
12886            if (inclDetails) {
12887                pw.print(prefix);
12888                pw.print("    ");
12889                pw.print("oom: max="); pw.print(r.maxAdj);
12890                pw.print(" curRaw="); pw.print(r.curRawAdj);
12891                pw.print(" setRaw="); pw.print(r.setRawAdj);
12892                pw.print(" cur="); pw.print(r.curAdj);
12893                pw.print(" set="); pw.println(r.setAdj);
12894                pw.print(prefix);
12895                pw.print("    ");
12896                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12897                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12898                pw.print(" lastPss="); pw.print(r.lastPss);
12899                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12900                pw.print(prefix);
12901                pw.print("    ");
12902                pw.print("cached="); pw.print(r.cached);
12903                pw.print(" empty="); pw.print(r.empty);
12904                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12905
12906                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12907                    if (r.lastWakeTime != 0) {
12908                        long wtime;
12909                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12910                        synchronized (stats) {
12911                            wtime = stats.getProcessWakeTime(r.info.uid,
12912                                    r.pid, curRealtime);
12913                        }
12914                        long timeUsed = wtime - r.lastWakeTime;
12915                        pw.print(prefix);
12916                        pw.print("    ");
12917                        pw.print("keep awake over ");
12918                        TimeUtils.formatDuration(realtimeSince, pw);
12919                        pw.print(" used ");
12920                        TimeUtils.formatDuration(timeUsed, pw);
12921                        pw.print(" (");
12922                        pw.print((timeUsed*100)/realtimeSince);
12923                        pw.println("%)");
12924                    }
12925                    if (r.lastCpuTime != 0) {
12926                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12927                        pw.print(prefix);
12928                        pw.print("    ");
12929                        pw.print("run cpu over ");
12930                        TimeUtils.formatDuration(uptimeSince, pw);
12931                        pw.print(" used ");
12932                        TimeUtils.formatDuration(timeUsed, pw);
12933                        pw.print(" (");
12934                        pw.print((timeUsed*100)/uptimeSince);
12935                        pw.println("%)");
12936                    }
12937                }
12938            }
12939        }
12940        return true;
12941    }
12942
12943    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12944        ArrayList<ProcessRecord> procs;
12945        synchronized (this) {
12946            if (args != null && args.length > start
12947                    && args[start].charAt(0) != '-') {
12948                procs = new ArrayList<ProcessRecord>();
12949                int pid = -1;
12950                try {
12951                    pid = Integer.parseInt(args[start]);
12952                } catch (NumberFormatException e) {
12953                }
12954                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12955                    ProcessRecord proc = mLruProcesses.get(i);
12956                    if (proc.pid == pid) {
12957                        procs.add(proc);
12958                    } else if (proc.processName.equals(args[start])) {
12959                        procs.add(proc);
12960                    }
12961                }
12962                if (procs.size() <= 0) {
12963                    return null;
12964                }
12965            } else {
12966                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12967            }
12968        }
12969        return procs;
12970    }
12971
12972    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12973            PrintWriter pw, String[] args) {
12974        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12975        if (procs == null) {
12976            pw.println("No process found for: " + args[0]);
12977            return;
12978        }
12979
12980        long uptime = SystemClock.uptimeMillis();
12981        long realtime = SystemClock.elapsedRealtime();
12982        pw.println("Applications Graphics Acceleration Info:");
12983        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12984
12985        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12986            ProcessRecord r = procs.get(i);
12987            if (r.thread != null) {
12988                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12989                pw.flush();
12990                try {
12991                    TransferPipe tp = new TransferPipe();
12992                    try {
12993                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12994                        tp.go(fd);
12995                    } finally {
12996                        tp.kill();
12997                    }
12998                } catch (IOException e) {
12999                    pw.println("Failure while dumping the app: " + r);
13000                    pw.flush();
13001                } catch (RemoteException e) {
13002                    pw.println("Got a RemoteException while dumping the app " + r);
13003                    pw.flush();
13004                }
13005            }
13006        }
13007    }
13008
13009    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13010        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13011        if (procs == null) {
13012            pw.println("No process found for: " + args[0]);
13013            return;
13014        }
13015
13016        pw.println("Applications Database Info:");
13017
13018        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13019            ProcessRecord r = procs.get(i);
13020            if (r.thread != null) {
13021                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13022                pw.flush();
13023                try {
13024                    TransferPipe tp = new TransferPipe();
13025                    try {
13026                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13027                        tp.go(fd);
13028                    } finally {
13029                        tp.kill();
13030                    }
13031                } catch (IOException e) {
13032                    pw.println("Failure while dumping the app: " + r);
13033                    pw.flush();
13034                } catch (RemoteException e) {
13035                    pw.println("Got a RemoteException while dumping the app " + r);
13036                    pw.flush();
13037                }
13038            }
13039        }
13040    }
13041
13042    final static class MemItem {
13043        final boolean isProc;
13044        final String label;
13045        final String shortLabel;
13046        final long pss;
13047        final int id;
13048        final boolean hasActivities;
13049        ArrayList<MemItem> subitems;
13050
13051        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13052                boolean _hasActivities) {
13053            isProc = true;
13054            label = _label;
13055            shortLabel = _shortLabel;
13056            pss = _pss;
13057            id = _id;
13058            hasActivities = _hasActivities;
13059        }
13060
13061        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13062            isProc = false;
13063            label = _label;
13064            shortLabel = _shortLabel;
13065            pss = _pss;
13066            id = _id;
13067            hasActivities = false;
13068        }
13069    }
13070
13071    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13072            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13073        if (sort && !isCompact) {
13074            Collections.sort(items, new Comparator<MemItem>() {
13075                @Override
13076                public int compare(MemItem lhs, MemItem rhs) {
13077                    if (lhs.pss < rhs.pss) {
13078                        return 1;
13079                    } else if (lhs.pss > rhs.pss) {
13080                        return -1;
13081                    }
13082                    return 0;
13083                }
13084            });
13085        }
13086
13087        for (int i=0; i<items.size(); i++) {
13088            MemItem mi = items.get(i);
13089            if (!isCompact) {
13090                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13091            } else if (mi.isProc) {
13092                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13093                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13094                pw.println(mi.hasActivities ? ",a" : ",e");
13095            } else {
13096                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13097                pw.println(mi.pss);
13098            }
13099            if (mi.subitems != null) {
13100                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13101                        true, isCompact);
13102            }
13103        }
13104    }
13105
13106    // These are in KB.
13107    static final long[] DUMP_MEM_BUCKETS = new long[] {
13108        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13109        120*1024, 160*1024, 200*1024,
13110        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13111        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13112    };
13113
13114    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13115            boolean stackLike) {
13116        int start = label.lastIndexOf('.');
13117        if (start >= 0) start++;
13118        else start = 0;
13119        int end = label.length();
13120        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13121            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13122                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13123                out.append(bucket);
13124                out.append(stackLike ? "MB." : "MB ");
13125                out.append(label, start, end);
13126                return;
13127            }
13128        }
13129        out.append(memKB/1024);
13130        out.append(stackLike ? "MB." : "MB ");
13131        out.append(label, start, end);
13132    }
13133
13134    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13135            ProcessList.NATIVE_ADJ,
13136            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13137            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13138            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13139            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13140            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13141    };
13142    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13143            "Native",
13144            "System", "Persistent", "Foreground",
13145            "Visible", "Perceptible",
13146            "Heavy Weight", "Backup",
13147            "A Services", "Home",
13148            "Previous", "B Services", "Cached"
13149    };
13150    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13151            "native",
13152            "sys", "pers", "fore",
13153            "vis", "percept",
13154            "heavy", "backup",
13155            "servicea", "home",
13156            "prev", "serviceb", "cached"
13157    };
13158
13159    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13160            long realtime, boolean isCheckinRequest, boolean isCompact) {
13161        if (isCheckinRequest || isCompact) {
13162            // short checkin version
13163            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13164        } else {
13165            pw.println("Applications Memory Usage (kB):");
13166            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13167        }
13168    }
13169
13170    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13171            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13172        boolean dumpDetails = false;
13173        boolean dumpFullDetails = false;
13174        boolean dumpDalvik = false;
13175        boolean oomOnly = false;
13176        boolean isCompact = false;
13177        boolean localOnly = false;
13178
13179        int opti = 0;
13180        while (opti < args.length) {
13181            String opt = args[opti];
13182            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13183                break;
13184            }
13185            opti++;
13186            if ("-a".equals(opt)) {
13187                dumpDetails = true;
13188                dumpFullDetails = true;
13189                dumpDalvik = true;
13190            } else if ("-d".equals(opt)) {
13191                dumpDalvik = true;
13192            } else if ("-c".equals(opt)) {
13193                isCompact = true;
13194            } else if ("--oom".equals(opt)) {
13195                oomOnly = true;
13196            } else if ("--local".equals(opt)) {
13197                localOnly = true;
13198            } else if ("-h".equals(opt)) {
13199                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13200                pw.println("  -a: include all available information for each process.");
13201                pw.println("  -d: include dalvik details when dumping process details.");
13202                pw.println("  -c: dump in a compact machine-parseable representation.");
13203                pw.println("  --oom: only show processes organized by oom adj.");
13204                pw.println("  --local: only collect details locally, don't call process.");
13205                pw.println("If [process] is specified it can be the name or ");
13206                pw.println("pid of a specific process to dump.");
13207                return;
13208            } else {
13209                pw.println("Unknown argument: " + opt + "; use -h for help");
13210            }
13211        }
13212
13213        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13214        long uptime = SystemClock.uptimeMillis();
13215        long realtime = SystemClock.elapsedRealtime();
13216        final long[] tmpLong = new long[1];
13217
13218        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13219        if (procs == null) {
13220            // No Java processes.  Maybe they want to print a native process.
13221            if (args != null && args.length > opti
13222                    && args[opti].charAt(0) != '-') {
13223                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13224                        = new ArrayList<ProcessCpuTracker.Stats>();
13225                updateCpuStatsNow();
13226                int findPid = -1;
13227                try {
13228                    findPid = Integer.parseInt(args[opti]);
13229                } catch (NumberFormatException e) {
13230                }
13231                synchronized (mProcessCpuThread) {
13232                    final int N = mProcessCpuTracker.countStats();
13233                    for (int i=0; i<N; i++) {
13234                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13235                        if (st.pid == findPid || (st.baseName != null
13236                                && st.baseName.equals(args[opti]))) {
13237                            nativeProcs.add(st);
13238                        }
13239                    }
13240                }
13241                if (nativeProcs.size() > 0) {
13242                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13243                            isCompact);
13244                    Debug.MemoryInfo mi = null;
13245                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13246                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13247                        final int pid = r.pid;
13248                        if (!isCheckinRequest && dumpDetails) {
13249                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13250                        }
13251                        if (mi == null) {
13252                            mi = new Debug.MemoryInfo();
13253                        }
13254                        if (dumpDetails || (!brief && !oomOnly)) {
13255                            Debug.getMemoryInfo(pid, mi);
13256                        } else {
13257                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13258                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13259                        }
13260                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13261                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13262                        if (isCheckinRequest) {
13263                            pw.println();
13264                        }
13265                    }
13266                    return;
13267                }
13268            }
13269            pw.println("No process found for: " + args[opti]);
13270            return;
13271        }
13272
13273        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13274            dumpDetails = true;
13275        }
13276
13277        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13278
13279        String[] innerArgs = new String[args.length-opti];
13280        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13281
13282        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13283        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13284        long nativePss=0, dalvikPss=0, otherPss=0;
13285        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13286
13287        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13288        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13289                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13290
13291        long totalPss = 0;
13292        long cachedPss = 0;
13293
13294        Debug.MemoryInfo mi = null;
13295        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13296            final ProcessRecord r = procs.get(i);
13297            final IApplicationThread thread;
13298            final int pid;
13299            final int oomAdj;
13300            final boolean hasActivities;
13301            synchronized (this) {
13302                thread = r.thread;
13303                pid = r.pid;
13304                oomAdj = r.getSetAdjWithServices();
13305                hasActivities = r.activities.size() > 0;
13306            }
13307            if (thread != null) {
13308                if (!isCheckinRequest && dumpDetails) {
13309                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13310                }
13311                if (mi == null) {
13312                    mi = new Debug.MemoryInfo();
13313                }
13314                if (dumpDetails || (!brief && !oomOnly)) {
13315                    Debug.getMemoryInfo(pid, mi);
13316                } else {
13317                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13318                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13319                }
13320                if (dumpDetails) {
13321                    if (localOnly) {
13322                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13323                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13324                        if (isCheckinRequest) {
13325                            pw.println();
13326                        }
13327                    } else {
13328                        try {
13329                            pw.flush();
13330                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13331                                    dumpDalvik, innerArgs);
13332                        } catch (RemoteException e) {
13333                            if (!isCheckinRequest) {
13334                                pw.println("Got RemoteException!");
13335                                pw.flush();
13336                            }
13337                        }
13338                    }
13339                }
13340
13341                final long myTotalPss = mi.getTotalPss();
13342                final long myTotalUss = mi.getTotalUss();
13343
13344                synchronized (this) {
13345                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13346                        // Record this for posterity if the process has been stable.
13347                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13348                    }
13349                }
13350
13351                if (!isCheckinRequest && mi != null) {
13352                    totalPss += myTotalPss;
13353                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13354                            (hasActivities ? " / activities)" : ")"),
13355                            r.processName, myTotalPss, pid, hasActivities);
13356                    procMems.add(pssItem);
13357                    procMemsMap.put(pid, pssItem);
13358
13359                    nativePss += mi.nativePss;
13360                    dalvikPss += mi.dalvikPss;
13361                    otherPss += mi.otherPss;
13362                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13363                        long mem = mi.getOtherPss(j);
13364                        miscPss[j] += mem;
13365                        otherPss -= mem;
13366                    }
13367
13368                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13369                        cachedPss += myTotalPss;
13370                    }
13371
13372                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13373                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13374                                || oomIndex == (oomPss.length-1)) {
13375                            oomPss[oomIndex] += myTotalPss;
13376                            if (oomProcs[oomIndex] == null) {
13377                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13378                            }
13379                            oomProcs[oomIndex].add(pssItem);
13380                            break;
13381                        }
13382                    }
13383                }
13384            }
13385        }
13386
13387        long nativeProcTotalPss = 0;
13388
13389        if (!isCheckinRequest && procs.size() > 1) {
13390            // If we are showing aggregations, also look for native processes to
13391            // include so that our aggregations are more accurate.
13392            updateCpuStatsNow();
13393            synchronized (mProcessCpuThread) {
13394                final int N = mProcessCpuTracker.countStats();
13395                for (int i=0; i<N; i++) {
13396                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13397                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13398                        if (mi == null) {
13399                            mi = new Debug.MemoryInfo();
13400                        }
13401                        if (!brief && !oomOnly) {
13402                            Debug.getMemoryInfo(st.pid, mi);
13403                        } else {
13404                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13405                            mi.nativePrivateDirty = (int)tmpLong[0];
13406                        }
13407
13408                        final long myTotalPss = mi.getTotalPss();
13409                        totalPss += myTotalPss;
13410                        nativeProcTotalPss += myTotalPss;
13411
13412                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13413                                st.name, myTotalPss, st.pid, false);
13414                        procMems.add(pssItem);
13415
13416                        nativePss += mi.nativePss;
13417                        dalvikPss += mi.dalvikPss;
13418                        otherPss += mi.otherPss;
13419                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13420                            long mem = mi.getOtherPss(j);
13421                            miscPss[j] += mem;
13422                            otherPss -= mem;
13423                        }
13424                        oomPss[0] += myTotalPss;
13425                        if (oomProcs[0] == null) {
13426                            oomProcs[0] = new ArrayList<MemItem>();
13427                        }
13428                        oomProcs[0].add(pssItem);
13429                    }
13430                }
13431            }
13432
13433            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13434
13435            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13436            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13437            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13438            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13439                String label = Debug.MemoryInfo.getOtherLabel(j);
13440                catMems.add(new MemItem(label, label, miscPss[j], j));
13441            }
13442
13443            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13444            for (int j=0; j<oomPss.length; j++) {
13445                if (oomPss[j] != 0) {
13446                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13447                            : DUMP_MEM_OOM_LABEL[j];
13448                    MemItem item = new MemItem(label, label, oomPss[j],
13449                            DUMP_MEM_OOM_ADJ[j]);
13450                    item.subitems = oomProcs[j];
13451                    oomMems.add(item);
13452                }
13453            }
13454
13455            if (!brief && !oomOnly && !isCompact) {
13456                pw.println();
13457                pw.println("Total PSS by process:");
13458                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13459                pw.println();
13460            }
13461            if (!isCompact) {
13462                pw.println("Total PSS by OOM adjustment:");
13463            }
13464            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13465            if (!brief && !oomOnly) {
13466                PrintWriter out = categoryPw != null ? categoryPw : pw;
13467                if (!isCompact) {
13468                    out.println();
13469                    out.println("Total PSS by category:");
13470                }
13471                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13472            }
13473            if (!isCompact) {
13474                pw.println();
13475            }
13476            MemInfoReader memInfo = new MemInfoReader();
13477            memInfo.readMemInfo();
13478            if (nativeProcTotalPss > 0) {
13479                synchronized (this) {
13480                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13481                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13482                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13483                            nativeProcTotalPss);
13484                }
13485            }
13486            if (!brief) {
13487                if (!isCompact) {
13488                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13489                    pw.print(" kB (status ");
13490                    switch (mLastMemoryLevel) {
13491                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13492                            pw.println("normal)");
13493                            break;
13494                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13495                            pw.println("moderate)");
13496                            break;
13497                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13498                            pw.println("low)");
13499                            break;
13500                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13501                            pw.println("critical)");
13502                            break;
13503                        default:
13504                            pw.print(mLastMemoryLevel);
13505                            pw.println(")");
13506                            break;
13507                    }
13508                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13509                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13510                            pw.print(cachedPss); pw.print(" cached pss + ");
13511                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13512                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13513                } else {
13514                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13515                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13516                            + memInfo.getFreeSizeKb()); pw.print(",");
13517                    pw.println(totalPss - cachedPss);
13518                }
13519            }
13520            if (!isCompact) {
13521                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13522                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13523                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13524                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13525                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13526                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13527                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13528                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13529                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13530                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13531                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13532            }
13533            if (!brief) {
13534                if (memInfo.getZramTotalSizeKb() != 0) {
13535                    if (!isCompact) {
13536                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13537                                pw.print(" kB physical used for ");
13538                                pw.print(memInfo.getSwapTotalSizeKb()
13539                                        - memInfo.getSwapFreeSizeKb());
13540                                pw.print(" kB in swap (");
13541                                pw.print(memInfo.getSwapTotalSizeKb());
13542                                pw.println(" kB total swap)");
13543                    } else {
13544                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13545                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13546                                pw.println(memInfo.getSwapFreeSizeKb());
13547                    }
13548                }
13549                final int[] SINGLE_LONG_FORMAT = new int[] {
13550                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13551                };
13552                long[] longOut = new long[1];
13553                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13554                        SINGLE_LONG_FORMAT, null, longOut, null);
13555                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13556                longOut[0] = 0;
13557                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13558                        SINGLE_LONG_FORMAT, null, longOut, null);
13559                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13560                longOut[0] = 0;
13561                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13562                        SINGLE_LONG_FORMAT, null, longOut, null);
13563                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13564                longOut[0] = 0;
13565                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13566                        SINGLE_LONG_FORMAT, null, longOut, null);
13567                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13568                if (!isCompact) {
13569                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13570                        pw.print("      KSM: "); pw.print(sharing);
13571                                pw.print(" kB saved from shared ");
13572                                pw.print(shared); pw.println(" kB");
13573                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13574                                pw.print(voltile); pw.println(" kB volatile");
13575                    }
13576                    pw.print("   Tuning: ");
13577                    pw.print(ActivityManager.staticGetMemoryClass());
13578                    pw.print(" (large ");
13579                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13580                    pw.print("), oom ");
13581                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13582                    pw.print(" kB");
13583                    pw.print(", restore limit ");
13584                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13585                    pw.print(" kB");
13586                    if (ActivityManager.isLowRamDeviceStatic()) {
13587                        pw.print(" (low-ram)");
13588                    }
13589                    if (ActivityManager.isHighEndGfx()) {
13590                        pw.print(" (high-end-gfx)");
13591                    }
13592                    pw.println();
13593                } else {
13594                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13595                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13596                    pw.println(voltile);
13597                    pw.print("tuning,");
13598                    pw.print(ActivityManager.staticGetMemoryClass());
13599                    pw.print(',');
13600                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13601                    pw.print(',');
13602                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13603                    if (ActivityManager.isLowRamDeviceStatic()) {
13604                        pw.print(",low-ram");
13605                    }
13606                    if (ActivityManager.isHighEndGfx()) {
13607                        pw.print(",high-end-gfx");
13608                    }
13609                    pw.println();
13610                }
13611            }
13612        }
13613    }
13614
13615    /**
13616     * Searches array of arguments for the specified string
13617     * @param args array of argument strings
13618     * @param value value to search for
13619     * @return true if the value is contained in the array
13620     */
13621    private static boolean scanArgs(String[] args, String value) {
13622        if (args != null) {
13623            for (String arg : args) {
13624                if (value.equals(arg)) {
13625                    return true;
13626                }
13627            }
13628        }
13629        return false;
13630    }
13631
13632    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13633            ContentProviderRecord cpr, boolean always) {
13634        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13635
13636        if (!inLaunching || always) {
13637            synchronized (cpr) {
13638                cpr.launchingApp = null;
13639                cpr.notifyAll();
13640            }
13641            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13642            String names[] = cpr.info.authority.split(";");
13643            for (int j = 0; j < names.length; j++) {
13644                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13645            }
13646        }
13647
13648        for (int i=0; i<cpr.connections.size(); i++) {
13649            ContentProviderConnection conn = cpr.connections.get(i);
13650            if (conn.waiting) {
13651                // If this connection is waiting for the provider, then we don't
13652                // need to mess with its process unless we are always removing
13653                // or for some reason the provider is not currently launching.
13654                if (inLaunching && !always) {
13655                    continue;
13656                }
13657            }
13658            ProcessRecord capp = conn.client;
13659            conn.dead = true;
13660            if (conn.stableCount > 0) {
13661                if (!capp.persistent && capp.thread != null
13662                        && capp.pid != 0
13663                        && capp.pid != MY_PID) {
13664                    killUnneededProcessLocked(capp, "depends on provider "
13665                            + cpr.name.flattenToShortString()
13666                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13667                }
13668            } else if (capp.thread != null && conn.provider.provider != null) {
13669                try {
13670                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13671                } catch (RemoteException e) {
13672                }
13673                // In the protocol here, we don't expect the client to correctly
13674                // clean up this connection, we'll just remove it.
13675                cpr.connections.remove(i);
13676                conn.client.conProviders.remove(conn);
13677            }
13678        }
13679
13680        if (inLaunching && always) {
13681            mLaunchingProviders.remove(cpr);
13682        }
13683        return inLaunching;
13684    }
13685
13686    /**
13687     * Main code for cleaning up a process when it has gone away.  This is
13688     * called both as a result of the process dying, or directly when stopping
13689     * a process when running in single process mode.
13690     */
13691    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13692            boolean restarting, boolean allowRestart, int index) {
13693        if (index >= 0) {
13694            removeLruProcessLocked(app);
13695            ProcessList.remove(app.pid);
13696        }
13697
13698        mProcessesToGc.remove(app);
13699        mPendingPssProcesses.remove(app);
13700
13701        // Dismiss any open dialogs.
13702        if (app.crashDialog != null && !app.forceCrashReport) {
13703            app.crashDialog.dismiss();
13704            app.crashDialog = null;
13705        }
13706        if (app.anrDialog != null) {
13707            app.anrDialog.dismiss();
13708            app.anrDialog = null;
13709        }
13710        if (app.waitDialog != null) {
13711            app.waitDialog.dismiss();
13712            app.waitDialog = null;
13713        }
13714
13715        app.crashing = false;
13716        app.notResponding = false;
13717
13718        app.resetPackageList(mProcessStats);
13719        app.unlinkDeathRecipient();
13720        app.makeInactive(mProcessStats);
13721        app.waitingToKill = null;
13722        app.forcingToForeground = null;
13723        updateProcessForegroundLocked(app, false, false);
13724        app.foregroundActivities = false;
13725        app.hasShownUi = false;
13726        app.treatLikeActivity = false;
13727        app.hasAboveClient = false;
13728        app.hasClientActivities = false;
13729
13730        mServices.killServicesLocked(app, allowRestart);
13731
13732        boolean restart = false;
13733
13734        // Remove published content providers.
13735        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13736            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13737            final boolean always = app.bad || !allowRestart;
13738            if (removeDyingProviderLocked(app, cpr, always) || always) {
13739                // We left the provider in the launching list, need to
13740                // restart it.
13741                restart = true;
13742            }
13743
13744            cpr.provider = null;
13745            cpr.proc = null;
13746        }
13747        app.pubProviders.clear();
13748
13749        // Take care of any launching providers waiting for this process.
13750        if (checkAppInLaunchingProvidersLocked(app, false)) {
13751            restart = true;
13752        }
13753
13754        // Unregister from connected content providers.
13755        if (!app.conProviders.isEmpty()) {
13756            for (int i=0; i<app.conProviders.size(); i++) {
13757                ContentProviderConnection conn = app.conProviders.get(i);
13758                conn.provider.connections.remove(conn);
13759            }
13760            app.conProviders.clear();
13761        }
13762
13763        // At this point there may be remaining entries in mLaunchingProviders
13764        // where we were the only one waiting, so they are no longer of use.
13765        // Look for these and clean up if found.
13766        // XXX Commented out for now.  Trying to figure out a way to reproduce
13767        // the actual situation to identify what is actually going on.
13768        if (false) {
13769            for (int i=0; i<mLaunchingProviders.size(); i++) {
13770                ContentProviderRecord cpr = (ContentProviderRecord)
13771                        mLaunchingProviders.get(i);
13772                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13773                    synchronized (cpr) {
13774                        cpr.launchingApp = null;
13775                        cpr.notifyAll();
13776                    }
13777                }
13778            }
13779        }
13780
13781        skipCurrentReceiverLocked(app);
13782
13783        // Unregister any receivers.
13784        for (int i=app.receivers.size()-1; i>=0; i--) {
13785            removeReceiverLocked(app.receivers.valueAt(i));
13786        }
13787        app.receivers.clear();
13788
13789        // If the app is undergoing backup, tell the backup manager about it
13790        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13791            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13792                    + mBackupTarget.appInfo + " died during backup");
13793            try {
13794                IBackupManager bm = IBackupManager.Stub.asInterface(
13795                        ServiceManager.getService(Context.BACKUP_SERVICE));
13796                bm.agentDisconnected(app.info.packageName);
13797            } catch (RemoteException e) {
13798                // can't happen; backup manager is local
13799            }
13800        }
13801
13802        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13803            ProcessChangeItem item = mPendingProcessChanges.get(i);
13804            if (item.pid == app.pid) {
13805                mPendingProcessChanges.remove(i);
13806                mAvailProcessChanges.add(item);
13807            }
13808        }
13809        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13810
13811        // If the caller is restarting this app, then leave it in its
13812        // current lists and let the caller take care of it.
13813        if (restarting) {
13814            return;
13815        }
13816
13817        if (!app.persistent || app.isolated) {
13818            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13819                    "Removing non-persistent process during cleanup: " + app);
13820            mProcessNames.remove(app.processName, app.uid);
13821            mIsolatedProcesses.remove(app.uid);
13822            if (mHeavyWeightProcess == app) {
13823                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13824                        mHeavyWeightProcess.userId, 0));
13825                mHeavyWeightProcess = null;
13826            }
13827        } else if (!app.removed) {
13828            // This app is persistent, so we need to keep its record around.
13829            // If it is not already on the pending app list, add it there
13830            // and start a new process for it.
13831            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13832                mPersistentStartingProcesses.add(app);
13833                restart = true;
13834            }
13835        }
13836        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13837                "Clean-up removing on hold: " + app);
13838        mProcessesOnHold.remove(app);
13839
13840        if (app == mHomeProcess) {
13841            mHomeProcess = null;
13842        }
13843        if (app == mPreviousProcess) {
13844            mPreviousProcess = null;
13845        }
13846
13847        if (restart && !app.isolated) {
13848            // We have components that still need to be running in the
13849            // process, so re-launch it.
13850            mProcessNames.put(app.processName, app.uid, app);
13851            startProcessLocked(app, "restart", app.processName);
13852        } else if (app.pid > 0 && app.pid != MY_PID) {
13853            // Goodbye!
13854            boolean removed;
13855            synchronized (mPidsSelfLocked) {
13856                mPidsSelfLocked.remove(app.pid);
13857                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13858            }
13859            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13860            if (app.isolated) {
13861                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13862            }
13863            app.setPid(0);
13864        }
13865    }
13866
13867    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13868        // Look through the content providers we are waiting to have launched,
13869        // and if any run in this process then either schedule a restart of
13870        // the process or kill the client waiting for it if this process has
13871        // gone bad.
13872        int NL = mLaunchingProviders.size();
13873        boolean restart = false;
13874        for (int i=0; i<NL; i++) {
13875            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13876            if (cpr.launchingApp == app) {
13877                if (!alwaysBad && !app.bad) {
13878                    restart = true;
13879                } else {
13880                    removeDyingProviderLocked(app, cpr, true);
13881                    // cpr should have been removed from mLaunchingProviders
13882                    NL = mLaunchingProviders.size();
13883                    i--;
13884                }
13885            }
13886        }
13887        return restart;
13888    }
13889
13890    // =========================================================
13891    // SERVICES
13892    // =========================================================
13893
13894    @Override
13895    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13896            int flags) {
13897        enforceNotIsolatedCaller("getServices");
13898        synchronized (this) {
13899            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13900        }
13901    }
13902
13903    @Override
13904    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13905        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13906        synchronized (this) {
13907            return mServices.getRunningServiceControlPanelLocked(name);
13908        }
13909    }
13910
13911    @Override
13912    public ComponentName startService(IApplicationThread caller, Intent service,
13913            String resolvedType, int userId) {
13914        enforceNotIsolatedCaller("startService");
13915        // Refuse possible leaked file descriptors
13916        if (service != null && service.hasFileDescriptors() == true) {
13917            throw new IllegalArgumentException("File descriptors passed in Intent");
13918        }
13919
13920        if (DEBUG_SERVICE)
13921            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13922        synchronized(this) {
13923            final int callingPid = Binder.getCallingPid();
13924            final int callingUid = Binder.getCallingUid();
13925            final long origId = Binder.clearCallingIdentity();
13926            ComponentName res = mServices.startServiceLocked(caller, service,
13927                    resolvedType, callingPid, callingUid, userId);
13928            Binder.restoreCallingIdentity(origId);
13929            return res;
13930        }
13931    }
13932
13933    ComponentName startServiceInPackage(int uid,
13934            Intent service, String resolvedType, int userId) {
13935        synchronized(this) {
13936            if (DEBUG_SERVICE)
13937                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13938            final long origId = Binder.clearCallingIdentity();
13939            ComponentName res = mServices.startServiceLocked(null, service,
13940                    resolvedType, -1, uid, userId);
13941            Binder.restoreCallingIdentity(origId);
13942            return res;
13943        }
13944    }
13945
13946    @Override
13947    public int stopService(IApplicationThread caller, Intent service,
13948            String resolvedType, int userId) {
13949        enforceNotIsolatedCaller("stopService");
13950        // Refuse possible leaked file descriptors
13951        if (service != null && service.hasFileDescriptors() == true) {
13952            throw new IllegalArgumentException("File descriptors passed in Intent");
13953        }
13954
13955        synchronized(this) {
13956            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13957        }
13958    }
13959
13960    @Override
13961    public IBinder peekService(Intent service, String resolvedType) {
13962        enforceNotIsolatedCaller("peekService");
13963        // Refuse possible leaked file descriptors
13964        if (service != null && service.hasFileDescriptors() == true) {
13965            throw new IllegalArgumentException("File descriptors passed in Intent");
13966        }
13967        synchronized(this) {
13968            return mServices.peekServiceLocked(service, resolvedType);
13969        }
13970    }
13971
13972    @Override
13973    public boolean stopServiceToken(ComponentName className, IBinder token,
13974            int startId) {
13975        synchronized(this) {
13976            return mServices.stopServiceTokenLocked(className, token, startId);
13977        }
13978    }
13979
13980    @Override
13981    public void setServiceForeground(ComponentName className, IBinder token,
13982            int id, Notification notification, boolean removeNotification) {
13983        synchronized(this) {
13984            mServices.setServiceForegroundLocked(className, token, id, notification,
13985                    removeNotification);
13986        }
13987    }
13988
13989    @Override
13990    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13991            boolean requireFull, String name, String callerPackage) {
13992        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13993                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13994    }
13995
13996    int unsafeConvertIncomingUser(int userId) {
13997        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13998                ? mCurrentUserId : userId;
13999    }
14000
14001    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14002            int allowMode, String name, String callerPackage) {
14003        final int callingUserId = UserHandle.getUserId(callingUid);
14004        if (callingUserId == userId) {
14005            return userId;
14006        }
14007
14008        // Note that we may be accessing mCurrentUserId outside of a lock...
14009        // shouldn't be a big deal, if this is being called outside
14010        // of a locked context there is intrinsically a race with
14011        // the value the caller will receive and someone else changing it.
14012        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14013        // we will switch to the calling user if access to the current user fails.
14014        int targetUserId = unsafeConvertIncomingUser(userId);
14015
14016        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14017            final boolean allow;
14018            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14019                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14020                // If the caller has this permission, they always pass go.  And collect $200.
14021                allow = true;
14022            } else if (allowMode == ALLOW_FULL_ONLY) {
14023                // We require full access, sucks to be you.
14024                allow = false;
14025            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14026                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14027                // If the caller does not have either permission, they are always doomed.
14028                allow = false;
14029            } else if (allowMode == ALLOW_NON_FULL) {
14030                // We are blanket allowing non-full access, you lucky caller!
14031                allow = true;
14032            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14033                // We may or may not allow this depending on whether the two users are
14034                // in the same profile.
14035                synchronized (mUserProfileGroupIdsSelfLocked) {
14036                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14037                            UserInfo.NO_PROFILE_GROUP_ID);
14038                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14039                            UserInfo.NO_PROFILE_GROUP_ID);
14040                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14041                            && callingProfile == targetProfile;
14042                }
14043            } else {
14044                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14045            }
14046            if (!allow) {
14047                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14048                    // In this case, they would like to just execute as their
14049                    // owner user instead of failing.
14050                    targetUserId = callingUserId;
14051                } else {
14052                    StringBuilder builder = new StringBuilder(128);
14053                    builder.append("Permission Denial: ");
14054                    builder.append(name);
14055                    if (callerPackage != null) {
14056                        builder.append(" from ");
14057                        builder.append(callerPackage);
14058                    }
14059                    builder.append(" asks to run as user ");
14060                    builder.append(userId);
14061                    builder.append(" but is calling from user ");
14062                    builder.append(UserHandle.getUserId(callingUid));
14063                    builder.append("; this requires ");
14064                    builder.append(INTERACT_ACROSS_USERS_FULL);
14065                    if (allowMode != ALLOW_FULL_ONLY) {
14066                        builder.append(" or ");
14067                        builder.append(INTERACT_ACROSS_USERS);
14068                    }
14069                    String msg = builder.toString();
14070                    Slog.w(TAG, msg);
14071                    throw new SecurityException(msg);
14072                }
14073            }
14074        }
14075        if (!allowAll && targetUserId < 0) {
14076            throw new IllegalArgumentException(
14077                    "Call does not support special user #" + targetUserId);
14078        }
14079        return targetUserId;
14080    }
14081
14082    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14083            String className, int flags) {
14084        boolean result = false;
14085        // For apps that don't have pre-defined UIDs, check for permission
14086        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14087            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14088                if (ActivityManager.checkUidPermission(
14089                        INTERACT_ACROSS_USERS,
14090                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14091                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14092                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14093                            + " requests FLAG_SINGLE_USER, but app does not hold "
14094                            + INTERACT_ACROSS_USERS;
14095                    Slog.w(TAG, msg);
14096                    throw new SecurityException(msg);
14097                }
14098                // Permission passed
14099                result = true;
14100            }
14101        } else if ("system".equals(componentProcessName)) {
14102            result = true;
14103        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14104                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14105            // Phone app is allowed to export singleuser providers.
14106            result = true;
14107        } else {
14108            // App with pre-defined UID, check if it's a persistent app
14109            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14110        }
14111        if (DEBUG_MU) {
14112            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14113                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14114        }
14115        return result;
14116    }
14117
14118    /**
14119     * Checks to see if the caller is in the same app as the singleton
14120     * component, or the component is in a special app. It allows special apps
14121     * to export singleton components but prevents exporting singleton
14122     * components for regular apps.
14123     */
14124    boolean isValidSingletonCall(int callingUid, int componentUid) {
14125        int componentAppId = UserHandle.getAppId(componentUid);
14126        return UserHandle.isSameApp(callingUid, componentUid)
14127                || componentAppId == Process.SYSTEM_UID
14128                || componentAppId == Process.PHONE_UID
14129                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14130                        == PackageManager.PERMISSION_GRANTED;
14131    }
14132
14133    public int bindService(IApplicationThread caller, IBinder token,
14134            Intent service, String resolvedType,
14135            IServiceConnection connection, int flags, int userId) {
14136        enforceNotIsolatedCaller("bindService");
14137        // Refuse possible leaked file descriptors
14138        if (service != null && service.hasFileDescriptors() == true) {
14139            throw new IllegalArgumentException("File descriptors passed in Intent");
14140        }
14141
14142        synchronized(this) {
14143            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14144                    connection, flags, userId);
14145        }
14146    }
14147
14148    public boolean unbindService(IServiceConnection connection) {
14149        synchronized (this) {
14150            return mServices.unbindServiceLocked(connection);
14151        }
14152    }
14153
14154    public void publishService(IBinder token, Intent intent, IBinder service) {
14155        // Refuse possible leaked file descriptors
14156        if (intent != null && intent.hasFileDescriptors() == true) {
14157            throw new IllegalArgumentException("File descriptors passed in Intent");
14158        }
14159
14160        synchronized(this) {
14161            if (!(token instanceof ServiceRecord)) {
14162                throw new IllegalArgumentException("Invalid service token");
14163            }
14164            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14165        }
14166    }
14167
14168    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14169        // Refuse possible leaked file descriptors
14170        if (intent != null && intent.hasFileDescriptors() == true) {
14171            throw new IllegalArgumentException("File descriptors passed in Intent");
14172        }
14173
14174        synchronized(this) {
14175            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14176        }
14177    }
14178
14179    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14180        synchronized(this) {
14181            if (!(token instanceof ServiceRecord)) {
14182                throw new IllegalArgumentException("Invalid service token");
14183            }
14184            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14185        }
14186    }
14187
14188    // =========================================================
14189    // BACKUP AND RESTORE
14190    // =========================================================
14191
14192    // Cause the target app to be launched if necessary and its backup agent
14193    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14194    // activity manager to announce its creation.
14195    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14196        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14197        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14198
14199        synchronized(this) {
14200            // !!! TODO: currently no check here that we're already bound
14201            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14202            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14203            synchronized (stats) {
14204                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14205            }
14206
14207            // Backup agent is now in use, its package can't be stopped.
14208            try {
14209                AppGlobals.getPackageManager().setPackageStoppedState(
14210                        app.packageName, false, UserHandle.getUserId(app.uid));
14211            } catch (RemoteException e) {
14212            } catch (IllegalArgumentException e) {
14213                Slog.w(TAG, "Failed trying to unstop package "
14214                        + app.packageName + ": " + e);
14215            }
14216
14217            BackupRecord r = new BackupRecord(ss, app, backupMode);
14218            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14219                    ? new ComponentName(app.packageName, app.backupAgentName)
14220                    : new ComponentName("android", "FullBackupAgent");
14221            // startProcessLocked() returns existing proc's record if it's already running
14222            ProcessRecord proc = startProcessLocked(app.processName, app,
14223                    false, 0, "backup", hostingName, false, false, false);
14224            if (proc == null) {
14225                Slog.e(TAG, "Unable to start backup agent process " + r);
14226                return false;
14227            }
14228
14229            r.app = proc;
14230            mBackupTarget = r;
14231            mBackupAppName = app.packageName;
14232
14233            // Try not to kill the process during backup
14234            updateOomAdjLocked(proc);
14235
14236            // If the process is already attached, schedule the creation of the backup agent now.
14237            // If it is not yet live, this will be done when it attaches to the framework.
14238            if (proc.thread != null) {
14239                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14240                try {
14241                    proc.thread.scheduleCreateBackupAgent(app,
14242                            compatibilityInfoForPackageLocked(app), backupMode);
14243                } catch (RemoteException e) {
14244                    // Will time out on the backup manager side
14245                }
14246            } else {
14247                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14248            }
14249            // Invariants: at this point, the target app process exists and the application
14250            // is either already running or in the process of coming up.  mBackupTarget and
14251            // mBackupAppName describe the app, so that when it binds back to the AM we
14252            // know that it's scheduled for a backup-agent operation.
14253        }
14254
14255        return true;
14256    }
14257
14258    @Override
14259    public void clearPendingBackup() {
14260        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14261        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14262
14263        synchronized (this) {
14264            mBackupTarget = null;
14265            mBackupAppName = null;
14266        }
14267    }
14268
14269    // A backup agent has just come up
14270    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14271        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14272                + " = " + agent);
14273
14274        synchronized(this) {
14275            if (!agentPackageName.equals(mBackupAppName)) {
14276                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14277                return;
14278            }
14279        }
14280
14281        long oldIdent = Binder.clearCallingIdentity();
14282        try {
14283            IBackupManager bm = IBackupManager.Stub.asInterface(
14284                    ServiceManager.getService(Context.BACKUP_SERVICE));
14285            bm.agentConnected(agentPackageName, agent);
14286        } catch (RemoteException e) {
14287            // can't happen; the backup manager service is local
14288        } catch (Exception e) {
14289            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14290            e.printStackTrace();
14291        } finally {
14292            Binder.restoreCallingIdentity(oldIdent);
14293        }
14294    }
14295
14296    // done with this agent
14297    public void unbindBackupAgent(ApplicationInfo appInfo) {
14298        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14299        if (appInfo == null) {
14300            Slog.w(TAG, "unbind backup agent for null app");
14301            return;
14302        }
14303
14304        synchronized(this) {
14305            try {
14306                if (mBackupAppName == null) {
14307                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14308                    return;
14309                }
14310
14311                if (!mBackupAppName.equals(appInfo.packageName)) {
14312                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14313                    return;
14314                }
14315
14316                // Not backing this app up any more; reset its OOM adjustment
14317                final ProcessRecord proc = mBackupTarget.app;
14318                updateOomAdjLocked(proc);
14319
14320                // If the app crashed during backup, 'thread' will be null here
14321                if (proc.thread != null) {
14322                    try {
14323                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14324                                compatibilityInfoForPackageLocked(appInfo));
14325                    } catch (Exception e) {
14326                        Slog.e(TAG, "Exception when unbinding backup agent:");
14327                        e.printStackTrace();
14328                    }
14329                }
14330            } finally {
14331                mBackupTarget = null;
14332                mBackupAppName = null;
14333            }
14334        }
14335    }
14336    // =========================================================
14337    // BROADCASTS
14338    // =========================================================
14339
14340    private final List getStickiesLocked(String action, IntentFilter filter,
14341            List cur, int userId) {
14342        final ContentResolver resolver = mContext.getContentResolver();
14343        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14344        if (stickies == null) {
14345            return cur;
14346        }
14347        final ArrayList<Intent> list = stickies.get(action);
14348        if (list == null) {
14349            return cur;
14350        }
14351        int N = list.size();
14352        for (int i=0; i<N; i++) {
14353            Intent intent = list.get(i);
14354            if (filter.match(resolver, intent, true, TAG) >= 0) {
14355                if (cur == null) {
14356                    cur = new ArrayList<Intent>();
14357                }
14358                cur.add(intent);
14359            }
14360        }
14361        return cur;
14362    }
14363
14364    boolean isPendingBroadcastProcessLocked(int pid) {
14365        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14366                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14367    }
14368
14369    void skipPendingBroadcastLocked(int pid) {
14370            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14371            for (BroadcastQueue queue : mBroadcastQueues) {
14372                queue.skipPendingBroadcastLocked(pid);
14373            }
14374    }
14375
14376    // The app just attached; send any pending broadcasts that it should receive
14377    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14378        boolean didSomething = false;
14379        for (BroadcastQueue queue : mBroadcastQueues) {
14380            didSomething |= queue.sendPendingBroadcastsLocked(app);
14381        }
14382        return didSomething;
14383    }
14384
14385    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14386            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14387        enforceNotIsolatedCaller("registerReceiver");
14388        int callingUid;
14389        int callingPid;
14390        synchronized(this) {
14391            ProcessRecord callerApp = null;
14392            if (caller != null) {
14393                callerApp = getRecordForAppLocked(caller);
14394                if (callerApp == null) {
14395                    throw new SecurityException(
14396                            "Unable to find app for caller " + caller
14397                            + " (pid=" + Binder.getCallingPid()
14398                            + ") when registering receiver " + receiver);
14399                }
14400                if (callerApp.info.uid != Process.SYSTEM_UID &&
14401                        !callerApp.pkgList.containsKey(callerPackage) &&
14402                        !"android".equals(callerPackage)) {
14403                    throw new SecurityException("Given caller package " + callerPackage
14404                            + " is not running in process " + callerApp);
14405                }
14406                callingUid = callerApp.info.uid;
14407                callingPid = callerApp.pid;
14408            } else {
14409                callerPackage = null;
14410                callingUid = Binder.getCallingUid();
14411                callingPid = Binder.getCallingPid();
14412            }
14413
14414            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14415                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14416
14417            List allSticky = null;
14418
14419            // Look for any matching sticky broadcasts...
14420            Iterator actions = filter.actionsIterator();
14421            if (actions != null) {
14422                while (actions.hasNext()) {
14423                    String action = (String)actions.next();
14424                    allSticky = getStickiesLocked(action, filter, allSticky,
14425                            UserHandle.USER_ALL);
14426                    allSticky = getStickiesLocked(action, filter, allSticky,
14427                            UserHandle.getUserId(callingUid));
14428                }
14429            } else {
14430                allSticky = getStickiesLocked(null, filter, allSticky,
14431                        UserHandle.USER_ALL);
14432                allSticky = getStickiesLocked(null, filter, allSticky,
14433                        UserHandle.getUserId(callingUid));
14434            }
14435
14436            // The first sticky in the list is returned directly back to
14437            // the client.
14438            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14439
14440            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14441                    + ": " + sticky);
14442
14443            if (receiver == null) {
14444                return sticky;
14445            }
14446
14447            ReceiverList rl
14448                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14449            if (rl == null) {
14450                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14451                        userId, receiver);
14452                if (rl.app != null) {
14453                    rl.app.receivers.add(rl);
14454                } else {
14455                    try {
14456                        receiver.asBinder().linkToDeath(rl, 0);
14457                    } catch (RemoteException e) {
14458                        return sticky;
14459                    }
14460                    rl.linkedToDeath = true;
14461                }
14462                mRegisteredReceivers.put(receiver.asBinder(), rl);
14463            } else if (rl.uid != callingUid) {
14464                throw new IllegalArgumentException(
14465                        "Receiver requested to register for uid " + callingUid
14466                        + " was previously registered for uid " + rl.uid);
14467            } else if (rl.pid != callingPid) {
14468                throw new IllegalArgumentException(
14469                        "Receiver requested to register for pid " + callingPid
14470                        + " was previously registered for pid " + rl.pid);
14471            } else if (rl.userId != userId) {
14472                throw new IllegalArgumentException(
14473                        "Receiver requested to register for user " + userId
14474                        + " was previously registered for user " + rl.userId);
14475            }
14476            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14477                    permission, callingUid, userId);
14478            rl.add(bf);
14479            if (!bf.debugCheck()) {
14480                Slog.w(TAG, "==> For Dynamic broadast");
14481            }
14482            mReceiverResolver.addFilter(bf);
14483
14484            // Enqueue broadcasts for all existing stickies that match
14485            // this filter.
14486            if (allSticky != null) {
14487                ArrayList receivers = new ArrayList();
14488                receivers.add(bf);
14489
14490                int N = allSticky.size();
14491                for (int i=0; i<N; i++) {
14492                    Intent intent = (Intent)allSticky.get(i);
14493                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14494                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14495                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14496                            null, null, false, true, true, -1);
14497                    queue.enqueueParallelBroadcastLocked(r);
14498                    queue.scheduleBroadcastsLocked();
14499                }
14500            }
14501
14502            return sticky;
14503        }
14504    }
14505
14506    public void unregisterReceiver(IIntentReceiver receiver) {
14507        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14508
14509        final long origId = Binder.clearCallingIdentity();
14510        try {
14511            boolean doTrim = false;
14512
14513            synchronized(this) {
14514                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14515                if (rl != null) {
14516                    if (rl.curBroadcast != null) {
14517                        BroadcastRecord r = rl.curBroadcast;
14518                        final boolean doNext = finishReceiverLocked(
14519                                receiver.asBinder(), r.resultCode, r.resultData,
14520                                r.resultExtras, r.resultAbort);
14521                        if (doNext) {
14522                            doTrim = true;
14523                            r.queue.processNextBroadcast(false);
14524                        }
14525                    }
14526
14527                    if (rl.app != null) {
14528                        rl.app.receivers.remove(rl);
14529                    }
14530                    removeReceiverLocked(rl);
14531                    if (rl.linkedToDeath) {
14532                        rl.linkedToDeath = false;
14533                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14534                    }
14535                }
14536            }
14537
14538            // If we actually concluded any broadcasts, we might now be able
14539            // to trim the recipients' apps from our working set
14540            if (doTrim) {
14541                trimApplications();
14542                return;
14543            }
14544
14545        } finally {
14546            Binder.restoreCallingIdentity(origId);
14547        }
14548    }
14549
14550    void removeReceiverLocked(ReceiverList rl) {
14551        mRegisteredReceivers.remove(rl.receiver.asBinder());
14552        int N = rl.size();
14553        for (int i=0; i<N; i++) {
14554            mReceiverResolver.removeFilter(rl.get(i));
14555        }
14556    }
14557
14558    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14559        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14560            ProcessRecord r = mLruProcesses.get(i);
14561            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14562                try {
14563                    r.thread.dispatchPackageBroadcast(cmd, packages);
14564                } catch (RemoteException ex) {
14565                }
14566            }
14567        }
14568    }
14569
14570    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14571            int[] users) {
14572        List<ResolveInfo> receivers = null;
14573        try {
14574            HashSet<ComponentName> singleUserReceivers = null;
14575            boolean scannedFirstReceivers = false;
14576            for (int user : users) {
14577                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14578                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14579                if (user != 0 && newReceivers != null) {
14580                    // If this is not the primary user, we need to check for
14581                    // any receivers that should be filtered out.
14582                    for (int i=0; i<newReceivers.size(); i++) {
14583                        ResolveInfo ri = newReceivers.get(i);
14584                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14585                            newReceivers.remove(i);
14586                            i--;
14587                        }
14588                    }
14589                }
14590                if (newReceivers != null && newReceivers.size() == 0) {
14591                    newReceivers = null;
14592                }
14593                if (receivers == null) {
14594                    receivers = newReceivers;
14595                } else if (newReceivers != null) {
14596                    // We need to concatenate the additional receivers
14597                    // found with what we have do far.  This would be easy,
14598                    // but we also need to de-dup any receivers that are
14599                    // singleUser.
14600                    if (!scannedFirstReceivers) {
14601                        // Collect any single user receivers we had already retrieved.
14602                        scannedFirstReceivers = true;
14603                        for (int i=0; i<receivers.size(); i++) {
14604                            ResolveInfo ri = receivers.get(i);
14605                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14606                                ComponentName cn = new ComponentName(
14607                                        ri.activityInfo.packageName, ri.activityInfo.name);
14608                                if (singleUserReceivers == null) {
14609                                    singleUserReceivers = new HashSet<ComponentName>();
14610                                }
14611                                singleUserReceivers.add(cn);
14612                            }
14613                        }
14614                    }
14615                    // Add the new results to the existing results, tracking
14616                    // and de-dupping single user receivers.
14617                    for (int i=0; i<newReceivers.size(); i++) {
14618                        ResolveInfo ri = newReceivers.get(i);
14619                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14620                            ComponentName cn = new ComponentName(
14621                                    ri.activityInfo.packageName, ri.activityInfo.name);
14622                            if (singleUserReceivers == null) {
14623                                singleUserReceivers = new HashSet<ComponentName>();
14624                            }
14625                            if (!singleUserReceivers.contains(cn)) {
14626                                singleUserReceivers.add(cn);
14627                                receivers.add(ri);
14628                            }
14629                        } else {
14630                            receivers.add(ri);
14631                        }
14632                    }
14633                }
14634            }
14635        } catch (RemoteException ex) {
14636            // pm is in same process, this will never happen.
14637        }
14638        return receivers;
14639    }
14640
14641    private final int broadcastIntentLocked(ProcessRecord callerApp,
14642            String callerPackage, Intent intent, String resolvedType,
14643            IIntentReceiver resultTo, int resultCode, String resultData,
14644            Bundle map, String requiredPermission, int appOp,
14645            boolean ordered, boolean sticky, int callingPid, int callingUid,
14646            int userId) {
14647        intent = new Intent(intent);
14648
14649        // By default broadcasts do not go to stopped apps.
14650        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14651
14652        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14653            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14654            + " ordered=" + ordered + " userid=" + userId);
14655        if ((resultTo != null) && !ordered) {
14656            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14657        }
14658
14659        userId = handleIncomingUser(callingPid, callingUid, userId,
14660                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14661
14662        // Make sure that the user who is receiving this broadcast is started.
14663        // If not, we will just skip it.
14664
14665
14666        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14667            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14668                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14669                Slog.w(TAG, "Skipping broadcast of " + intent
14670                        + ": user " + userId + " is stopped");
14671                return ActivityManager.BROADCAST_SUCCESS;
14672            }
14673        }
14674
14675        /*
14676         * Prevent non-system code (defined here to be non-persistent
14677         * processes) from sending protected broadcasts.
14678         */
14679        int callingAppId = UserHandle.getAppId(callingUid);
14680        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14681            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14682            || callingAppId == Process.NFC_UID || callingUid == 0) {
14683            // Always okay.
14684        } else if (callerApp == null || !callerApp.persistent) {
14685            try {
14686                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14687                        intent.getAction())) {
14688                    String msg = "Permission Denial: not allowed to send broadcast "
14689                            + intent.getAction() + " from pid="
14690                            + callingPid + ", uid=" + callingUid;
14691                    Slog.w(TAG, msg);
14692                    throw new SecurityException(msg);
14693                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14694                    // Special case for compatibility: we don't want apps to send this,
14695                    // but historically it has not been protected and apps may be using it
14696                    // to poke their own app widget.  So, instead of making it protected,
14697                    // just limit it to the caller.
14698                    if (callerApp == null) {
14699                        String msg = "Permission Denial: not allowed to send broadcast "
14700                                + intent.getAction() + " from unknown caller.";
14701                        Slog.w(TAG, msg);
14702                        throw new SecurityException(msg);
14703                    } else if (intent.getComponent() != null) {
14704                        // They are good enough to send to an explicit component...  verify
14705                        // it is being sent to the calling app.
14706                        if (!intent.getComponent().getPackageName().equals(
14707                                callerApp.info.packageName)) {
14708                            String msg = "Permission Denial: not allowed to send broadcast "
14709                                    + intent.getAction() + " to "
14710                                    + intent.getComponent().getPackageName() + " from "
14711                                    + callerApp.info.packageName;
14712                            Slog.w(TAG, msg);
14713                            throw new SecurityException(msg);
14714                        }
14715                    } else {
14716                        // Limit broadcast to their own package.
14717                        intent.setPackage(callerApp.info.packageName);
14718                    }
14719                }
14720            } catch (RemoteException e) {
14721                Slog.w(TAG, "Remote exception", e);
14722                return ActivityManager.BROADCAST_SUCCESS;
14723            }
14724        }
14725
14726        // Handle special intents: if this broadcast is from the package
14727        // manager about a package being removed, we need to remove all of
14728        // its activities from the history stack.
14729        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14730                intent.getAction());
14731        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14732                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14733                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14734                || uidRemoved) {
14735            if (checkComponentPermission(
14736                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14737                    callingPid, callingUid, -1, true)
14738                    == PackageManager.PERMISSION_GRANTED) {
14739                if (uidRemoved) {
14740                    final Bundle intentExtras = intent.getExtras();
14741                    final int uid = intentExtras != null
14742                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14743                    if (uid >= 0) {
14744                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14745                        synchronized (bs) {
14746                            bs.removeUidStatsLocked(uid);
14747                        }
14748                        mAppOpsService.uidRemoved(uid);
14749                    }
14750                } else {
14751                    // If resources are unavailable just force stop all
14752                    // those packages and flush the attribute cache as well.
14753                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14754                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14755                        if (list != null && (list.length > 0)) {
14756                            for (String pkg : list) {
14757                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14758                                        "storage unmount");
14759                            }
14760                            sendPackageBroadcastLocked(
14761                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14762                        }
14763                    } else {
14764                        Uri data = intent.getData();
14765                        String ssp;
14766                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14767                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14768                                    intent.getAction());
14769                            boolean fullUninstall = removed &&
14770                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14771                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14772                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14773                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14774                                        false, fullUninstall, userId,
14775                                        removed ? "pkg removed" : "pkg changed");
14776                            }
14777                            if (removed) {
14778                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14779                                        new String[] {ssp}, userId);
14780                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14781                                    mAppOpsService.packageRemoved(
14782                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14783
14784                                    // Remove all permissions granted from/to this package
14785                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14786                                }
14787                            }
14788                        }
14789                    }
14790                }
14791            } else {
14792                String msg = "Permission Denial: " + intent.getAction()
14793                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14794                        + ", uid=" + callingUid + ")"
14795                        + " requires "
14796                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14797                Slog.w(TAG, msg);
14798                throw new SecurityException(msg);
14799            }
14800
14801        // Special case for adding a package: by default turn on compatibility
14802        // mode.
14803        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14804            Uri data = intent.getData();
14805            String ssp;
14806            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14807                mCompatModePackages.handlePackageAddedLocked(ssp,
14808                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14809            }
14810        }
14811
14812        /*
14813         * If this is the time zone changed action, queue up a message that will reset the timezone
14814         * of all currently running processes. This message will get queued up before the broadcast
14815         * happens.
14816         */
14817        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14818            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14819        }
14820
14821        /*
14822         * If the user set the time, let all running processes know.
14823         */
14824        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14825            final int is24Hour = intent.getBooleanExtra(
14826                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14827            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14828        }
14829
14830        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14831            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14832        }
14833
14834        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14835            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14836            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14837        }
14838
14839        // Add to the sticky list if requested.
14840        if (sticky) {
14841            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14842                    callingPid, callingUid)
14843                    != PackageManager.PERMISSION_GRANTED) {
14844                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14845                        + callingPid + ", uid=" + callingUid
14846                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14847                Slog.w(TAG, msg);
14848                throw new SecurityException(msg);
14849            }
14850            if (requiredPermission != null) {
14851                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14852                        + " and enforce permission " + requiredPermission);
14853                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14854            }
14855            if (intent.getComponent() != null) {
14856                throw new SecurityException(
14857                        "Sticky broadcasts can't target a specific component");
14858            }
14859            // We use userId directly here, since the "all" target is maintained
14860            // as a separate set of sticky broadcasts.
14861            if (userId != UserHandle.USER_ALL) {
14862                // But first, if this is not a broadcast to all users, then
14863                // make sure it doesn't conflict with an existing broadcast to
14864                // all users.
14865                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14866                        UserHandle.USER_ALL);
14867                if (stickies != null) {
14868                    ArrayList<Intent> list = stickies.get(intent.getAction());
14869                    if (list != null) {
14870                        int N = list.size();
14871                        int i;
14872                        for (i=0; i<N; i++) {
14873                            if (intent.filterEquals(list.get(i))) {
14874                                throw new IllegalArgumentException(
14875                                        "Sticky broadcast " + intent + " for user "
14876                                        + userId + " conflicts with existing global broadcast");
14877                            }
14878                        }
14879                    }
14880                }
14881            }
14882            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14883            if (stickies == null) {
14884                stickies = new ArrayMap<String, ArrayList<Intent>>();
14885                mStickyBroadcasts.put(userId, stickies);
14886            }
14887            ArrayList<Intent> list = stickies.get(intent.getAction());
14888            if (list == null) {
14889                list = new ArrayList<Intent>();
14890                stickies.put(intent.getAction(), list);
14891            }
14892            int N = list.size();
14893            int i;
14894            for (i=0; i<N; i++) {
14895                if (intent.filterEquals(list.get(i))) {
14896                    // This sticky already exists, replace it.
14897                    list.set(i, new Intent(intent));
14898                    break;
14899                }
14900            }
14901            if (i >= N) {
14902                list.add(new Intent(intent));
14903            }
14904        }
14905
14906        int[] users;
14907        if (userId == UserHandle.USER_ALL) {
14908            // Caller wants broadcast to go to all started users.
14909            users = mStartedUserArray;
14910        } else {
14911            // Caller wants broadcast to go to one specific user.
14912            users = new int[] {userId};
14913        }
14914
14915        // Figure out who all will receive this broadcast.
14916        List receivers = null;
14917        List<BroadcastFilter> registeredReceivers = null;
14918        // Need to resolve the intent to interested receivers...
14919        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14920                 == 0) {
14921            receivers = collectReceiverComponents(intent, resolvedType, users);
14922        }
14923        if (intent.getComponent() == null) {
14924            registeredReceivers = mReceiverResolver.queryIntent(intent,
14925                    resolvedType, false, userId);
14926        }
14927
14928        final boolean replacePending =
14929                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14930
14931        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14932                + " replacePending=" + replacePending);
14933
14934        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14935        if (!ordered && NR > 0) {
14936            // If we are not serializing this broadcast, then send the
14937            // registered receivers separately so they don't wait for the
14938            // components to be launched.
14939            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14940            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14941                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14942                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14943                    ordered, sticky, false, userId);
14944            if (DEBUG_BROADCAST) Slog.v(
14945                    TAG, "Enqueueing parallel broadcast " + r);
14946            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14947            if (!replaced) {
14948                queue.enqueueParallelBroadcastLocked(r);
14949                queue.scheduleBroadcastsLocked();
14950            }
14951            registeredReceivers = null;
14952            NR = 0;
14953        }
14954
14955        // Merge into one list.
14956        int ir = 0;
14957        if (receivers != null) {
14958            // A special case for PACKAGE_ADDED: do not allow the package
14959            // being added to see this broadcast.  This prevents them from
14960            // using this as a back door to get run as soon as they are
14961            // installed.  Maybe in the future we want to have a special install
14962            // broadcast or such for apps, but we'd like to deliberately make
14963            // this decision.
14964            String skipPackages[] = null;
14965            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14966                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14967                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14968                Uri data = intent.getData();
14969                if (data != null) {
14970                    String pkgName = data.getSchemeSpecificPart();
14971                    if (pkgName != null) {
14972                        skipPackages = new String[] { pkgName };
14973                    }
14974                }
14975            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14976                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14977            }
14978            if (skipPackages != null && (skipPackages.length > 0)) {
14979                for (String skipPackage : skipPackages) {
14980                    if (skipPackage != null) {
14981                        int NT = receivers.size();
14982                        for (int it=0; it<NT; it++) {
14983                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14984                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14985                                receivers.remove(it);
14986                                it--;
14987                                NT--;
14988                            }
14989                        }
14990                    }
14991                }
14992            }
14993
14994            int NT = receivers != null ? receivers.size() : 0;
14995            int it = 0;
14996            ResolveInfo curt = null;
14997            BroadcastFilter curr = null;
14998            while (it < NT && ir < NR) {
14999                if (curt == null) {
15000                    curt = (ResolveInfo)receivers.get(it);
15001                }
15002                if (curr == null) {
15003                    curr = registeredReceivers.get(ir);
15004                }
15005                if (curr.getPriority() >= curt.priority) {
15006                    // Insert this broadcast record into the final list.
15007                    receivers.add(it, curr);
15008                    ir++;
15009                    curr = null;
15010                    it++;
15011                    NT++;
15012                } else {
15013                    // Skip to the next ResolveInfo in the final list.
15014                    it++;
15015                    curt = null;
15016                }
15017            }
15018        }
15019        while (ir < NR) {
15020            if (receivers == null) {
15021                receivers = new ArrayList();
15022            }
15023            receivers.add(registeredReceivers.get(ir));
15024            ir++;
15025        }
15026
15027        if ((receivers != null && receivers.size() > 0)
15028                || resultTo != null) {
15029            BroadcastQueue queue = broadcastQueueForIntent(intent);
15030            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15031                    callerPackage, callingPid, callingUid, resolvedType,
15032                    requiredPermission, appOp, receivers, resultTo, resultCode,
15033                    resultData, map, ordered, sticky, false, userId);
15034            if (DEBUG_BROADCAST) Slog.v(
15035                    TAG, "Enqueueing ordered broadcast " + r
15036                    + ": prev had " + queue.mOrderedBroadcasts.size());
15037            if (DEBUG_BROADCAST) {
15038                int seq = r.intent.getIntExtra("seq", -1);
15039                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15040            }
15041            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15042            if (!replaced) {
15043                queue.enqueueOrderedBroadcastLocked(r);
15044                queue.scheduleBroadcastsLocked();
15045            }
15046        }
15047
15048        return ActivityManager.BROADCAST_SUCCESS;
15049    }
15050
15051    final Intent verifyBroadcastLocked(Intent intent) {
15052        // Refuse possible leaked file descriptors
15053        if (intent != null && intent.hasFileDescriptors() == true) {
15054            throw new IllegalArgumentException("File descriptors passed in Intent");
15055        }
15056
15057        int flags = intent.getFlags();
15058
15059        if (!mProcessesReady) {
15060            // if the caller really truly claims to know what they're doing, go
15061            // ahead and allow the broadcast without launching any receivers
15062            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15063                intent = new Intent(intent);
15064                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15065            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15066                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15067                        + " before boot completion");
15068                throw new IllegalStateException("Cannot broadcast before boot completed");
15069            }
15070        }
15071
15072        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15073            throw new IllegalArgumentException(
15074                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15075        }
15076
15077        return intent;
15078    }
15079
15080    public final int broadcastIntent(IApplicationThread caller,
15081            Intent intent, String resolvedType, IIntentReceiver resultTo,
15082            int resultCode, String resultData, Bundle map,
15083            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15084        enforceNotIsolatedCaller("broadcastIntent");
15085        synchronized(this) {
15086            intent = verifyBroadcastLocked(intent);
15087
15088            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15089            final int callingPid = Binder.getCallingPid();
15090            final int callingUid = Binder.getCallingUid();
15091            final long origId = Binder.clearCallingIdentity();
15092            int res = broadcastIntentLocked(callerApp,
15093                    callerApp != null ? callerApp.info.packageName : null,
15094                    intent, resolvedType, resultTo,
15095                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15096                    callingPid, callingUid, userId);
15097            Binder.restoreCallingIdentity(origId);
15098            return res;
15099        }
15100    }
15101
15102    int broadcastIntentInPackage(String packageName, int uid,
15103            Intent intent, String resolvedType, IIntentReceiver resultTo,
15104            int resultCode, String resultData, Bundle map,
15105            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15106        synchronized(this) {
15107            intent = verifyBroadcastLocked(intent);
15108
15109            final long origId = Binder.clearCallingIdentity();
15110            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15111                    resultTo, resultCode, resultData, map, requiredPermission,
15112                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15113            Binder.restoreCallingIdentity(origId);
15114            return res;
15115        }
15116    }
15117
15118    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15119        // Refuse possible leaked file descriptors
15120        if (intent != null && intent.hasFileDescriptors() == true) {
15121            throw new IllegalArgumentException("File descriptors passed in Intent");
15122        }
15123
15124        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15125                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15126
15127        synchronized(this) {
15128            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15129                    != PackageManager.PERMISSION_GRANTED) {
15130                String msg = "Permission Denial: unbroadcastIntent() from pid="
15131                        + Binder.getCallingPid()
15132                        + ", uid=" + Binder.getCallingUid()
15133                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15134                Slog.w(TAG, msg);
15135                throw new SecurityException(msg);
15136            }
15137            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15138            if (stickies != null) {
15139                ArrayList<Intent> list = stickies.get(intent.getAction());
15140                if (list != null) {
15141                    int N = list.size();
15142                    int i;
15143                    for (i=0; i<N; i++) {
15144                        if (intent.filterEquals(list.get(i))) {
15145                            list.remove(i);
15146                            break;
15147                        }
15148                    }
15149                    if (list.size() <= 0) {
15150                        stickies.remove(intent.getAction());
15151                    }
15152                }
15153                if (stickies.size() <= 0) {
15154                    mStickyBroadcasts.remove(userId);
15155                }
15156            }
15157        }
15158    }
15159
15160    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15161            String resultData, Bundle resultExtras, boolean resultAbort) {
15162        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15163        if (r == null) {
15164            Slog.w(TAG, "finishReceiver called but not found on queue");
15165            return false;
15166        }
15167
15168        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15169    }
15170
15171    void backgroundServicesFinishedLocked(int userId) {
15172        for (BroadcastQueue queue : mBroadcastQueues) {
15173            queue.backgroundServicesFinishedLocked(userId);
15174        }
15175    }
15176
15177    public void finishReceiver(IBinder who, int resultCode, String resultData,
15178            Bundle resultExtras, boolean resultAbort) {
15179        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15180
15181        // Refuse possible leaked file descriptors
15182        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15183            throw new IllegalArgumentException("File descriptors passed in Bundle");
15184        }
15185
15186        final long origId = Binder.clearCallingIdentity();
15187        try {
15188            boolean doNext = false;
15189            BroadcastRecord r;
15190
15191            synchronized(this) {
15192                r = broadcastRecordForReceiverLocked(who);
15193                if (r != null) {
15194                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15195                        resultData, resultExtras, resultAbort, true);
15196                }
15197            }
15198
15199            if (doNext) {
15200                r.queue.processNextBroadcast(false);
15201            }
15202            trimApplications();
15203        } finally {
15204            Binder.restoreCallingIdentity(origId);
15205        }
15206    }
15207
15208    // =========================================================
15209    // INSTRUMENTATION
15210    // =========================================================
15211
15212    public boolean startInstrumentation(ComponentName className,
15213            String profileFile, int flags, Bundle arguments,
15214            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15215            int userId, String abiOverride) {
15216        enforceNotIsolatedCaller("startInstrumentation");
15217        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15218                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15219        // Refuse possible leaked file descriptors
15220        if (arguments != null && arguments.hasFileDescriptors()) {
15221            throw new IllegalArgumentException("File descriptors passed in Bundle");
15222        }
15223
15224        synchronized(this) {
15225            InstrumentationInfo ii = null;
15226            ApplicationInfo ai = null;
15227            try {
15228                ii = mContext.getPackageManager().getInstrumentationInfo(
15229                    className, STOCK_PM_FLAGS);
15230                ai = AppGlobals.getPackageManager().getApplicationInfo(
15231                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15232            } catch (PackageManager.NameNotFoundException e) {
15233            } catch (RemoteException e) {
15234            }
15235            if (ii == null) {
15236                reportStartInstrumentationFailure(watcher, className,
15237                        "Unable to find instrumentation info for: " + className);
15238                return false;
15239            }
15240            if (ai == null) {
15241                reportStartInstrumentationFailure(watcher, className,
15242                        "Unable to find instrumentation target package: " + ii.targetPackage);
15243                return false;
15244            }
15245
15246            int match = mContext.getPackageManager().checkSignatures(
15247                    ii.targetPackage, ii.packageName);
15248            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15249                String msg = "Permission Denial: starting instrumentation "
15250                        + className + " from pid="
15251                        + Binder.getCallingPid()
15252                        + ", uid=" + Binder.getCallingPid()
15253                        + " not allowed because package " + ii.packageName
15254                        + " does not have a signature matching the target "
15255                        + ii.targetPackage;
15256                reportStartInstrumentationFailure(watcher, className, msg);
15257                throw new SecurityException(msg);
15258            }
15259
15260            final long origId = Binder.clearCallingIdentity();
15261            // Instrumentation can kill and relaunch even persistent processes
15262            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15263                    "start instr");
15264            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15265            app.instrumentationClass = className;
15266            app.instrumentationInfo = ai;
15267            app.instrumentationProfileFile = profileFile;
15268            app.instrumentationArguments = arguments;
15269            app.instrumentationWatcher = watcher;
15270            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15271            app.instrumentationResultClass = className;
15272            Binder.restoreCallingIdentity(origId);
15273        }
15274
15275        return true;
15276    }
15277
15278    /**
15279     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15280     * error to the logs, but if somebody is watching, send the report there too.  This enables
15281     * the "am" command to report errors with more information.
15282     *
15283     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15284     * @param cn The component name of the instrumentation.
15285     * @param report The error report.
15286     */
15287    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15288            ComponentName cn, String report) {
15289        Slog.w(TAG, report);
15290        try {
15291            if (watcher != null) {
15292                Bundle results = new Bundle();
15293                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15294                results.putString("Error", report);
15295                watcher.instrumentationStatus(cn, -1, results);
15296            }
15297        } catch (RemoteException e) {
15298            Slog.w(TAG, e);
15299        }
15300    }
15301
15302    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15303        if (app.instrumentationWatcher != null) {
15304            try {
15305                // NOTE:  IInstrumentationWatcher *must* be oneway here
15306                app.instrumentationWatcher.instrumentationFinished(
15307                    app.instrumentationClass,
15308                    resultCode,
15309                    results);
15310            } catch (RemoteException e) {
15311            }
15312        }
15313        if (app.instrumentationUiAutomationConnection != null) {
15314            try {
15315                app.instrumentationUiAutomationConnection.shutdown();
15316            } catch (RemoteException re) {
15317                /* ignore */
15318            }
15319            // Only a UiAutomation can set this flag and now that
15320            // it is finished we make sure it is reset to its default.
15321            mUserIsMonkey = false;
15322        }
15323        app.instrumentationWatcher = null;
15324        app.instrumentationUiAutomationConnection = null;
15325        app.instrumentationClass = null;
15326        app.instrumentationInfo = null;
15327        app.instrumentationProfileFile = null;
15328        app.instrumentationArguments = null;
15329
15330        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15331                "finished inst");
15332    }
15333
15334    public void finishInstrumentation(IApplicationThread target,
15335            int resultCode, Bundle results) {
15336        int userId = UserHandle.getCallingUserId();
15337        // Refuse possible leaked file descriptors
15338        if (results != null && results.hasFileDescriptors()) {
15339            throw new IllegalArgumentException("File descriptors passed in Intent");
15340        }
15341
15342        synchronized(this) {
15343            ProcessRecord app = getRecordForAppLocked(target);
15344            if (app == null) {
15345                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15346                return;
15347            }
15348            final long origId = Binder.clearCallingIdentity();
15349            finishInstrumentationLocked(app, resultCode, results);
15350            Binder.restoreCallingIdentity(origId);
15351        }
15352    }
15353
15354    // =========================================================
15355    // CONFIGURATION
15356    // =========================================================
15357
15358    public ConfigurationInfo getDeviceConfigurationInfo() {
15359        ConfigurationInfo config = new ConfigurationInfo();
15360        synchronized (this) {
15361            config.reqTouchScreen = mConfiguration.touchscreen;
15362            config.reqKeyboardType = mConfiguration.keyboard;
15363            config.reqNavigation = mConfiguration.navigation;
15364            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15365                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15366                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15367            }
15368            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15369                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15370                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15371            }
15372            config.reqGlEsVersion = GL_ES_VERSION;
15373        }
15374        return config;
15375    }
15376
15377    ActivityStack getFocusedStack() {
15378        return mStackSupervisor.getFocusedStack();
15379    }
15380
15381    public Configuration getConfiguration() {
15382        Configuration ci;
15383        synchronized(this) {
15384            ci = new Configuration(mConfiguration);
15385        }
15386        return ci;
15387    }
15388
15389    public void updatePersistentConfiguration(Configuration values) {
15390        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15391                "updateConfiguration()");
15392        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15393                "updateConfiguration()");
15394        if (values == null) {
15395            throw new NullPointerException("Configuration must not be null");
15396        }
15397
15398        synchronized(this) {
15399            final long origId = Binder.clearCallingIdentity();
15400            updateConfigurationLocked(values, null, true, false);
15401            Binder.restoreCallingIdentity(origId);
15402        }
15403    }
15404
15405    public void updateConfiguration(Configuration values) {
15406        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15407                "updateConfiguration()");
15408
15409        synchronized(this) {
15410            if (values == null && mWindowManager != null) {
15411                // sentinel: fetch the current configuration from the window manager
15412                values = mWindowManager.computeNewConfiguration();
15413            }
15414
15415            if (mWindowManager != null) {
15416                mProcessList.applyDisplaySize(mWindowManager);
15417            }
15418
15419            final long origId = Binder.clearCallingIdentity();
15420            if (values != null) {
15421                Settings.System.clearConfiguration(values);
15422            }
15423            updateConfigurationLocked(values, null, false, false);
15424            Binder.restoreCallingIdentity(origId);
15425        }
15426    }
15427
15428    /**
15429     * Do either or both things: (1) change the current configuration, and (2)
15430     * make sure the given activity is running with the (now) current
15431     * configuration.  Returns true if the activity has been left running, or
15432     * false if <var>starting</var> is being destroyed to match the new
15433     * configuration.
15434     * @param persistent TODO
15435     */
15436    boolean updateConfigurationLocked(Configuration values,
15437            ActivityRecord starting, boolean persistent, boolean initLocale) {
15438        int changes = 0;
15439
15440        if (values != null) {
15441            Configuration newConfig = new Configuration(mConfiguration);
15442            changes = newConfig.updateFrom(values);
15443            if (changes != 0) {
15444                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15445                    Slog.i(TAG, "Updating configuration to: " + values);
15446                }
15447
15448                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15449
15450                if (values.locale != null && !initLocale) {
15451                    saveLocaleLocked(values.locale,
15452                                     !values.locale.equals(mConfiguration.locale),
15453                                     values.userSetLocale);
15454                }
15455
15456                mConfigurationSeq++;
15457                if (mConfigurationSeq <= 0) {
15458                    mConfigurationSeq = 1;
15459                }
15460                newConfig.seq = mConfigurationSeq;
15461                mConfiguration = newConfig;
15462                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15463                //mUsageStatsService.noteStartConfig(newConfig);
15464
15465                final Configuration configCopy = new Configuration(mConfiguration);
15466
15467                // TODO: If our config changes, should we auto dismiss any currently
15468                // showing dialogs?
15469                mShowDialogs = shouldShowDialogs(newConfig);
15470
15471                AttributeCache ac = AttributeCache.instance();
15472                if (ac != null) {
15473                    ac.updateConfiguration(configCopy);
15474                }
15475
15476                // Make sure all resources in our process are updated
15477                // right now, so that anyone who is going to retrieve
15478                // resource values after we return will be sure to get
15479                // the new ones.  This is especially important during
15480                // boot, where the first config change needs to guarantee
15481                // all resources have that config before following boot
15482                // code is executed.
15483                mSystemThread.applyConfigurationToResources(configCopy);
15484
15485                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15486                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15487                    msg.obj = new Configuration(configCopy);
15488                    mHandler.sendMessage(msg);
15489                }
15490
15491                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15492                    ProcessRecord app = mLruProcesses.get(i);
15493                    try {
15494                        if (app.thread != null) {
15495                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15496                                    + app.processName + " new config " + mConfiguration);
15497                            app.thread.scheduleConfigurationChanged(configCopy);
15498                        }
15499                    } catch (Exception e) {
15500                    }
15501                }
15502                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15503                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15504                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15505                        | Intent.FLAG_RECEIVER_FOREGROUND);
15506                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15507                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15508                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15509                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15510                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15511                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15512                    broadcastIntentLocked(null, null, intent,
15513                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15514                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15515                }
15516            }
15517        }
15518
15519        boolean kept = true;
15520        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15521        // mainStack is null during startup.
15522        if (mainStack != null) {
15523            if (changes != 0 && starting == null) {
15524                // If the configuration changed, and the caller is not already
15525                // in the process of starting an activity, then find the top
15526                // activity to check if its configuration needs to change.
15527                starting = mainStack.topRunningActivityLocked(null);
15528            }
15529
15530            if (starting != null) {
15531                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15532                // And we need to make sure at this point that all other activities
15533                // are made visible with the correct configuration.
15534                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15535            }
15536        }
15537
15538        if (values != null && mWindowManager != null) {
15539            mWindowManager.setNewConfiguration(mConfiguration);
15540        }
15541
15542        return kept;
15543    }
15544
15545    /**
15546     * Decide based on the configuration whether we should shouw the ANR,
15547     * crash, etc dialogs.  The idea is that if there is no affordnace to
15548     * press the on-screen buttons, we shouldn't show the dialog.
15549     *
15550     * A thought: SystemUI might also want to get told about this, the Power
15551     * dialog / global actions also might want different behaviors.
15552     */
15553    private static final boolean shouldShowDialogs(Configuration config) {
15554        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15555                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15556    }
15557
15558    /**
15559     * Save the locale.  You must be inside a synchronized (this) block.
15560     */
15561    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15562        if(isDiff) {
15563            SystemProperties.set("user.language", l.getLanguage());
15564            SystemProperties.set("user.region", l.getCountry());
15565        }
15566
15567        if(isPersist) {
15568            SystemProperties.set("persist.sys.language", l.getLanguage());
15569            SystemProperties.set("persist.sys.country", l.getCountry());
15570            SystemProperties.set("persist.sys.localevar", l.getVariant());
15571        }
15572    }
15573
15574    @Override
15575    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15576        ActivityRecord srec = ActivityRecord.forToken(token);
15577        return srec != null && srec.task.affinity != null &&
15578                srec.task.affinity.equals(destAffinity);
15579    }
15580
15581    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15582            Intent resultData) {
15583
15584        synchronized (this) {
15585            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15586            if (stack != null) {
15587                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15588            }
15589            return false;
15590        }
15591    }
15592
15593    public int getLaunchedFromUid(IBinder activityToken) {
15594        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15595        if (srec == null) {
15596            return -1;
15597        }
15598        return srec.launchedFromUid;
15599    }
15600
15601    public String getLaunchedFromPackage(IBinder activityToken) {
15602        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15603        if (srec == null) {
15604            return null;
15605        }
15606        return srec.launchedFromPackage;
15607    }
15608
15609    // =========================================================
15610    // LIFETIME MANAGEMENT
15611    // =========================================================
15612
15613    // Returns which broadcast queue the app is the current [or imminent] receiver
15614    // on, or 'null' if the app is not an active broadcast recipient.
15615    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15616        BroadcastRecord r = app.curReceiver;
15617        if (r != null) {
15618            return r.queue;
15619        }
15620
15621        // It's not the current receiver, but it might be starting up to become one
15622        synchronized (this) {
15623            for (BroadcastQueue queue : mBroadcastQueues) {
15624                r = queue.mPendingBroadcast;
15625                if (r != null && r.curApp == app) {
15626                    // found it; report which queue it's in
15627                    return queue;
15628                }
15629            }
15630        }
15631
15632        return null;
15633    }
15634
15635    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15636            boolean doingAll, long now) {
15637        if (mAdjSeq == app.adjSeq) {
15638            // This adjustment has already been computed.
15639            return app.curRawAdj;
15640        }
15641
15642        if (app.thread == null) {
15643            app.adjSeq = mAdjSeq;
15644            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15645            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15646            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15647        }
15648
15649        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15650        app.adjSource = null;
15651        app.adjTarget = null;
15652        app.empty = false;
15653        app.cached = false;
15654
15655        final int activitiesSize = app.activities.size();
15656
15657        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15658            // The max adjustment doesn't allow this app to be anything
15659            // below foreground, so it is not worth doing work for it.
15660            app.adjType = "fixed";
15661            app.adjSeq = mAdjSeq;
15662            app.curRawAdj = app.maxAdj;
15663            app.foregroundActivities = false;
15664            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15665            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15666            // System processes can do UI, and when they do we want to have
15667            // them trim their memory after the user leaves the UI.  To
15668            // facilitate this, here we need to determine whether or not it
15669            // is currently showing UI.
15670            app.systemNoUi = true;
15671            if (app == TOP_APP) {
15672                app.systemNoUi = false;
15673            } else if (activitiesSize > 0) {
15674                for (int j = 0; j < activitiesSize; j++) {
15675                    final ActivityRecord r = app.activities.get(j);
15676                    if (r.visible) {
15677                        app.systemNoUi = false;
15678                    }
15679                }
15680            }
15681            if (!app.systemNoUi) {
15682                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15683            }
15684            return (app.curAdj=app.maxAdj);
15685        }
15686
15687        app.systemNoUi = false;
15688
15689        // Determine the importance of the process, starting with most
15690        // important to least, and assign an appropriate OOM adjustment.
15691        int adj;
15692        int schedGroup;
15693        int procState;
15694        boolean foregroundActivities = false;
15695        BroadcastQueue queue;
15696        if (app == TOP_APP) {
15697            // The last app on the list is the foreground app.
15698            adj = ProcessList.FOREGROUND_APP_ADJ;
15699            schedGroup = Process.THREAD_GROUP_DEFAULT;
15700            app.adjType = "top-activity";
15701            foregroundActivities = true;
15702            procState = ActivityManager.PROCESS_STATE_TOP;
15703        } else if (app.instrumentationClass != null) {
15704            // Don't want to kill running instrumentation.
15705            adj = ProcessList.FOREGROUND_APP_ADJ;
15706            schedGroup = Process.THREAD_GROUP_DEFAULT;
15707            app.adjType = "instrumentation";
15708            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15709        } else if ((queue = isReceivingBroadcast(app)) != null) {
15710            // An app that is currently receiving a broadcast also
15711            // counts as being in the foreground for OOM killer purposes.
15712            // It's placed in a sched group based on the nature of the
15713            // broadcast as reflected by which queue it's active in.
15714            adj = ProcessList.FOREGROUND_APP_ADJ;
15715            schedGroup = (queue == mFgBroadcastQueue)
15716                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15717            app.adjType = "broadcast";
15718            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15719        } else if (app.executingServices.size() > 0) {
15720            // An app that is currently executing a service callback also
15721            // counts as being in the foreground.
15722            adj = ProcessList.FOREGROUND_APP_ADJ;
15723            schedGroup = app.execServicesFg ?
15724                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15725            app.adjType = "exec-service";
15726            procState = ActivityManager.PROCESS_STATE_SERVICE;
15727            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15728        } else {
15729            // As far as we know the process is empty.  We may change our mind later.
15730            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15731            // At this point we don't actually know the adjustment.  Use the cached adj
15732            // value that the caller wants us to.
15733            adj = cachedAdj;
15734            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15735            app.cached = true;
15736            app.empty = true;
15737            app.adjType = "cch-empty";
15738        }
15739
15740        // Examine all activities if not already foreground.
15741        if (!foregroundActivities && activitiesSize > 0) {
15742            for (int j = 0; j < activitiesSize; j++) {
15743                final ActivityRecord r = app.activities.get(j);
15744                if (r.app != app) {
15745                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15746                            + app + "?!?");
15747                    continue;
15748                }
15749                if (r.visible) {
15750                    // App has a visible activity; only upgrade adjustment.
15751                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15752                        adj = ProcessList.VISIBLE_APP_ADJ;
15753                        app.adjType = "visible";
15754                    }
15755                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15756                        procState = ActivityManager.PROCESS_STATE_TOP;
15757                    }
15758                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15759                    app.cached = false;
15760                    app.empty = false;
15761                    foregroundActivities = true;
15762                    break;
15763                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15764                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15765                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15766                        app.adjType = "pausing";
15767                    }
15768                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15769                        procState = ActivityManager.PROCESS_STATE_TOP;
15770                    }
15771                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15772                    app.cached = false;
15773                    app.empty = false;
15774                    foregroundActivities = true;
15775                } else if (r.state == ActivityState.STOPPING) {
15776                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15777                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15778                        app.adjType = "stopping";
15779                    }
15780                    // For the process state, we will at this point consider the
15781                    // process to be cached.  It will be cached either as an activity
15782                    // or empty depending on whether the activity is finishing.  We do
15783                    // this so that we can treat the process as cached for purposes of
15784                    // memory trimming (determing current memory level, trim command to
15785                    // send to process) since there can be an arbitrary number of stopping
15786                    // processes and they should soon all go into the cached state.
15787                    if (!r.finishing) {
15788                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15789                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15790                        }
15791                    }
15792                    app.cached = false;
15793                    app.empty = false;
15794                    foregroundActivities = true;
15795                } else {
15796                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15797                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15798                        app.adjType = "cch-act";
15799                    }
15800                }
15801            }
15802        }
15803
15804        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15805            if (app.foregroundServices) {
15806                // The user is aware of this app, so make it visible.
15807                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15808                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15809                app.cached = false;
15810                app.adjType = "fg-service";
15811                schedGroup = Process.THREAD_GROUP_DEFAULT;
15812            } else if (app.forcingToForeground != null) {
15813                // The user is aware of this app, so make it visible.
15814                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15815                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15816                app.cached = false;
15817                app.adjType = "force-fg";
15818                app.adjSource = app.forcingToForeground;
15819                schedGroup = Process.THREAD_GROUP_DEFAULT;
15820            }
15821        }
15822
15823        if (app == mHeavyWeightProcess) {
15824            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15825                // We don't want to kill the current heavy-weight process.
15826                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15827                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15828                app.cached = false;
15829                app.adjType = "heavy";
15830            }
15831            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15832                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15833            }
15834        }
15835
15836        if (app == mHomeProcess) {
15837            if (adj > ProcessList.HOME_APP_ADJ) {
15838                // This process is hosting what we currently consider to be the
15839                // home app, so we don't want to let it go into the background.
15840                adj = ProcessList.HOME_APP_ADJ;
15841                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15842                app.cached = false;
15843                app.adjType = "home";
15844            }
15845            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15846                procState = ActivityManager.PROCESS_STATE_HOME;
15847            }
15848        }
15849
15850        if (app == mPreviousProcess && app.activities.size() > 0) {
15851            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15852                // This was the previous process that showed UI to the user.
15853                // We want to try to keep it around more aggressively, to give
15854                // a good experience around switching between two apps.
15855                adj = ProcessList.PREVIOUS_APP_ADJ;
15856                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15857                app.cached = false;
15858                app.adjType = "previous";
15859            }
15860            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15861                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15862            }
15863        }
15864
15865        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15866                + " reason=" + app.adjType);
15867
15868        // By default, we use the computed adjustment.  It may be changed if
15869        // there are applications dependent on our services or providers, but
15870        // this gives us a baseline and makes sure we don't get into an
15871        // infinite recursion.
15872        app.adjSeq = mAdjSeq;
15873        app.curRawAdj = adj;
15874        app.hasStartedServices = false;
15875
15876        if (mBackupTarget != null && app == mBackupTarget.app) {
15877            // If possible we want to avoid killing apps while they're being backed up
15878            if (adj > ProcessList.BACKUP_APP_ADJ) {
15879                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15880                adj = ProcessList.BACKUP_APP_ADJ;
15881                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15882                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15883                }
15884                app.adjType = "backup";
15885                app.cached = false;
15886            }
15887            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15888                procState = ActivityManager.PROCESS_STATE_BACKUP;
15889            }
15890        }
15891
15892        boolean mayBeTop = false;
15893
15894        for (int is = app.services.size()-1;
15895                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15896                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15897                        || procState > ActivityManager.PROCESS_STATE_TOP);
15898                is--) {
15899            ServiceRecord s = app.services.valueAt(is);
15900            if (s.startRequested) {
15901                app.hasStartedServices = true;
15902                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15903                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15904                }
15905                if (app.hasShownUi && app != mHomeProcess) {
15906                    // If this process has shown some UI, let it immediately
15907                    // go to the LRU list because it may be pretty heavy with
15908                    // UI stuff.  We'll tag it with a label just to help
15909                    // debug and understand what is going on.
15910                    if (adj > ProcessList.SERVICE_ADJ) {
15911                        app.adjType = "cch-started-ui-services";
15912                    }
15913                } else {
15914                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15915                        // This service has seen some activity within
15916                        // recent memory, so we will keep its process ahead
15917                        // of the background processes.
15918                        if (adj > ProcessList.SERVICE_ADJ) {
15919                            adj = ProcessList.SERVICE_ADJ;
15920                            app.adjType = "started-services";
15921                            app.cached = false;
15922                        }
15923                    }
15924                    // If we have let the service slide into the background
15925                    // state, still have some text describing what it is doing
15926                    // even though the service no longer has an impact.
15927                    if (adj > ProcessList.SERVICE_ADJ) {
15928                        app.adjType = "cch-started-services";
15929                    }
15930                }
15931            }
15932            for (int conni = s.connections.size()-1;
15933                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15934                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15935                            || procState > ActivityManager.PROCESS_STATE_TOP);
15936                    conni--) {
15937                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15938                for (int i = 0;
15939                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15940                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15941                                || procState > ActivityManager.PROCESS_STATE_TOP);
15942                        i++) {
15943                    // XXX should compute this based on the max of
15944                    // all connected clients.
15945                    ConnectionRecord cr = clist.get(i);
15946                    if (cr.binding.client == app) {
15947                        // Binding to ourself is not interesting.
15948                        continue;
15949                    }
15950                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15951                        ProcessRecord client = cr.binding.client;
15952                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15953                                TOP_APP, doingAll, now);
15954                        int clientProcState = client.curProcState;
15955                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15956                            // If the other app is cached for any reason, for purposes here
15957                            // we are going to consider it empty.  The specific cached state
15958                            // doesn't propagate except under certain conditions.
15959                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15960                        }
15961                        String adjType = null;
15962                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15963                            // Not doing bind OOM management, so treat
15964                            // this guy more like a started service.
15965                            if (app.hasShownUi && app != mHomeProcess) {
15966                                // If this process has shown some UI, let it immediately
15967                                // go to the LRU list because it may be pretty heavy with
15968                                // UI stuff.  We'll tag it with a label just to help
15969                                // debug and understand what is going on.
15970                                if (adj > clientAdj) {
15971                                    adjType = "cch-bound-ui-services";
15972                                }
15973                                app.cached = false;
15974                                clientAdj = adj;
15975                                clientProcState = procState;
15976                            } else {
15977                                if (now >= (s.lastActivity
15978                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15979                                    // This service has not seen activity within
15980                                    // recent memory, so allow it to drop to the
15981                                    // LRU list if there is no other reason to keep
15982                                    // it around.  We'll also tag it with a label just
15983                                    // to help debug and undertand what is going on.
15984                                    if (adj > clientAdj) {
15985                                        adjType = "cch-bound-services";
15986                                    }
15987                                    clientAdj = adj;
15988                                }
15989                            }
15990                        }
15991                        if (adj > clientAdj) {
15992                            // If this process has recently shown UI, and
15993                            // the process that is binding to it is less
15994                            // important than being visible, then we don't
15995                            // care about the binding as much as we care
15996                            // about letting this process get into the LRU
15997                            // list to be killed and restarted if needed for
15998                            // memory.
15999                            if (app.hasShownUi && app != mHomeProcess
16000                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16001                                adjType = "cch-bound-ui-services";
16002                            } else {
16003                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16004                                        |Context.BIND_IMPORTANT)) != 0) {
16005                                    adj = clientAdj;
16006                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16007                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16008                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16009                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16010                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16011                                    adj = clientAdj;
16012                                } else {
16013                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16014                                        adj = ProcessList.VISIBLE_APP_ADJ;
16015                                    }
16016                                }
16017                                if (!client.cached) {
16018                                    app.cached = false;
16019                                }
16020                                adjType = "service";
16021                            }
16022                        }
16023                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16024                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16025                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16026                            }
16027                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16028                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16029                                    // Special handling of clients who are in the top state.
16030                                    // We *may* want to consider this process to be in the
16031                                    // top state as well, but only if there is not another
16032                                    // reason for it to be running.  Being on the top is a
16033                                    // special state, meaning you are specifically running
16034                                    // for the current top app.  If the process is already
16035                                    // running in the background for some other reason, it
16036                                    // is more important to continue considering it to be
16037                                    // in the background state.
16038                                    mayBeTop = true;
16039                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16040                                } else {
16041                                    // Special handling for above-top states (persistent
16042                                    // processes).  These should not bring the current process
16043                                    // into the top state, since they are not on top.  Instead
16044                                    // give them the best state after that.
16045                                    clientProcState =
16046                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16047                                }
16048                            }
16049                        } else {
16050                            if (clientProcState <
16051                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16052                                clientProcState =
16053                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16054                            }
16055                        }
16056                        if (procState > clientProcState) {
16057                            procState = clientProcState;
16058                        }
16059                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16060                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16061                            app.pendingUiClean = true;
16062                        }
16063                        if (adjType != null) {
16064                            app.adjType = adjType;
16065                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16066                                    .REASON_SERVICE_IN_USE;
16067                            app.adjSource = cr.binding.client;
16068                            app.adjSourceProcState = clientProcState;
16069                            app.adjTarget = s.name;
16070                        }
16071                    }
16072                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16073                        app.treatLikeActivity = true;
16074                    }
16075                    final ActivityRecord a = cr.activity;
16076                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16077                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16078                                (a.visible || a.state == ActivityState.RESUMED
16079                                 || a.state == ActivityState.PAUSING)) {
16080                            adj = ProcessList.FOREGROUND_APP_ADJ;
16081                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16082                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16083                            }
16084                            app.cached = false;
16085                            app.adjType = "service";
16086                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16087                                    .REASON_SERVICE_IN_USE;
16088                            app.adjSource = a;
16089                            app.adjSourceProcState = procState;
16090                            app.adjTarget = s.name;
16091                        }
16092                    }
16093                }
16094            }
16095        }
16096
16097        for (int provi = app.pubProviders.size()-1;
16098                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16099                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16100                        || procState > ActivityManager.PROCESS_STATE_TOP);
16101                provi--) {
16102            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16103            for (int i = cpr.connections.size()-1;
16104                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16105                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16106                            || procState > ActivityManager.PROCESS_STATE_TOP);
16107                    i--) {
16108                ContentProviderConnection conn = cpr.connections.get(i);
16109                ProcessRecord client = conn.client;
16110                if (client == app) {
16111                    // Being our own client is not interesting.
16112                    continue;
16113                }
16114                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16115                int clientProcState = client.curProcState;
16116                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16117                    // If the other app is cached for any reason, for purposes here
16118                    // we are going to consider it empty.
16119                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16120                }
16121                if (adj > clientAdj) {
16122                    if (app.hasShownUi && app != mHomeProcess
16123                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16124                        app.adjType = "cch-ui-provider";
16125                    } else {
16126                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16127                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16128                        app.adjType = "provider";
16129                    }
16130                    app.cached &= client.cached;
16131                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16132                            .REASON_PROVIDER_IN_USE;
16133                    app.adjSource = client;
16134                    app.adjSourceProcState = clientProcState;
16135                    app.adjTarget = cpr.name;
16136                }
16137                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16138                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16139                        // Special handling of clients who are in the top state.
16140                        // We *may* want to consider this process to be in the
16141                        // top state as well, but only if there is not another
16142                        // reason for it to be running.  Being on the top is a
16143                        // special state, meaning you are specifically running
16144                        // for the current top app.  If the process is already
16145                        // running in the background for some other reason, it
16146                        // is more important to continue considering it to be
16147                        // in the background state.
16148                        mayBeTop = true;
16149                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16150                    } else {
16151                        // Special handling for above-top states (persistent
16152                        // processes).  These should not bring the current process
16153                        // into the top state, since they are not on top.  Instead
16154                        // give them the best state after that.
16155                        clientProcState =
16156                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16157                    }
16158                }
16159                if (procState > clientProcState) {
16160                    procState = clientProcState;
16161                }
16162                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16163                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16164                }
16165            }
16166            // If the provider has external (non-framework) process
16167            // dependencies, ensure that its adjustment is at least
16168            // FOREGROUND_APP_ADJ.
16169            if (cpr.hasExternalProcessHandles()) {
16170                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16171                    adj = ProcessList.FOREGROUND_APP_ADJ;
16172                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16173                    app.cached = false;
16174                    app.adjType = "provider";
16175                    app.adjTarget = cpr.name;
16176                }
16177                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16178                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16179                }
16180            }
16181        }
16182
16183        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16184            // A client of one of our services or providers is in the top state.  We
16185            // *may* want to be in the top state, but not if we are already running in
16186            // the background for some other reason.  For the decision here, we are going
16187            // to pick out a few specific states that we want to remain in when a client
16188            // is top (states that tend to be longer-term) and otherwise allow it to go
16189            // to the top state.
16190            switch (procState) {
16191                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16192                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16193                case ActivityManager.PROCESS_STATE_SERVICE:
16194                    // These all are longer-term states, so pull them up to the top
16195                    // of the background states, but not all the way to the top state.
16196                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16197                    break;
16198                default:
16199                    // Otherwise, top is a better choice, so take it.
16200                    procState = ActivityManager.PROCESS_STATE_TOP;
16201                    break;
16202            }
16203        }
16204
16205        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16206            if (app.hasClientActivities) {
16207                // This is a cached process, but with client activities.  Mark it so.
16208                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16209                app.adjType = "cch-client-act";
16210            } else if (app.treatLikeActivity) {
16211                // This is a cached process, but somebody wants us to treat it like it has
16212                // an activity, okay!
16213                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16214                app.adjType = "cch-as-act";
16215            }
16216        }
16217
16218        if (adj == ProcessList.SERVICE_ADJ) {
16219            if (doingAll) {
16220                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16221                mNewNumServiceProcs++;
16222                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16223                if (!app.serviceb) {
16224                    // This service isn't far enough down on the LRU list to
16225                    // normally be a B service, but if we are low on RAM and it
16226                    // is large we want to force it down since we would prefer to
16227                    // keep launcher over it.
16228                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16229                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16230                        app.serviceHighRam = true;
16231                        app.serviceb = true;
16232                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16233                    } else {
16234                        mNewNumAServiceProcs++;
16235                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16236                    }
16237                } else {
16238                    app.serviceHighRam = false;
16239                }
16240            }
16241            if (app.serviceb) {
16242                adj = ProcessList.SERVICE_B_ADJ;
16243            }
16244        }
16245
16246        app.curRawAdj = adj;
16247
16248        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16249        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16250        if (adj > app.maxAdj) {
16251            adj = app.maxAdj;
16252            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16253                schedGroup = Process.THREAD_GROUP_DEFAULT;
16254            }
16255        }
16256
16257        // Do final modification to adj.  Everything we do between here and applying
16258        // the final setAdj must be done in this function, because we will also use
16259        // it when computing the final cached adj later.  Note that we don't need to
16260        // worry about this for max adj above, since max adj will always be used to
16261        // keep it out of the cached vaues.
16262        app.curAdj = app.modifyRawOomAdj(adj);
16263        app.curSchedGroup = schedGroup;
16264        app.curProcState = procState;
16265        app.foregroundActivities = foregroundActivities;
16266
16267        return app.curRawAdj;
16268    }
16269
16270    /**
16271     * Schedule PSS collection of a process.
16272     */
16273    void requestPssLocked(ProcessRecord proc, int procState) {
16274        if (mPendingPssProcesses.contains(proc)) {
16275            return;
16276        }
16277        if (mPendingPssProcesses.size() == 0) {
16278            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16279        }
16280        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16281        proc.pssProcState = procState;
16282        mPendingPssProcesses.add(proc);
16283    }
16284
16285    /**
16286     * Schedule PSS collection of all processes.
16287     */
16288    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16289        if (!always) {
16290            if (now < (mLastFullPssTime +
16291                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16292                return;
16293            }
16294        }
16295        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16296        mLastFullPssTime = now;
16297        mFullPssPending = true;
16298        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16299        mPendingPssProcesses.clear();
16300        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16301            ProcessRecord app = mLruProcesses.get(i);
16302            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16303                app.pssProcState = app.setProcState;
16304                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16305                        isSleeping(), now);
16306                mPendingPssProcesses.add(app);
16307            }
16308        }
16309        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16310    }
16311
16312    /**
16313     * Ask a given process to GC right now.
16314     */
16315    final void performAppGcLocked(ProcessRecord app) {
16316        try {
16317            app.lastRequestedGc = SystemClock.uptimeMillis();
16318            if (app.thread != null) {
16319                if (app.reportLowMemory) {
16320                    app.reportLowMemory = false;
16321                    app.thread.scheduleLowMemory();
16322                } else {
16323                    app.thread.processInBackground();
16324                }
16325            }
16326        } catch (Exception e) {
16327            // whatever.
16328        }
16329    }
16330
16331    /**
16332     * Returns true if things are idle enough to perform GCs.
16333     */
16334    private final boolean canGcNowLocked() {
16335        boolean processingBroadcasts = false;
16336        for (BroadcastQueue q : mBroadcastQueues) {
16337            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16338                processingBroadcasts = true;
16339            }
16340        }
16341        return !processingBroadcasts
16342                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16343    }
16344
16345    /**
16346     * Perform GCs on all processes that are waiting for it, but only
16347     * if things are idle.
16348     */
16349    final void performAppGcsLocked() {
16350        final int N = mProcessesToGc.size();
16351        if (N <= 0) {
16352            return;
16353        }
16354        if (canGcNowLocked()) {
16355            while (mProcessesToGc.size() > 0) {
16356                ProcessRecord proc = mProcessesToGc.remove(0);
16357                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16358                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16359                            <= SystemClock.uptimeMillis()) {
16360                        // To avoid spamming the system, we will GC processes one
16361                        // at a time, waiting a few seconds between each.
16362                        performAppGcLocked(proc);
16363                        scheduleAppGcsLocked();
16364                        return;
16365                    } else {
16366                        // It hasn't been long enough since we last GCed this
16367                        // process...  put it in the list to wait for its time.
16368                        addProcessToGcListLocked(proc);
16369                        break;
16370                    }
16371                }
16372            }
16373
16374            scheduleAppGcsLocked();
16375        }
16376    }
16377
16378    /**
16379     * If all looks good, perform GCs on all processes waiting for them.
16380     */
16381    final void performAppGcsIfAppropriateLocked() {
16382        if (canGcNowLocked()) {
16383            performAppGcsLocked();
16384            return;
16385        }
16386        // Still not idle, wait some more.
16387        scheduleAppGcsLocked();
16388    }
16389
16390    /**
16391     * Schedule the execution of all pending app GCs.
16392     */
16393    final void scheduleAppGcsLocked() {
16394        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16395
16396        if (mProcessesToGc.size() > 0) {
16397            // Schedule a GC for the time to the next process.
16398            ProcessRecord proc = mProcessesToGc.get(0);
16399            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16400
16401            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16402            long now = SystemClock.uptimeMillis();
16403            if (when < (now+GC_TIMEOUT)) {
16404                when = now + GC_TIMEOUT;
16405            }
16406            mHandler.sendMessageAtTime(msg, when);
16407        }
16408    }
16409
16410    /**
16411     * Add a process to the array of processes waiting to be GCed.  Keeps the
16412     * list in sorted order by the last GC time.  The process can't already be
16413     * on the list.
16414     */
16415    final void addProcessToGcListLocked(ProcessRecord proc) {
16416        boolean added = false;
16417        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16418            if (mProcessesToGc.get(i).lastRequestedGc <
16419                    proc.lastRequestedGc) {
16420                added = true;
16421                mProcessesToGc.add(i+1, proc);
16422                break;
16423            }
16424        }
16425        if (!added) {
16426            mProcessesToGc.add(0, proc);
16427        }
16428    }
16429
16430    /**
16431     * Set up to ask a process to GC itself.  This will either do it
16432     * immediately, or put it on the list of processes to gc the next
16433     * time things are idle.
16434     */
16435    final void scheduleAppGcLocked(ProcessRecord app) {
16436        long now = SystemClock.uptimeMillis();
16437        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16438            return;
16439        }
16440        if (!mProcessesToGc.contains(app)) {
16441            addProcessToGcListLocked(app);
16442            scheduleAppGcsLocked();
16443        }
16444    }
16445
16446    final void checkExcessivePowerUsageLocked(boolean doKills) {
16447        updateCpuStatsNow();
16448
16449        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16450        boolean doWakeKills = doKills;
16451        boolean doCpuKills = doKills;
16452        if (mLastPowerCheckRealtime == 0) {
16453            doWakeKills = false;
16454        }
16455        if (mLastPowerCheckUptime == 0) {
16456            doCpuKills = false;
16457        }
16458        if (stats.isScreenOn()) {
16459            doWakeKills = false;
16460        }
16461        final long curRealtime = SystemClock.elapsedRealtime();
16462        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16463        final long curUptime = SystemClock.uptimeMillis();
16464        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16465        mLastPowerCheckRealtime = curRealtime;
16466        mLastPowerCheckUptime = curUptime;
16467        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16468            doWakeKills = false;
16469        }
16470        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16471            doCpuKills = false;
16472        }
16473        int i = mLruProcesses.size();
16474        while (i > 0) {
16475            i--;
16476            ProcessRecord app = mLruProcesses.get(i);
16477            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16478                long wtime;
16479                synchronized (stats) {
16480                    wtime = stats.getProcessWakeTime(app.info.uid,
16481                            app.pid, curRealtime);
16482                }
16483                long wtimeUsed = wtime - app.lastWakeTime;
16484                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16485                if (DEBUG_POWER) {
16486                    StringBuilder sb = new StringBuilder(128);
16487                    sb.append("Wake for ");
16488                    app.toShortString(sb);
16489                    sb.append(": over ");
16490                    TimeUtils.formatDuration(realtimeSince, sb);
16491                    sb.append(" used ");
16492                    TimeUtils.formatDuration(wtimeUsed, sb);
16493                    sb.append(" (");
16494                    sb.append((wtimeUsed*100)/realtimeSince);
16495                    sb.append("%)");
16496                    Slog.i(TAG, sb.toString());
16497                    sb.setLength(0);
16498                    sb.append("CPU for ");
16499                    app.toShortString(sb);
16500                    sb.append(": over ");
16501                    TimeUtils.formatDuration(uptimeSince, sb);
16502                    sb.append(" used ");
16503                    TimeUtils.formatDuration(cputimeUsed, sb);
16504                    sb.append(" (");
16505                    sb.append((cputimeUsed*100)/uptimeSince);
16506                    sb.append("%)");
16507                    Slog.i(TAG, sb.toString());
16508                }
16509                // If a process has held a wake lock for more
16510                // than 50% of the time during this period,
16511                // that sounds bad.  Kill!
16512                if (doWakeKills && realtimeSince > 0
16513                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16514                    synchronized (stats) {
16515                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16516                                realtimeSince, wtimeUsed);
16517                    }
16518                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16519                            + " during " + realtimeSince);
16520                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16521                } else if (doCpuKills && uptimeSince > 0
16522                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16523                    synchronized (stats) {
16524                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16525                                uptimeSince, cputimeUsed);
16526                    }
16527                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16528                            + " during " + uptimeSince);
16529                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16530                } else {
16531                    app.lastWakeTime = wtime;
16532                    app.lastCpuTime = app.curCpuTime;
16533                }
16534            }
16535        }
16536    }
16537
16538    private final boolean applyOomAdjLocked(ProcessRecord app,
16539            ProcessRecord TOP_APP, boolean doingAll, long now) {
16540        boolean success = true;
16541
16542        if (app.curRawAdj != app.setRawAdj) {
16543            app.setRawAdj = app.curRawAdj;
16544        }
16545
16546        int changes = 0;
16547
16548        if (app.curAdj != app.setAdj) {
16549            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16550            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16551                TAG, "Set " + app.pid + " " + app.processName +
16552                " adj " + app.curAdj + ": " + app.adjType);
16553            app.setAdj = app.curAdj;
16554        }
16555
16556        if (app.setSchedGroup != app.curSchedGroup) {
16557            app.setSchedGroup = app.curSchedGroup;
16558            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16559                    "Setting process group of " + app.processName
16560                    + " to " + app.curSchedGroup);
16561            if (app.waitingToKill != null &&
16562                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16563                killUnneededProcessLocked(app, app.waitingToKill);
16564                success = false;
16565            } else {
16566                if (true) {
16567                    long oldId = Binder.clearCallingIdentity();
16568                    try {
16569                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16570                    } catch (Exception e) {
16571                        Slog.w(TAG, "Failed setting process group of " + app.pid
16572                                + " to " + app.curSchedGroup);
16573                        e.printStackTrace();
16574                    } finally {
16575                        Binder.restoreCallingIdentity(oldId);
16576                    }
16577                } else {
16578                    if (app.thread != null) {
16579                        try {
16580                            app.thread.setSchedulingGroup(app.curSchedGroup);
16581                        } catch (RemoteException e) {
16582                        }
16583                    }
16584                }
16585                Process.setSwappiness(app.pid,
16586                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16587            }
16588        }
16589        if (app.repForegroundActivities != app.foregroundActivities) {
16590            app.repForegroundActivities = app.foregroundActivities;
16591            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16592        }
16593        if (app.repProcState != app.curProcState) {
16594            app.repProcState = app.curProcState;
16595            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16596            if (app.thread != null) {
16597                try {
16598                    if (false) {
16599                        //RuntimeException h = new RuntimeException("here");
16600                        Slog.i(TAG, "Sending new process state " + app.repProcState
16601                                + " to " + app /*, h*/);
16602                    }
16603                    app.thread.setProcessState(app.repProcState);
16604                } catch (RemoteException e) {
16605                }
16606            }
16607        }
16608        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16609                app.setProcState)) {
16610            app.lastStateTime = now;
16611            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16612                    isSleeping(), now);
16613            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16614                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16615                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16616                    + (app.nextPssTime-now) + ": " + app);
16617        } else {
16618            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16619                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16620                requestPssLocked(app, app.setProcState);
16621                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16622                        isSleeping(), now);
16623            } else if (false && DEBUG_PSS) {
16624                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16625            }
16626        }
16627        if (app.setProcState != app.curProcState) {
16628            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16629                    "Proc state change of " + app.processName
16630                    + " to " + app.curProcState);
16631            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16632            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16633            if (setImportant && !curImportant) {
16634                // This app is no longer something we consider important enough to allow to
16635                // use arbitrary amounts of battery power.  Note
16636                // its current wake lock time to later know to kill it if
16637                // it is not behaving well.
16638                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16639                synchronized (stats) {
16640                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16641                            app.pid, SystemClock.elapsedRealtime());
16642                }
16643                app.lastCpuTime = app.curCpuTime;
16644
16645            }
16646            app.setProcState = app.curProcState;
16647            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16648                app.notCachedSinceIdle = false;
16649            }
16650            if (!doingAll) {
16651                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16652            } else {
16653                app.procStateChanged = true;
16654            }
16655        }
16656
16657        if (changes != 0) {
16658            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16659            int i = mPendingProcessChanges.size()-1;
16660            ProcessChangeItem item = null;
16661            while (i >= 0) {
16662                item = mPendingProcessChanges.get(i);
16663                if (item.pid == app.pid) {
16664                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16665                    break;
16666                }
16667                i--;
16668            }
16669            if (i < 0) {
16670                // No existing item in pending changes; need a new one.
16671                final int NA = mAvailProcessChanges.size();
16672                if (NA > 0) {
16673                    item = mAvailProcessChanges.remove(NA-1);
16674                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16675                } else {
16676                    item = new ProcessChangeItem();
16677                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16678                }
16679                item.changes = 0;
16680                item.pid = app.pid;
16681                item.uid = app.info.uid;
16682                if (mPendingProcessChanges.size() == 0) {
16683                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16684                            "*** Enqueueing dispatch processes changed!");
16685                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16686                }
16687                mPendingProcessChanges.add(item);
16688            }
16689            item.changes |= changes;
16690            item.processState = app.repProcState;
16691            item.foregroundActivities = app.repForegroundActivities;
16692            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16693                    + Integer.toHexString(System.identityHashCode(item))
16694                    + " " + app.toShortString() + ": changes=" + item.changes
16695                    + " procState=" + item.processState
16696                    + " foreground=" + item.foregroundActivities
16697                    + " type=" + app.adjType + " source=" + app.adjSource
16698                    + " target=" + app.adjTarget);
16699        }
16700
16701        return success;
16702    }
16703
16704    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16705        if (proc.thread != null) {
16706            if (proc.baseProcessTracker != null) {
16707                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16708            }
16709            if (proc.repProcState >= 0) {
16710                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16711                        proc.repProcState);
16712            }
16713        }
16714    }
16715
16716    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16717            ProcessRecord TOP_APP, boolean doingAll, long now) {
16718        if (app.thread == null) {
16719            return false;
16720        }
16721
16722        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16723
16724        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16725    }
16726
16727    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16728            boolean oomAdj) {
16729        if (isForeground != proc.foregroundServices) {
16730            proc.foregroundServices = isForeground;
16731            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16732                    proc.info.uid);
16733            if (isForeground) {
16734                if (curProcs == null) {
16735                    curProcs = new ArrayList<ProcessRecord>();
16736                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16737                }
16738                if (!curProcs.contains(proc)) {
16739                    curProcs.add(proc);
16740                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16741                            proc.info.packageName, proc.info.uid);
16742                }
16743            } else {
16744                if (curProcs != null) {
16745                    if (curProcs.remove(proc)) {
16746                        mBatteryStatsService.noteEvent(
16747                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16748                                proc.info.packageName, proc.info.uid);
16749                        if (curProcs.size() <= 0) {
16750                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16751                        }
16752                    }
16753                }
16754            }
16755            if (oomAdj) {
16756                updateOomAdjLocked();
16757            }
16758        }
16759    }
16760
16761    private final ActivityRecord resumedAppLocked() {
16762        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16763        String pkg;
16764        int uid;
16765        if (act != null) {
16766            pkg = act.packageName;
16767            uid = act.info.applicationInfo.uid;
16768        } else {
16769            pkg = null;
16770            uid = -1;
16771        }
16772        // Has the UID or resumed package name changed?
16773        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16774                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16775            if (mCurResumedPackage != null) {
16776                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16777                        mCurResumedPackage, mCurResumedUid);
16778            }
16779            mCurResumedPackage = pkg;
16780            mCurResumedUid = uid;
16781            if (mCurResumedPackage != null) {
16782                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16783                        mCurResumedPackage, mCurResumedUid);
16784            }
16785        }
16786        return act;
16787    }
16788
16789    final boolean updateOomAdjLocked(ProcessRecord app) {
16790        final ActivityRecord TOP_ACT = resumedAppLocked();
16791        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16792        final boolean wasCached = app.cached;
16793
16794        mAdjSeq++;
16795
16796        // This is the desired cached adjusment we want to tell it to use.
16797        // If our app is currently cached, we know it, and that is it.  Otherwise,
16798        // we don't know it yet, and it needs to now be cached we will then
16799        // need to do a complete oom adj.
16800        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16801                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16802        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16803                SystemClock.uptimeMillis());
16804        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16805            // Changed to/from cached state, so apps after it in the LRU
16806            // list may also be changed.
16807            updateOomAdjLocked();
16808        }
16809        return success;
16810    }
16811
16812    final void updateOomAdjLocked() {
16813        final ActivityRecord TOP_ACT = resumedAppLocked();
16814        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16815        final long now = SystemClock.uptimeMillis();
16816        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16817        final int N = mLruProcesses.size();
16818
16819        if (false) {
16820            RuntimeException e = new RuntimeException();
16821            e.fillInStackTrace();
16822            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16823        }
16824
16825        mAdjSeq++;
16826        mNewNumServiceProcs = 0;
16827        mNewNumAServiceProcs = 0;
16828
16829        final int emptyProcessLimit;
16830        final int cachedProcessLimit;
16831        if (mProcessLimit <= 0) {
16832            emptyProcessLimit = cachedProcessLimit = 0;
16833        } else if (mProcessLimit == 1) {
16834            emptyProcessLimit = 1;
16835            cachedProcessLimit = 0;
16836        } else {
16837            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16838            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16839        }
16840
16841        // Let's determine how many processes we have running vs.
16842        // how many slots we have for background processes; we may want
16843        // to put multiple processes in a slot of there are enough of
16844        // them.
16845        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16846                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16847        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16848        if (numEmptyProcs > cachedProcessLimit) {
16849            // If there are more empty processes than our limit on cached
16850            // processes, then use the cached process limit for the factor.
16851            // This ensures that the really old empty processes get pushed
16852            // down to the bottom, so if we are running low on memory we will
16853            // have a better chance at keeping around more cached processes
16854            // instead of a gazillion empty processes.
16855            numEmptyProcs = cachedProcessLimit;
16856        }
16857        int emptyFactor = numEmptyProcs/numSlots;
16858        if (emptyFactor < 1) emptyFactor = 1;
16859        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16860        if (cachedFactor < 1) cachedFactor = 1;
16861        int stepCached = 0;
16862        int stepEmpty = 0;
16863        int numCached = 0;
16864        int numEmpty = 0;
16865        int numTrimming = 0;
16866
16867        mNumNonCachedProcs = 0;
16868        mNumCachedHiddenProcs = 0;
16869
16870        // First update the OOM adjustment for each of the
16871        // application processes based on their current state.
16872        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16873        int nextCachedAdj = curCachedAdj+1;
16874        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16875        int nextEmptyAdj = curEmptyAdj+2;
16876        for (int i=N-1; i>=0; i--) {
16877            ProcessRecord app = mLruProcesses.get(i);
16878            if (!app.killedByAm && app.thread != null) {
16879                app.procStateChanged = false;
16880                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16881
16882                // If we haven't yet assigned the final cached adj
16883                // to the process, do that now.
16884                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16885                    switch (app.curProcState) {
16886                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16887                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16888                            // This process is a cached process holding activities...
16889                            // assign it the next cached value for that type, and then
16890                            // step that cached level.
16891                            app.curRawAdj = curCachedAdj;
16892                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16893                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16894                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16895                                    + ")");
16896                            if (curCachedAdj != nextCachedAdj) {
16897                                stepCached++;
16898                                if (stepCached >= cachedFactor) {
16899                                    stepCached = 0;
16900                                    curCachedAdj = nextCachedAdj;
16901                                    nextCachedAdj += 2;
16902                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16903                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16904                                    }
16905                                }
16906                            }
16907                            break;
16908                        default:
16909                            // For everything else, assign next empty cached process
16910                            // level and bump that up.  Note that this means that
16911                            // long-running services that have dropped down to the
16912                            // cached level will be treated as empty (since their process
16913                            // state is still as a service), which is what we want.
16914                            app.curRawAdj = curEmptyAdj;
16915                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16916                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16917                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16918                                    + ")");
16919                            if (curEmptyAdj != nextEmptyAdj) {
16920                                stepEmpty++;
16921                                if (stepEmpty >= emptyFactor) {
16922                                    stepEmpty = 0;
16923                                    curEmptyAdj = nextEmptyAdj;
16924                                    nextEmptyAdj += 2;
16925                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16926                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16927                                    }
16928                                }
16929                            }
16930                            break;
16931                    }
16932                }
16933
16934                applyOomAdjLocked(app, TOP_APP, true, now);
16935
16936                // Count the number of process types.
16937                switch (app.curProcState) {
16938                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16939                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16940                        mNumCachedHiddenProcs++;
16941                        numCached++;
16942                        if (numCached > cachedProcessLimit) {
16943                            killUnneededProcessLocked(app, "cached #" + numCached);
16944                        }
16945                        break;
16946                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16947                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16948                                && app.lastActivityTime < oldTime) {
16949                            killUnneededProcessLocked(app, "empty for "
16950                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16951                                    / 1000) + "s");
16952                        } else {
16953                            numEmpty++;
16954                            if (numEmpty > emptyProcessLimit) {
16955                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16956                            }
16957                        }
16958                        break;
16959                    default:
16960                        mNumNonCachedProcs++;
16961                        break;
16962                }
16963
16964                if (app.isolated && app.services.size() <= 0) {
16965                    // If this is an isolated process, and there are no
16966                    // services running in it, then the process is no longer
16967                    // needed.  We agressively kill these because we can by
16968                    // definition not re-use the same process again, and it is
16969                    // good to avoid having whatever code was running in them
16970                    // left sitting around after no longer needed.
16971                    killUnneededProcessLocked(app, "isolated not needed");
16972                }
16973
16974                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16975                        && !app.killedByAm) {
16976                    numTrimming++;
16977                }
16978            }
16979        }
16980
16981        mNumServiceProcs = mNewNumServiceProcs;
16982
16983        // Now determine the memory trimming level of background processes.
16984        // Unfortunately we need to start at the back of the list to do this
16985        // properly.  We only do this if the number of background apps we
16986        // are managing to keep around is less than half the maximum we desire;
16987        // if we are keeping a good number around, we'll let them use whatever
16988        // memory they want.
16989        final int numCachedAndEmpty = numCached + numEmpty;
16990        int memFactor;
16991        if (numCached <= ProcessList.TRIM_CACHED_APPS
16992                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16993            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16994                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16995            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16996                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16997            } else {
16998                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16999            }
17000        } else {
17001            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17002        }
17003        // We always allow the memory level to go up (better).  We only allow it to go
17004        // down if we are in a state where that is allowed, *and* the total number of processes
17005        // has gone down since last time.
17006        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17007                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17008                + " last=" + mLastNumProcesses);
17009        if (memFactor > mLastMemoryLevel) {
17010            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17011                memFactor = mLastMemoryLevel;
17012                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17013            }
17014        }
17015        mLastMemoryLevel = memFactor;
17016        mLastNumProcesses = mLruProcesses.size();
17017        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17018        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17019        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17020            if (mLowRamStartTime == 0) {
17021                mLowRamStartTime = now;
17022            }
17023            int step = 0;
17024            int fgTrimLevel;
17025            switch (memFactor) {
17026                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17027                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17028                    break;
17029                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17030                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17031                    break;
17032                default:
17033                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17034                    break;
17035            }
17036            int factor = numTrimming/3;
17037            int minFactor = 2;
17038            if (mHomeProcess != null) minFactor++;
17039            if (mPreviousProcess != null) minFactor++;
17040            if (factor < minFactor) factor = minFactor;
17041            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17042            for (int i=N-1; i>=0; i--) {
17043                ProcessRecord app = mLruProcesses.get(i);
17044                if (allChanged || app.procStateChanged) {
17045                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17046                    app.procStateChanged = false;
17047                }
17048                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17049                        && !app.killedByAm) {
17050                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17051                        try {
17052                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17053                                    "Trimming memory of " + app.processName
17054                                    + " to " + curLevel);
17055                            app.thread.scheduleTrimMemory(curLevel);
17056                        } catch (RemoteException e) {
17057                        }
17058                        if (false) {
17059                            // For now we won't do this; our memory trimming seems
17060                            // to be good enough at this point that destroying
17061                            // activities causes more harm than good.
17062                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17063                                    && app != mHomeProcess && app != mPreviousProcess) {
17064                                // Need to do this on its own message because the stack may not
17065                                // be in a consistent state at this point.
17066                                // For these apps we will also finish their activities
17067                                // to help them free memory.
17068                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17069                            }
17070                        }
17071                    }
17072                    app.trimMemoryLevel = curLevel;
17073                    step++;
17074                    if (step >= factor) {
17075                        step = 0;
17076                        switch (curLevel) {
17077                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17078                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17079                                break;
17080                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17081                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17082                                break;
17083                        }
17084                    }
17085                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17086                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17087                            && app.thread != null) {
17088                        try {
17089                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17090                                    "Trimming memory of heavy-weight " + app.processName
17091                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17092                            app.thread.scheduleTrimMemory(
17093                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17094                        } catch (RemoteException e) {
17095                        }
17096                    }
17097                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17098                } else {
17099                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17100                            || app.systemNoUi) && app.pendingUiClean) {
17101                        // If this application is now in the background and it
17102                        // had done UI, then give it the special trim level to
17103                        // have it free UI resources.
17104                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17105                        if (app.trimMemoryLevel < level && app.thread != null) {
17106                            try {
17107                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17108                                        "Trimming memory of bg-ui " + app.processName
17109                                        + " to " + level);
17110                                app.thread.scheduleTrimMemory(level);
17111                            } catch (RemoteException e) {
17112                            }
17113                        }
17114                        app.pendingUiClean = false;
17115                    }
17116                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17117                        try {
17118                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17119                                    "Trimming memory of fg " + app.processName
17120                                    + " to " + fgTrimLevel);
17121                            app.thread.scheduleTrimMemory(fgTrimLevel);
17122                        } catch (RemoteException e) {
17123                        }
17124                    }
17125                    app.trimMemoryLevel = fgTrimLevel;
17126                }
17127            }
17128        } else {
17129            if (mLowRamStartTime != 0) {
17130                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17131                mLowRamStartTime = 0;
17132            }
17133            for (int i=N-1; i>=0; i--) {
17134                ProcessRecord app = mLruProcesses.get(i);
17135                if (allChanged || app.procStateChanged) {
17136                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17137                    app.procStateChanged = false;
17138                }
17139                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17140                        || app.systemNoUi) && app.pendingUiClean) {
17141                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17142                            && app.thread != null) {
17143                        try {
17144                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17145                                    "Trimming memory of ui hidden " + app.processName
17146                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17147                            app.thread.scheduleTrimMemory(
17148                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17149                        } catch (RemoteException e) {
17150                        }
17151                    }
17152                    app.pendingUiClean = false;
17153                }
17154                app.trimMemoryLevel = 0;
17155            }
17156        }
17157
17158        if (mAlwaysFinishActivities) {
17159            // Need to do this on its own message because the stack may not
17160            // be in a consistent state at this point.
17161            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17162        }
17163
17164        if (allChanged) {
17165            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17166        }
17167
17168        if (mProcessStats.shouldWriteNowLocked(now)) {
17169            mHandler.post(new Runnable() {
17170                @Override public void run() {
17171                    synchronized (ActivityManagerService.this) {
17172                        mProcessStats.writeStateAsyncLocked();
17173                    }
17174                }
17175            });
17176        }
17177
17178        if (DEBUG_OOM_ADJ) {
17179            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17180        }
17181    }
17182
17183    final void trimApplications() {
17184        synchronized (this) {
17185            int i;
17186
17187            // First remove any unused application processes whose package
17188            // has been removed.
17189            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17190                final ProcessRecord app = mRemovedProcesses.get(i);
17191                if (app.activities.size() == 0
17192                        && app.curReceiver == null && app.services.size() == 0) {
17193                    Slog.i(
17194                        TAG, "Exiting empty application process "
17195                        + app.processName + " ("
17196                        + (app.thread != null ? app.thread.asBinder() : null)
17197                        + ")\n");
17198                    if (app.pid > 0 && app.pid != MY_PID) {
17199                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
17200                                app.processName, app.setAdj, "empty");
17201                        app.killedByAm = true;
17202                        Process.killProcessQuiet(app.pid);
17203                        Process.killProcessGroup(app.info.uid, app.pid);
17204                    } else {
17205                        try {
17206                            app.thread.scheduleExit();
17207                        } catch (Exception e) {
17208                            // Ignore exceptions.
17209                        }
17210                    }
17211                    cleanUpApplicationRecordLocked(app, false, true, -1);
17212                    mRemovedProcesses.remove(i);
17213
17214                    if (app.persistent) {
17215                        addAppLocked(app.info, false, null /* ABI override */);
17216                    }
17217                }
17218            }
17219
17220            // Now update the oom adj for all processes.
17221            updateOomAdjLocked();
17222        }
17223    }
17224
17225    /** This method sends the specified signal to each of the persistent apps */
17226    public void signalPersistentProcesses(int sig) throws RemoteException {
17227        if (sig != Process.SIGNAL_USR1) {
17228            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17229        }
17230
17231        synchronized (this) {
17232            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17233                    != PackageManager.PERMISSION_GRANTED) {
17234                throw new SecurityException("Requires permission "
17235                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17236            }
17237
17238            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17239                ProcessRecord r = mLruProcesses.get(i);
17240                if (r.thread != null && r.persistent) {
17241                    Process.sendSignal(r.pid, sig);
17242                }
17243            }
17244        }
17245    }
17246
17247    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17248        if (proc == null || proc == mProfileProc) {
17249            proc = mProfileProc;
17250            path = mProfileFile;
17251            profileType = mProfileType;
17252            clearProfilerLocked();
17253        }
17254        if (proc == null) {
17255            return;
17256        }
17257        try {
17258            proc.thread.profilerControl(false, path, null, profileType);
17259        } catch (RemoteException e) {
17260            throw new IllegalStateException("Process disappeared");
17261        }
17262    }
17263
17264    private void clearProfilerLocked() {
17265        if (mProfileFd != null) {
17266            try {
17267                mProfileFd.close();
17268            } catch (IOException e) {
17269            }
17270        }
17271        mProfileApp = null;
17272        mProfileProc = null;
17273        mProfileFile = null;
17274        mProfileType = 0;
17275        mAutoStopProfiler = false;
17276    }
17277
17278    public boolean profileControl(String process, int userId, boolean start,
17279            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17280
17281        try {
17282            synchronized (this) {
17283                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17284                // its own permission.
17285                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17286                        != PackageManager.PERMISSION_GRANTED) {
17287                    throw new SecurityException("Requires permission "
17288                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17289                }
17290
17291                if (start && fd == null) {
17292                    throw new IllegalArgumentException("null fd");
17293                }
17294
17295                ProcessRecord proc = null;
17296                if (process != null) {
17297                    proc = findProcessLocked(process, userId, "profileControl");
17298                }
17299
17300                if (start && (proc == null || proc.thread == null)) {
17301                    throw new IllegalArgumentException("Unknown process: " + process);
17302                }
17303
17304                if (start) {
17305                    stopProfilerLocked(null, null, 0);
17306                    setProfileApp(proc.info, proc.processName, path, fd, false);
17307                    mProfileProc = proc;
17308                    mProfileType = profileType;
17309                    try {
17310                        fd = fd.dup();
17311                    } catch (IOException e) {
17312                        fd = null;
17313                    }
17314                    proc.thread.profilerControl(start, path, fd, profileType);
17315                    fd = null;
17316                    mProfileFd = null;
17317                } else {
17318                    stopProfilerLocked(proc, path, profileType);
17319                    if (fd != null) {
17320                        try {
17321                            fd.close();
17322                        } catch (IOException e) {
17323                        }
17324                    }
17325                }
17326
17327                return true;
17328            }
17329        } catch (RemoteException e) {
17330            throw new IllegalStateException("Process disappeared");
17331        } finally {
17332            if (fd != null) {
17333                try {
17334                    fd.close();
17335                } catch (IOException e) {
17336                }
17337            }
17338        }
17339    }
17340
17341    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17342        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17343                userId, true, ALLOW_FULL_ONLY, callName, null);
17344        ProcessRecord proc = null;
17345        try {
17346            int pid = Integer.parseInt(process);
17347            synchronized (mPidsSelfLocked) {
17348                proc = mPidsSelfLocked.get(pid);
17349            }
17350        } catch (NumberFormatException e) {
17351        }
17352
17353        if (proc == null) {
17354            ArrayMap<String, SparseArray<ProcessRecord>> all
17355                    = mProcessNames.getMap();
17356            SparseArray<ProcessRecord> procs = all.get(process);
17357            if (procs != null && procs.size() > 0) {
17358                proc = procs.valueAt(0);
17359                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17360                    for (int i=1; i<procs.size(); i++) {
17361                        ProcessRecord thisProc = procs.valueAt(i);
17362                        if (thisProc.userId == userId) {
17363                            proc = thisProc;
17364                            break;
17365                        }
17366                    }
17367                }
17368            }
17369        }
17370
17371        return proc;
17372    }
17373
17374    public boolean dumpHeap(String process, int userId, boolean managed,
17375            String path, ParcelFileDescriptor fd) throws RemoteException {
17376
17377        try {
17378            synchronized (this) {
17379                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17380                // its own permission (same as profileControl).
17381                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17382                        != PackageManager.PERMISSION_GRANTED) {
17383                    throw new SecurityException("Requires permission "
17384                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17385                }
17386
17387                if (fd == null) {
17388                    throw new IllegalArgumentException("null fd");
17389                }
17390
17391                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17392                if (proc == null || proc.thread == null) {
17393                    throw new IllegalArgumentException("Unknown process: " + process);
17394                }
17395
17396                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17397                if (!isDebuggable) {
17398                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17399                        throw new SecurityException("Process not debuggable: " + proc);
17400                    }
17401                }
17402
17403                proc.thread.dumpHeap(managed, path, fd);
17404                fd = null;
17405                return true;
17406            }
17407        } catch (RemoteException e) {
17408            throw new IllegalStateException("Process disappeared");
17409        } finally {
17410            if (fd != null) {
17411                try {
17412                    fd.close();
17413                } catch (IOException e) {
17414                }
17415            }
17416        }
17417    }
17418
17419    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17420    public void monitor() {
17421        synchronized (this) { }
17422    }
17423
17424    void onCoreSettingsChange(Bundle settings) {
17425        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17426            ProcessRecord processRecord = mLruProcesses.get(i);
17427            try {
17428                if (processRecord.thread != null) {
17429                    processRecord.thread.setCoreSettings(settings);
17430                }
17431            } catch (RemoteException re) {
17432                /* ignore */
17433            }
17434        }
17435    }
17436
17437    // Multi-user methods
17438
17439    /**
17440     * Start user, if its not already running, but don't bring it to foreground.
17441     */
17442    @Override
17443    public boolean startUserInBackground(final int userId) {
17444        return startUser(userId, /* foreground */ false);
17445    }
17446
17447    /**
17448     * Refreshes the list of users related to the current user when either a
17449     * user switch happens or when a new related user is started in the
17450     * background.
17451     */
17452    private void updateCurrentProfileIdsLocked() {
17453        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17454                mCurrentUserId, false /* enabledOnly */);
17455        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17456        for (int i = 0; i < currentProfileIds.length; i++) {
17457            currentProfileIds[i] = profiles.get(i).id;
17458        }
17459        mCurrentProfileIds = currentProfileIds;
17460
17461        synchronized (mUserProfileGroupIdsSelfLocked) {
17462            mUserProfileGroupIdsSelfLocked.clear();
17463            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17464            for (int i = 0; i < users.size(); i++) {
17465                UserInfo user = users.get(i);
17466                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17467                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17468                }
17469            }
17470        }
17471    }
17472
17473    private Set getProfileIdsLocked(int userId) {
17474        Set userIds = new HashSet<Integer>();
17475        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17476                userId, false /* enabledOnly */);
17477        for (UserInfo user : profiles) {
17478            userIds.add(Integer.valueOf(user.id));
17479        }
17480        return userIds;
17481    }
17482
17483    @Override
17484    public boolean switchUser(final int userId) {
17485        return startUser(userId, /* foregound */ true);
17486    }
17487
17488    private boolean startUser(final int userId, boolean foreground) {
17489        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17490                != PackageManager.PERMISSION_GRANTED) {
17491            String msg = "Permission Denial: switchUser() from pid="
17492                    + Binder.getCallingPid()
17493                    + ", uid=" + Binder.getCallingUid()
17494                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17495            Slog.w(TAG, msg);
17496            throw new SecurityException(msg);
17497        }
17498
17499        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17500
17501        final long ident = Binder.clearCallingIdentity();
17502        try {
17503            synchronized (this) {
17504                final int oldUserId = mCurrentUserId;
17505                if (oldUserId == userId) {
17506                    return true;
17507                }
17508
17509                mStackSupervisor.setLockTaskModeLocked(null, false);
17510
17511                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17512                if (userInfo == null) {
17513                    Slog.w(TAG, "No user info for user #" + userId);
17514                    return false;
17515                }
17516                if (foreground && userInfo.isManagedProfile()) {
17517                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17518                    return false;
17519                }
17520
17521                if (foreground) {
17522                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17523                            R.anim.screen_user_enter);
17524                }
17525
17526                boolean needStart = false;
17527
17528                // If the user we are switching to is not currently started, then
17529                // we need to start it now.
17530                if (mStartedUsers.get(userId) == null) {
17531                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17532                    updateStartedUserArrayLocked();
17533                    needStart = true;
17534                }
17535
17536                final Integer userIdInt = Integer.valueOf(userId);
17537                mUserLru.remove(userIdInt);
17538                mUserLru.add(userIdInt);
17539
17540                if (foreground) {
17541                    mCurrentUserId = userId;
17542                    updateCurrentProfileIdsLocked();
17543                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17544                    // Once the internal notion of the active user has switched, we lock the device
17545                    // with the option to show the user switcher on the keyguard.
17546                    mWindowManager.lockNow(null);
17547                } else {
17548                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17549                    updateCurrentProfileIdsLocked();
17550                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17551                    mUserLru.remove(currentUserIdInt);
17552                    mUserLru.add(currentUserIdInt);
17553                }
17554
17555                final UserStartedState uss = mStartedUsers.get(userId);
17556
17557                // Make sure user is in the started state.  If it is currently
17558                // stopping, we need to knock that off.
17559                if (uss.mState == UserStartedState.STATE_STOPPING) {
17560                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17561                    // so we can just fairly silently bring the user back from
17562                    // the almost-dead.
17563                    uss.mState = UserStartedState.STATE_RUNNING;
17564                    updateStartedUserArrayLocked();
17565                    needStart = true;
17566                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17567                    // This means ACTION_SHUTDOWN has been sent, so we will
17568                    // need to treat this as a new boot of the user.
17569                    uss.mState = UserStartedState.STATE_BOOTING;
17570                    updateStartedUserArrayLocked();
17571                    needStart = true;
17572                }
17573
17574                if (uss.mState == UserStartedState.STATE_BOOTING) {
17575                    // Booting up a new user, need to tell system services about it.
17576                    // Note that this is on the same handler as scheduling of broadcasts,
17577                    // which is important because it needs to go first.
17578                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17579                }
17580
17581                if (foreground) {
17582                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17583                            oldUserId));
17584                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17585                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17586                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17587                            oldUserId, userId, uss));
17588                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17589                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17590                }
17591
17592                if (needStart) {
17593                    // Send USER_STARTED broadcast
17594                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17595                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17596                            | Intent.FLAG_RECEIVER_FOREGROUND);
17597                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17598                    broadcastIntentLocked(null, null, intent,
17599                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17600                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17601                }
17602
17603                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17604                    if (userId != UserHandle.USER_OWNER) {
17605                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17606                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17607                        broadcastIntentLocked(null, null, intent, null,
17608                                new IIntentReceiver.Stub() {
17609                                    public void performReceive(Intent intent, int resultCode,
17610                                            String data, Bundle extras, boolean ordered,
17611                                            boolean sticky, int sendingUser) {
17612                                        userInitialized(uss, userId);
17613                                    }
17614                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17615                                true, false, MY_PID, Process.SYSTEM_UID,
17616                                userId);
17617                        uss.initializing = true;
17618                    } else {
17619                        getUserManagerLocked().makeInitialized(userInfo.id);
17620                    }
17621                }
17622
17623                if (foreground) {
17624                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17625                    if (homeInFront) {
17626                        startHomeActivityLocked(userId);
17627                    } else {
17628                        mStackSupervisor.resumeTopActivitiesLocked();
17629                    }
17630                    EventLogTags.writeAmSwitchUser(userId);
17631                    getUserManagerLocked().userForeground(userId);
17632                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17633                } else {
17634                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17635                }
17636
17637                if (needStart) {
17638                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17639                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17640                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17641                    broadcastIntentLocked(null, null, intent,
17642                            null, new IIntentReceiver.Stub() {
17643                                @Override
17644                                public void performReceive(Intent intent, int resultCode, String data,
17645                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17646                                        throws RemoteException {
17647                                }
17648                            }, 0, null, null,
17649                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17650                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17651                }
17652            }
17653        } finally {
17654            Binder.restoreCallingIdentity(ident);
17655        }
17656
17657        return true;
17658    }
17659
17660    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17661        long ident = Binder.clearCallingIdentity();
17662        try {
17663            Intent intent;
17664            if (oldUserId >= 0) {
17665                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17666                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17667                int count = profiles.size();
17668                for (int i = 0; i < count; i++) {
17669                    int profileUserId = profiles.get(i).id;
17670                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17671                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17672                            | Intent.FLAG_RECEIVER_FOREGROUND);
17673                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17674                    broadcastIntentLocked(null, null, intent,
17675                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17676                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17677                }
17678            }
17679            if (newUserId >= 0) {
17680                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17681                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17682                int count = profiles.size();
17683                for (int i = 0; i < count; i++) {
17684                    int profileUserId = profiles.get(i).id;
17685                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17686                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17687                            | Intent.FLAG_RECEIVER_FOREGROUND);
17688                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17689                    broadcastIntentLocked(null, null, intent,
17690                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17691                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17692                }
17693                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17694                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17695                        | Intent.FLAG_RECEIVER_FOREGROUND);
17696                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17697                broadcastIntentLocked(null, null, intent,
17698                        null, null, 0, null, null,
17699                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17700                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17701            }
17702        } finally {
17703            Binder.restoreCallingIdentity(ident);
17704        }
17705    }
17706
17707    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17708            final int newUserId) {
17709        final int N = mUserSwitchObservers.beginBroadcast();
17710        if (N > 0) {
17711            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17712                int mCount = 0;
17713                @Override
17714                public void sendResult(Bundle data) throws RemoteException {
17715                    synchronized (ActivityManagerService.this) {
17716                        if (mCurUserSwitchCallback == this) {
17717                            mCount++;
17718                            if (mCount == N) {
17719                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17720                            }
17721                        }
17722                    }
17723                }
17724            };
17725            synchronized (this) {
17726                uss.switching = true;
17727                mCurUserSwitchCallback = callback;
17728            }
17729            for (int i=0; i<N; i++) {
17730                try {
17731                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17732                            newUserId, callback);
17733                } catch (RemoteException e) {
17734                }
17735            }
17736        } else {
17737            synchronized (this) {
17738                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17739            }
17740        }
17741        mUserSwitchObservers.finishBroadcast();
17742    }
17743
17744    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17745        synchronized (this) {
17746            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17747            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17748        }
17749    }
17750
17751    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17752        mCurUserSwitchCallback = null;
17753        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17754        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17755                oldUserId, newUserId, uss));
17756    }
17757
17758    void userInitialized(UserStartedState uss, int newUserId) {
17759        completeSwitchAndInitalize(uss, newUserId, true, false);
17760    }
17761
17762    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17763        completeSwitchAndInitalize(uss, newUserId, false, true);
17764    }
17765
17766    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17767            boolean clearInitializing, boolean clearSwitching) {
17768        boolean unfrozen = false;
17769        synchronized (this) {
17770            if (clearInitializing) {
17771                uss.initializing = false;
17772                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17773            }
17774            if (clearSwitching) {
17775                uss.switching = false;
17776            }
17777            if (!uss.switching && !uss.initializing) {
17778                mWindowManager.stopFreezingScreen();
17779                unfrozen = true;
17780            }
17781        }
17782        if (unfrozen) {
17783            final int N = mUserSwitchObservers.beginBroadcast();
17784            for (int i=0; i<N; i++) {
17785                try {
17786                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17787                } catch (RemoteException e) {
17788                }
17789            }
17790            mUserSwitchObservers.finishBroadcast();
17791        }
17792    }
17793
17794    void scheduleStartProfilesLocked() {
17795        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17796            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17797                    DateUtils.SECOND_IN_MILLIS);
17798        }
17799    }
17800
17801    void startProfilesLocked() {
17802        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17803        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17804                mCurrentUserId, false /* enabledOnly */);
17805        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17806        for (UserInfo user : profiles) {
17807            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17808                    && user.id != mCurrentUserId) {
17809                toStart.add(user);
17810            }
17811        }
17812        final int n = toStart.size();
17813        int i = 0;
17814        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17815            startUserInBackground(toStart.get(i).id);
17816        }
17817        if (i < n) {
17818            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17819        }
17820    }
17821
17822    void finishUserBoot(UserStartedState uss) {
17823        synchronized (this) {
17824            if (uss.mState == UserStartedState.STATE_BOOTING
17825                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17826                uss.mState = UserStartedState.STATE_RUNNING;
17827                final int userId = uss.mHandle.getIdentifier();
17828                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17829                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17830                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17831                broadcastIntentLocked(null, null, intent,
17832                        null, null, 0, null, null,
17833                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17834                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17835            }
17836        }
17837    }
17838
17839    void finishUserSwitch(UserStartedState uss) {
17840        synchronized (this) {
17841            finishUserBoot(uss);
17842
17843            startProfilesLocked();
17844
17845            int num = mUserLru.size();
17846            int i = 0;
17847            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17848                Integer oldUserId = mUserLru.get(i);
17849                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17850                if (oldUss == null) {
17851                    // Shouldn't happen, but be sane if it does.
17852                    mUserLru.remove(i);
17853                    num--;
17854                    continue;
17855                }
17856                if (oldUss.mState == UserStartedState.STATE_STOPPING
17857                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17858                    // This user is already stopping, doesn't count.
17859                    num--;
17860                    i++;
17861                    continue;
17862                }
17863                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17864                    // Owner and current can't be stopped, but count as running.
17865                    i++;
17866                    continue;
17867                }
17868                // This is a user to be stopped.
17869                stopUserLocked(oldUserId, null);
17870                num--;
17871                i++;
17872            }
17873        }
17874    }
17875
17876    @Override
17877    public int stopUser(final int userId, final IStopUserCallback callback) {
17878        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17879                != PackageManager.PERMISSION_GRANTED) {
17880            String msg = "Permission Denial: switchUser() from pid="
17881                    + Binder.getCallingPid()
17882                    + ", uid=" + Binder.getCallingUid()
17883                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17884            Slog.w(TAG, msg);
17885            throw new SecurityException(msg);
17886        }
17887        if (userId <= 0) {
17888            throw new IllegalArgumentException("Can't stop primary user " + userId);
17889        }
17890        synchronized (this) {
17891            return stopUserLocked(userId, callback);
17892        }
17893    }
17894
17895    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17896        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17897        if (mCurrentUserId == userId) {
17898            return ActivityManager.USER_OP_IS_CURRENT;
17899        }
17900
17901        final UserStartedState uss = mStartedUsers.get(userId);
17902        if (uss == null) {
17903            // User is not started, nothing to do...  but we do need to
17904            // callback if requested.
17905            if (callback != null) {
17906                mHandler.post(new Runnable() {
17907                    @Override
17908                    public void run() {
17909                        try {
17910                            callback.userStopped(userId);
17911                        } catch (RemoteException e) {
17912                        }
17913                    }
17914                });
17915            }
17916            return ActivityManager.USER_OP_SUCCESS;
17917        }
17918
17919        if (callback != null) {
17920            uss.mStopCallbacks.add(callback);
17921        }
17922
17923        if (uss.mState != UserStartedState.STATE_STOPPING
17924                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17925            uss.mState = UserStartedState.STATE_STOPPING;
17926            updateStartedUserArrayLocked();
17927
17928            long ident = Binder.clearCallingIdentity();
17929            try {
17930                // We are going to broadcast ACTION_USER_STOPPING and then
17931                // once that is done send a final ACTION_SHUTDOWN and then
17932                // stop the user.
17933                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17934                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17935                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17936                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17937                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17938                // This is the result receiver for the final shutdown broadcast.
17939                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17940                    @Override
17941                    public void performReceive(Intent intent, int resultCode, String data,
17942                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17943                        finishUserStop(uss);
17944                    }
17945                };
17946                // This is the result receiver for the initial stopping broadcast.
17947                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17948                    @Override
17949                    public void performReceive(Intent intent, int resultCode, String data,
17950                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17951                        // On to the next.
17952                        synchronized (ActivityManagerService.this) {
17953                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17954                                // Whoops, we are being started back up.  Abort, abort!
17955                                return;
17956                            }
17957                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17958                        }
17959                        mBatteryStatsService.noteEvent(
17960                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17961                                Integer.toString(userId), userId);
17962                        mSystemServiceManager.stopUser(userId);
17963                        broadcastIntentLocked(null, null, shutdownIntent,
17964                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17965                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17966                    }
17967                };
17968                // Kick things off.
17969                broadcastIntentLocked(null, null, stoppingIntent,
17970                        null, stoppingReceiver, 0, null, null,
17971                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17972                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17973            } finally {
17974                Binder.restoreCallingIdentity(ident);
17975            }
17976        }
17977
17978        return ActivityManager.USER_OP_SUCCESS;
17979    }
17980
17981    void finishUserStop(UserStartedState uss) {
17982        final int userId = uss.mHandle.getIdentifier();
17983        boolean stopped;
17984        ArrayList<IStopUserCallback> callbacks;
17985        synchronized (this) {
17986            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17987            if (mStartedUsers.get(userId) != uss) {
17988                stopped = false;
17989            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17990                stopped = false;
17991            } else {
17992                stopped = true;
17993                // User can no longer run.
17994                mStartedUsers.remove(userId);
17995                mUserLru.remove(Integer.valueOf(userId));
17996                updateStartedUserArrayLocked();
17997
17998                // Clean up all state and processes associated with the user.
17999                // Kill all the processes for the user.
18000                forceStopUserLocked(userId, "finish user");
18001            }
18002
18003            // Explicitly remove the old information in mRecentTasks.
18004            removeRecentTasksForUserLocked(userId);
18005        }
18006
18007        for (int i=0; i<callbacks.size(); i++) {
18008            try {
18009                if (stopped) callbacks.get(i).userStopped(userId);
18010                else callbacks.get(i).userStopAborted(userId);
18011            } catch (RemoteException e) {
18012            }
18013        }
18014
18015        if (stopped) {
18016            mSystemServiceManager.cleanupUser(userId);
18017            synchronized (this) {
18018                mStackSupervisor.removeUserLocked(userId);
18019            }
18020        }
18021    }
18022
18023    @Override
18024    public UserInfo getCurrentUser() {
18025        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18026                != PackageManager.PERMISSION_GRANTED) && (
18027                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18028                != PackageManager.PERMISSION_GRANTED)) {
18029            String msg = "Permission Denial: getCurrentUser() from pid="
18030                    + Binder.getCallingPid()
18031                    + ", uid=" + Binder.getCallingUid()
18032                    + " requires " + INTERACT_ACROSS_USERS;
18033            Slog.w(TAG, msg);
18034            throw new SecurityException(msg);
18035        }
18036        synchronized (this) {
18037            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18038        }
18039    }
18040
18041    int getCurrentUserIdLocked() {
18042        return mCurrentUserId;
18043    }
18044
18045    @Override
18046    public boolean isUserRunning(int userId, boolean orStopped) {
18047        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18048                != PackageManager.PERMISSION_GRANTED) {
18049            String msg = "Permission Denial: isUserRunning() from pid="
18050                    + Binder.getCallingPid()
18051                    + ", uid=" + Binder.getCallingUid()
18052                    + " requires " + INTERACT_ACROSS_USERS;
18053            Slog.w(TAG, msg);
18054            throw new SecurityException(msg);
18055        }
18056        synchronized (this) {
18057            return isUserRunningLocked(userId, orStopped);
18058        }
18059    }
18060
18061    boolean isUserRunningLocked(int userId, boolean orStopped) {
18062        UserStartedState state = mStartedUsers.get(userId);
18063        if (state == null) {
18064            return false;
18065        }
18066        if (orStopped) {
18067            return true;
18068        }
18069        return state.mState != UserStartedState.STATE_STOPPING
18070                && state.mState != UserStartedState.STATE_SHUTDOWN;
18071    }
18072
18073    @Override
18074    public int[] getRunningUserIds() {
18075        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18076                != PackageManager.PERMISSION_GRANTED) {
18077            String msg = "Permission Denial: isUserRunning() from pid="
18078                    + Binder.getCallingPid()
18079                    + ", uid=" + Binder.getCallingUid()
18080                    + " requires " + INTERACT_ACROSS_USERS;
18081            Slog.w(TAG, msg);
18082            throw new SecurityException(msg);
18083        }
18084        synchronized (this) {
18085            return mStartedUserArray;
18086        }
18087    }
18088
18089    private void updateStartedUserArrayLocked() {
18090        int num = 0;
18091        for (int i=0; i<mStartedUsers.size();  i++) {
18092            UserStartedState uss = mStartedUsers.valueAt(i);
18093            // This list does not include stopping users.
18094            if (uss.mState != UserStartedState.STATE_STOPPING
18095                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18096                num++;
18097            }
18098        }
18099        mStartedUserArray = new int[num];
18100        num = 0;
18101        for (int i=0; i<mStartedUsers.size();  i++) {
18102            UserStartedState uss = mStartedUsers.valueAt(i);
18103            if (uss.mState != UserStartedState.STATE_STOPPING
18104                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18105                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18106                num++;
18107            }
18108        }
18109    }
18110
18111    @Override
18112    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18113        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18114                != PackageManager.PERMISSION_GRANTED) {
18115            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18116                    + Binder.getCallingPid()
18117                    + ", uid=" + Binder.getCallingUid()
18118                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18119            Slog.w(TAG, msg);
18120            throw new SecurityException(msg);
18121        }
18122
18123        mUserSwitchObservers.register(observer);
18124    }
18125
18126    @Override
18127    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18128        mUserSwitchObservers.unregister(observer);
18129    }
18130
18131    private boolean userExists(int userId) {
18132        if (userId == 0) {
18133            return true;
18134        }
18135        UserManagerService ums = getUserManagerLocked();
18136        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18137    }
18138
18139    int[] getUsersLocked() {
18140        UserManagerService ums = getUserManagerLocked();
18141        return ums != null ? ums.getUserIds() : new int[] { 0 };
18142    }
18143
18144    UserManagerService getUserManagerLocked() {
18145        if (mUserManager == null) {
18146            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18147            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18148        }
18149        return mUserManager;
18150    }
18151
18152    private int applyUserId(int uid, int userId) {
18153        return UserHandle.getUid(userId, uid);
18154    }
18155
18156    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18157        if (info == null) return null;
18158        ApplicationInfo newInfo = new ApplicationInfo(info);
18159        newInfo.uid = applyUserId(info.uid, userId);
18160        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18161                + info.packageName;
18162        return newInfo;
18163    }
18164
18165    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18166        if (aInfo == null
18167                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18168            return aInfo;
18169        }
18170
18171        ActivityInfo info = new ActivityInfo(aInfo);
18172        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18173        return info;
18174    }
18175
18176    private final class LocalService extends ActivityManagerInternal {
18177        @Override
18178        public void goingToSleep() {
18179            ActivityManagerService.this.goingToSleep();
18180        }
18181
18182        @Override
18183        public void wakingUp() {
18184            ActivityManagerService.this.wakingUp();
18185        }
18186
18187        @Override
18188        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18189                String processName, String abiOverride, int uid, Runnable crashHandler) {
18190            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18191                    processName, abiOverride, uid, crashHandler);
18192        }
18193    }
18194
18195    /**
18196     * An implementation of IAppTask, that allows an app to manage its own tasks via
18197     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18198     * only the process that calls getAppTasks() can call the AppTask methods.
18199     */
18200    class AppTaskImpl extends IAppTask.Stub {
18201        private int mTaskId;
18202        private int mCallingUid;
18203
18204        public AppTaskImpl(int taskId, int callingUid) {
18205            mTaskId = taskId;
18206            mCallingUid = callingUid;
18207        }
18208
18209        private void checkCaller() {
18210            if (mCallingUid != Binder.getCallingUid()) {
18211                throw new SecurityException("Caller " + mCallingUid
18212                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18213            }
18214        }
18215
18216        @Override
18217        public void finishAndRemoveTask() {
18218            checkCaller();
18219
18220            synchronized (ActivityManagerService.this) {
18221                long origId = Binder.clearCallingIdentity();
18222                try {
18223                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18224                    if (tr != null) {
18225                        // Only kill the process if we are not a new document
18226                        int flags = tr.getBaseIntent().getFlags();
18227                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18228                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18229                        removeTaskByIdLocked(mTaskId,
18230                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18231                    }
18232                } finally {
18233                    Binder.restoreCallingIdentity(origId);
18234                }
18235            }
18236        }
18237
18238        @Override
18239        public ActivityManager.RecentTaskInfo getTaskInfo() {
18240            checkCaller();
18241
18242            synchronized (ActivityManagerService.this) {
18243                long origId = Binder.clearCallingIdentity();
18244                try {
18245                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18246                    if (tr != null) {
18247                        return createRecentTaskInfoFromTaskRecord(tr);
18248                    }
18249                } finally {
18250                    Binder.restoreCallingIdentity(origId);
18251                }
18252                return null;
18253            }
18254        }
18255
18256        @Override
18257        public void setExcludeFromRecents(boolean exclude) {
18258            checkCaller();
18259
18260            synchronized (ActivityManagerService.this) {
18261                long origId = Binder.clearCallingIdentity();
18262                try {
18263                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18264                    if (tr != null) {
18265                        Intent intent = tr.getBaseIntent();
18266                        if (exclude) {
18267                            intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18268                        } else {
18269                            intent.setFlags(intent.getFlags()
18270                                    & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18271                        }
18272                    }
18273                } finally {
18274                    Binder.restoreCallingIdentity(origId);
18275                }
18276            }
18277        }
18278    }
18279}
18280