ActivityManagerService.java revision 7622a0f8e4198adf0aae5d4e167ee132b34f4cdb
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 com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
31import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
32import static org.xmlpull.v1.XmlPullParser.START_TAG;
33import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ProfilerInfo;
42import android.app.admin.DevicePolicyManager;
43import android.app.usage.UsageEvents;
44import android.app.usage.UsageStatsManagerInternal;
45import android.appwidget.AppWidgetManager;
46import android.content.res.Resources;
47import android.graphics.Bitmap;
48import android.graphics.Point;
49import android.graphics.Rect;
50import android.os.BatteryStats;
51import android.os.PersistableBundle;
52import android.os.storage.IMountService;
53import android.os.storage.StorageManager;
54import android.service.voice.IVoiceInteractionSession;
55import android.util.ArrayMap;
56import android.util.ArraySet;
57import android.util.SparseIntArray;
58
59import com.android.internal.R;
60import com.android.internal.annotations.GuardedBy;
61import com.android.internal.app.IAppOpsService;
62import com.android.internal.app.IVoiceInteractor;
63import com.android.internal.app.ProcessMap;
64import com.android.internal.app.ProcessStats;
65import com.android.internal.content.PackageMonitor;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.UserManagerService;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203import dalvik.system.VMRuntime;
204
205import java.io.BufferedInputStream;
206import java.io.BufferedOutputStream;
207import java.io.DataInputStream;
208import java.io.DataOutputStream;
209import java.io.File;
210import java.io.FileDescriptor;
211import java.io.FileInputStream;
212import java.io.FileNotFoundException;
213import java.io.FileOutputStream;
214import java.io.IOException;
215import java.io.InputStreamReader;
216import java.io.PrintWriter;
217import java.io.StringWriter;
218import java.lang.ref.WeakReference;
219import java.util.ArrayList;
220import java.util.Arrays;
221import java.util.Collections;
222import java.util.Comparator;
223import java.util.HashMap;
224import java.util.HashSet;
225import java.util.Iterator;
226import java.util.List;
227import java.util.Locale;
228import java.util.Map;
229import java.util.Set;
230import java.util.concurrent.atomic.AtomicBoolean;
231import java.util.concurrent.atomic.AtomicLong;
232
233public final class ActivityManagerService extends ActivityManagerNative
234        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
235
236    private static final String USER_DATA_DIR = "/data/user/";
237    // File that stores last updated system version and called preboot receivers
238    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
239
240    static final String TAG = "ActivityManager";
241    static final String TAG_MU = "ActivityManagerServiceMU";
242    static final boolean DEBUG = false;
243    static final boolean localLOGV = DEBUG;
244    static final boolean DEBUG_BACKUP = localLOGV || false;
245    static final boolean DEBUG_BROADCAST = localLOGV || false;
246    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_CLEANUP = localLOGV || false;
249    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
250    static final boolean DEBUG_FOCUS = false;
251    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
252    static final boolean DEBUG_MU = localLOGV || false;
253    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
254    static final boolean DEBUG_LRU = localLOGV || false;
255    static final boolean DEBUG_PAUSE = localLOGV || false;
256    static final boolean DEBUG_POWER = localLOGV || false;
257    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
258    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
259    static final boolean DEBUG_PROCESSES = localLOGV || false;
260    static final boolean DEBUG_PROVIDER = localLOGV || false;
261    static final boolean DEBUG_RESULTS = localLOGV || false;
262    static final boolean DEBUG_SERVICE = localLOGV || false;
263    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
264    static final boolean DEBUG_STACK = localLOGV || false;
265    static final boolean DEBUG_SWITCH = localLOGV || false;
266    static final boolean DEBUG_TASKS = localLOGV || false;
267    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
268    static final boolean DEBUG_TRANSITION = localLOGV || false;
269    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
270    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
271    static final boolean DEBUG_VISBILITY = localLOGV || false;
272    static final boolean DEBUG_PSS = localLOGV || false;
273    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
274    static final boolean DEBUG_RECENTS = localLOGV || false;
275    static final boolean VALIDATE_TOKENS = false;
276    static final boolean SHOW_ACTIVITY_START_TIME = true;
277
278    // Control over CPU and battery monitoring.
279    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
280    static final boolean MONITOR_CPU_USAGE = true;
281    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
282    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
283    static final boolean MONITOR_THREAD_CPU_USAGE = false;
284
285    // The flags that are set for all calls we make to the package manager.
286    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
287
288    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
289
290    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
291
292    // Maximum number recent bitmaps to keep in memory.
293    static final int MAX_RECENT_BITMAPS = 5;
294
295    // Amount of time after a call to stopAppSwitches() during which we will
296    // prevent further untrusted switches from happening.
297    static final long APP_SWITCH_DELAY_TIME = 5*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.
301    static final int PROC_START_TIMEOUT = 10*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real, when the process was
305    // started with a wrapper for instrumentation (such as Valgrind) because it
306    // could take much longer than usual.
307    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
308
309    // How long to wait after going idle before forcing apps to GC.
310    static final int GC_TIMEOUT = 5*1000;
311
312    // The minimum amount of time between successive GC requests for a process.
313    static final int GC_MIN_INTERVAL = 60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process.
316    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process
319    // when the request is due to the memory state being lowered.
320    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
321
322    // The rate at which we check for apps using excessive power -- 15 mins.
323    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on wake locks to start killing things.
327    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on CPU usage to start killing things.
331    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // How long we allow a receiver to run before giving up on it.
334    static final int BROADCAST_FG_TIMEOUT = 10*1000;
335    static final int BROADCAST_BG_TIMEOUT = 60*1000;
336
337    // How long we wait until we timeout on key dispatching.
338    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
339
340    // How long we wait until we timeout on key dispatching during instrumentation.
341    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
342
343    // Amount of time we wait for observers to handle a user switch before
344    // giving up on them and unfreezing the screen.
345    static final int USER_SWITCH_TIMEOUT = 2*1000;
346
347    // Maximum number of users we allow to be running at a time.
348    static final int MAX_RUNNING_USERS = 3;
349
350    // How long to wait in getAssistContextExtras for the activity and foreground services
351    // to respond with the result.
352    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
353
354    // Maximum number of persisted Uri grants a package is allowed
355    static final int MAX_PERSISTED_URI_GRANTS = 128;
356
357    static final int MY_PID = Process.myPid();
358
359    static final String[] EMPTY_STRING_ARRAY = new String[0];
360
361    // How many bytes to write into the dropbox log before truncating
362    static final int DROPBOX_MAX_SIZE = 256 * 1024;
363
364    // Access modes for handleIncomingUser.
365    static final int ALLOW_NON_FULL = 0;
366    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
367    static final int ALLOW_FULL_ONLY = 2;
368
369    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
370
371    /** All system services */
372    SystemServiceManager mSystemServiceManager;
373
374    /** Run all ActivityStacks through this */
375    ActivityStackSupervisor mStackSupervisor;
376
377    public IntentFirewall mIntentFirewall;
378
379    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
380    // default actuion automatically.  Important for devices without direct input
381    // devices.
382    private boolean mShowDialogs = true;
383
384    BroadcastQueue mFgBroadcastQueue;
385    BroadcastQueue mBgBroadcastQueue;
386    // Convenient for easy iteration over the queues. Foreground is first
387    // so that dispatch of foreground broadcasts gets precedence.
388    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
389
390    BroadcastQueue broadcastQueueForIntent(Intent intent) {
391        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
392        if (DEBUG_BACKGROUND_BROADCAST) {
393            Slog.i(TAG, "Broadcast intent " + intent + " on "
394                    + (isFg ? "foreground" : "background")
395                    + " queue");
396        }
397        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
398    }
399
400    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
401        for (BroadcastQueue queue : mBroadcastQueues) {
402            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
403            if (r != null) {
404                return r;
405            }
406        }
407        return null;
408    }
409
410    /**
411     * Activity we have told the window manager to have key focus.
412     */
413    ActivityRecord mFocusedActivity = null;
414
415    /**
416     * List of intents that were used to start the most recent tasks.
417     */
418    ArrayList<TaskRecord> mRecentTasks;
419    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
420
421    /**
422     * For addAppTask: cached of the last activity component that was added.
423     */
424    ComponentName mLastAddedTaskComponent;
425
426    /**
427     * For addAppTask: cached of the last activity uid that was added.
428     */
429    int mLastAddedTaskUid;
430
431    /**
432     * For addAppTask: cached of the last ActivityInfo that was added.
433     */
434    ActivityInfo mLastAddedTaskActivity;
435
436    public class PendingAssistExtras extends Binder implements Runnable {
437        public final ActivityRecord activity;
438        public boolean haveResult = false;
439        public Bundle result = null;
440        public PendingAssistExtras(ActivityRecord _activity) {
441            activity = _activity;
442        }
443        @Override
444        public void run() {
445            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
446            synchronized (this) {
447                haveResult = true;
448                notifyAll();
449            }
450        }
451    }
452
453    final ArrayList<PendingAssistExtras> mPendingAssistExtras
454            = new ArrayList<PendingAssistExtras>();
455
456    /**
457     * Process management.
458     */
459    final ProcessList mProcessList = new ProcessList();
460
461    /**
462     * All of the applications we currently have running organized by name.
463     * The keys are strings of the application package name (as
464     * returned by the package manager), and the keys are ApplicationRecord
465     * objects.
466     */
467    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
468
469    /**
470     * Tracking long-term execution of processes to look for abuse and other
471     * bad app behavior.
472     */
473    final ProcessStatsService mProcessStats;
474
475    /**
476     * The currently running isolated processes.
477     */
478    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
479
480    /**
481     * Counter for assigning isolated process uids, to avoid frequently reusing the
482     * same ones.
483     */
484    int mNextIsolatedProcessUid = 0;
485
486    /**
487     * The currently running heavy-weight process, if any.
488     */
489    ProcessRecord mHeavyWeightProcess = null;
490
491    /**
492     * The last time that various processes have crashed.
493     */
494    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
495
496    /**
497     * Information about a process that is currently marked as bad.
498     */
499    static final class BadProcessInfo {
500        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
501            this.time = time;
502            this.shortMsg = shortMsg;
503            this.longMsg = longMsg;
504            this.stack = stack;
505        }
506
507        final long time;
508        final String shortMsg;
509        final String longMsg;
510        final String stack;
511    }
512
513    /**
514     * Set of applications that we consider to be bad, and will reject
515     * incoming broadcasts from (which the user has no control over).
516     * Processes are added to this set when they have crashed twice within
517     * a minimum amount of time; they are removed from it when they are
518     * later restarted (hopefully due to some user action).  The value is the
519     * time it was added to the list.
520     */
521    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
522
523    /**
524     * All of the processes we currently have running organized by pid.
525     * The keys are the pid running the application.
526     *
527     * <p>NOTE: This object is protected by its own lock, NOT the global
528     * activity manager lock!
529     */
530    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
531
532    /**
533     * All of the processes that have been forced to be foreground.  The key
534     * is the pid of the caller who requested it (we hold a death
535     * link on it).
536     */
537    abstract class ForegroundToken implements IBinder.DeathRecipient {
538        int pid;
539        IBinder token;
540    }
541    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
542
543    /**
544     * List of records for processes that someone had tried to start before the
545     * system was ready.  We don't start them at that point, but ensure they
546     * are started by the time booting is complete.
547     */
548    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
549
550    /**
551     * List of persistent applications that are in the process
552     * of being started.
553     */
554    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * Processes that are being forcibly torn down.
558     */
559    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
560
561    /**
562     * List of running applications, sorted by recent usage.
563     * The first entry in the list is the least recently used.
564     */
565    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Where in mLruProcesses that the processes hosting activities start.
569     */
570    int mLruProcessActivityStart = 0;
571
572    /**
573     * Where in mLruProcesses that the processes hosting services start.
574     * This is after (lower index) than mLruProcessesActivityStart.
575     */
576    int mLruProcessServiceStart = 0;
577
578    /**
579     * List of processes that should gc as soon as things are idle.
580     */
581    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
582
583    /**
584     * Processes we want to collect PSS data from.
585     */
586    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
587
588    /**
589     * Last time we requested PSS data of all processes.
590     */
591    long mLastFullPssTime = SystemClock.uptimeMillis();
592
593    /**
594     * If set, the next time we collect PSS data we should do a full collection
595     * with data from native processes and the kernel.
596     */
597    boolean mFullPssPending = false;
598
599    /**
600     * This is the process holding what we currently consider to be
601     * the "home" activity.
602     */
603    ProcessRecord mHomeProcess;
604
605    /**
606     * This is the process holding the activity the user last visited that
607     * is in a different process from the one they are currently in.
608     */
609    ProcessRecord mPreviousProcess;
610
611    /**
612     * The time at which the previous process was last visible.
613     */
614    long mPreviousProcessVisibleTime;
615
616    /**
617     * Which uses have been started, so are allowed to run code.
618     */
619    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
620
621    /**
622     * LRU list of history of current users.  Most recently current is at the end.
623     */
624    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
625
626    /**
627     * Constant array of the users that are currently started.
628     */
629    int[] mStartedUserArray = new int[] { 0 };
630
631    /**
632     * Registered observers of the user switching mechanics.
633     */
634    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
635            = new RemoteCallbackList<IUserSwitchObserver>();
636
637    /**
638     * Currently active user switch.
639     */
640    Object mCurUserSwitchCallback;
641
642    /**
643     * Packages that the user has asked to have run in screen size
644     * compatibility mode instead of filling the screen.
645     */
646    final CompatModePackages mCompatModePackages;
647
648    /**
649     * Set of IntentSenderRecord objects that are currently active.
650     */
651    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
652            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
653
654    /**
655     * Fingerprints (hashCode()) of stack traces that we've
656     * already logged DropBox entries for.  Guarded by itself.  If
657     * something (rogue user app) forces this over
658     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
659     */
660    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
661    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
662
663    /**
664     * Strict Mode background batched logging state.
665     *
666     * The string buffer is guarded by itself, and its lock is also
667     * used to determine if another batched write is already
668     * in-flight.
669     */
670    private final StringBuilder mStrictModeBuffer = new StringBuilder();
671
672    /**
673     * Keeps track of all IIntentReceivers that have been registered for
674     * broadcasts.  Hash keys are the receiver IBinder, hash value is
675     * a ReceiverList.
676     */
677    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
678            new HashMap<IBinder, ReceiverList>();
679
680    /**
681     * Resolver for broadcast intents to registered receivers.
682     * Holds BroadcastFilter (subclass of IntentFilter).
683     */
684    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
685            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
686        @Override
687        protected boolean allowFilterResult(
688                BroadcastFilter filter, List<BroadcastFilter> dest) {
689            IBinder target = filter.receiverList.receiver.asBinder();
690            for (int i=dest.size()-1; i>=0; i--) {
691                if (dest.get(i).receiverList.receiver.asBinder() == target) {
692                    return false;
693                }
694            }
695            return true;
696        }
697
698        @Override
699        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
700            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
701                    || userId == filter.owningUserId) {
702                return super.newResult(filter, match, userId);
703            }
704            return null;
705        }
706
707        @Override
708        protected BroadcastFilter[] newArray(int size) {
709            return new BroadcastFilter[size];
710        }
711
712        @Override
713        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
714            return packageName.equals(filter.packageName);
715        }
716    };
717
718    /**
719     * State of all active sticky broadcasts per user.  Keys are the action of the
720     * sticky Intent, values are an ArrayList of all broadcasted intents with
721     * that action (which should usually be one).  The SparseArray is keyed
722     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
723     * for stickies that are sent to all users.
724     */
725    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
726            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
727
728    final ActiveServices mServices;
729
730    /**
731     * Backup/restore process management
732     */
733    String mBackupAppName = null;
734    BackupRecord mBackupTarget = null;
735
736    final ProviderMap mProviderMap;
737
738    /**
739     * List of content providers who have clients waiting for them.  The
740     * application is currently being launched and the provider will be
741     * removed from this list once it is published.
742     */
743    final ArrayList<ContentProviderRecord> mLaunchingProviders
744            = new ArrayList<ContentProviderRecord>();
745
746    /**
747     * File storing persisted {@link #mGrantedUriPermissions}.
748     */
749    private final AtomicFile mGrantFile;
750
751    /** XML constants used in {@link #mGrantFile} */
752    private static final String TAG_URI_GRANTS = "uri-grants";
753    private static final String TAG_URI_GRANT = "uri-grant";
754    private static final String ATTR_USER_HANDLE = "userHandle";
755    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
756    private static final String ATTR_TARGET_USER_ID = "targetUserId";
757    private static final String ATTR_SOURCE_PKG = "sourcePkg";
758    private static final String ATTR_TARGET_PKG = "targetPkg";
759    private static final String ATTR_URI = "uri";
760    private static final String ATTR_MODE_FLAGS = "modeFlags";
761    private static final String ATTR_CREATED_TIME = "createdTime";
762    private static final String ATTR_PREFIX = "prefix";
763
764    /**
765     * Global set of specific {@link Uri} permissions that have been granted.
766     * This optimized lookup structure maps from {@link UriPermission#targetUid}
767     * to {@link UriPermission#uri} to {@link UriPermission}.
768     */
769    @GuardedBy("this")
770    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
771            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
772
773    public static class GrantUri {
774        public final int sourceUserId;
775        public final Uri uri;
776        public boolean prefix;
777
778        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
779            this.sourceUserId = sourceUserId;
780            this.uri = uri;
781            this.prefix = prefix;
782        }
783
784        @Override
785        public int hashCode() {
786            return toString().hashCode();
787        }
788
789        @Override
790        public boolean equals(Object o) {
791            if (o instanceof GrantUri) {
792                GrantUri other = (GrantUri) o;
793                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
794                        && prefix == other.prefix;
795            }
796            return false;
797        }
798
799        @Override
800        public String toString() {
801            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
802            if (prefix) result += " [prefix]";
803            return result;
804        }
805
806        public String toSafeString() {
807            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
808            if (prefix) result += " [prefix]";
809            return result;
810        }
811
812        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
813            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
814                    ContentProvider.getUriWithoutUserId(uri), false);
815        }
816    }
817
818    CoreSettingsObserver mCoreSettingsObserver;
819
820    /**
821     * Thread-local storage used to carry caller permissions over through
822     * indirect content-provider access.
823     */
824    private class Identity {
825        public int pid;
826        public int uid;
827
828        Identity(int _pid, int _uid) {
829            pid = _pid;
830            uid = _uid;
831        }
832    }
833
834    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
835
836    /**
837     * All information we have collected about the runtime performance of
838     * any user id that can impact battery performance.
839     */
840    final BatteryStatsService mBatteryStatsService;
841
842    /**
843     * Information about component usage
844     */
845    UsageStatsManagerInternal mUsageStatsService;
846
847    /**
848     * Information about and control over application operations
849     */
850    final AppOpsService mAppOpsService;
851
852    /**
853     * Save recent tasks information across reboots.
854     */
855    final TaskPersister mTaskPersister;
856
857    /**
858     * Current configuration information.  HistoryRecord objects are given
859     * a reference to this object to indicate which configuration they are
860     * currently running in, so this object must be kept immutable.
861     */
862    Configuration mConfiguration = new Configuration();
863
864    /**
865     * Current sequencing integer of the configuration, for skipping old
866     * configurations.
867     */
868    int mConfigurationSeq = 0;
869
870    /**
871     * Hardware-reported OpenGLES version.
872     */
873    final int GL_ES_VERSION;
874
875    /**
876     * List of initialization arguments to pass to all processes when binding applications to them.
877     * For example, references to the commonly used services.
878     */
879    HashMap<String, IBinder> mAppBindArgs;
880
881    /**
882     * Temporary to avoid allocations.  Protected by main lock.
883     */
884    final StringBuilder mStringBuilder = new StringBuilder(256);
885
886    /**
887     * Used to control how we initialize the service.
888     */
889    ComponentName mTopComponent;
890    String mTopAction = Intent.ACTION_MAIN;
891    String mTopData;
892    boolean mProcessesReady = false;
893    boolean mSystemReady = false;
894    boolean mBooting = false;
895    boolean mCallFinishBooting = false;
896    boolean mBootAnimationComplete = false;
897    boolean mWaitingUpdate = false;
898    boolean mDidUpdate = false;
899    boolean mOnBattery = false;
900    boolean mLaunchWarningShown = false;
901
902    Context mContext;
903
904    int mFactoryTest;
905
906    boolean mCheckedForSetup;
907
908    /**
909     * The time at which we will allow normal application switches again,
910     * after a call to {@link #stopAppSwitches()}.
911     */
912    long mAppSwitchesAllowedTime;
913
914    /**
915     * This is set to true after the first switch after mAppSwitchesAllowedTime
916     * is set; any switches after that will clear the time.
917     */
918    boolean mDidAppSwitch;
919
920    /**
921     * Last time (in realtime) at which we checked for power usage.
922     */
923    long mLastPowerCheckRealtime;
924
925    /**
926     * Last time (in uptime) at which we checked for power usage.
927     */
928    long mLastPowerCheckUptime;
929
930    /**
931     * Set while we are wanting to sleep, to prevent any
932     * activities from being started/resumed.
933     */
934    private boolean mSleeping = false;
935
936    /**
937     * Set while we are running a voice interaction.  This overrides
938     * sleeping while it is active.
939     */
940    private boolean mRunningVoice = false;
941
942    /**
943     * State of external calls telling us if the device is asleep.
944     */
945    private boolean mWentToSleep = false;
946
947    /**
948     * State of external call telling us if the lock screen is shown.
949     */
950    private boolean mLockScreenShown = false;
951
952    /**
953     * Set if we are shutting down the system, similar to sleeping.
954     */
955    boolean mShuttingDown = false;
956
957    /**
958     * Current sequence id for oom_adj computation traversal.
959     */
960    int mAdjSeq = 0;
961
962    /**
963     * Current sequence id for process LRU updating.
964     */
965    int mLruSeq = 0;
966
967    /**
968     * Keep track of the non-cached/empty process we last found, to help
969     * determine how to distribute cached/empty processes next time.
970     */
971    int mNumNonCachedProcs = 0;
972
973    /**
974     * Keep track of the number of cached hidden procs, to balance oom adj
975     * distribution between those and empty procs.
976     */
977    int mNumCachedHiddenProcs = 0;
978
979    /**
980     * Keep track of the number of service processes we last found, to
981     * determine on the next iteration which should be B services.
982     */
983    int mNumServiceProcs = 0;
984    int mNewNumAServiceProcs = 0;
985    int mNewNumServiceProcs = 0;
986
987    /**
988     * Allow the current computed overall memory level of the system to go down?
989     * This is set to false when we are killing processes for reasons other than
990     * memory management, so that the now smaller process list will not be taken as
991     * an indication that memory is tighter.
992     */
993    boolean mAllowLowerMemLevel = false;
994
995    /**
996     * The last computed memory level, for holding when we are in a state that
997     * processes are going away for other reasons.
998     */
999    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1000
1001    /**
1002     * The last total number of process we have, to determine if changes actually look
1003     * like a shrinking number of process due to lower RAM.
1004     */
1005    int mLastNumProcesses;
1006
1007    /**
1008     * The uptime of the last time we performed idle maintenance.
1009     */
1010    long mLastIdleTime = SystemClock.uptimeMillis();
1011
1012    /**
1013     * Total time spent with RAM that has been added in the past since the last idle time.
1014     */
1015    long mLowRamTimeSinceLastIdle = 0;
1016
1017    /**
1018     * If RAM is currently low, when that horrible situation started.
1019     */
1020    long mLowRamStartTime = 0;
1021
1022    /**
1023     * For reporting to battery stats the current top application.
1024     */
1025    private String mCurResumedPackage = null;
1026    private int mCurResumedUid = -1;
1027
1028    /**
1029     * For reporting to battery stats the apps currently running foreground
1030     * service.  The ProcessMap is package/uid tuples; each of these contain
1031     * an array of the currently foreground processes.
1032     */
1033    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1034            = new ProcessMap<ArrayList<ProcessRecord>>();
1035
1036    /**
1037     * This is set if we had to do a delayed dexopt of an app before launching
1038     * it, to increase the ANR timeouts in that case.
1039     */
1040    boolean mDidDexOpt;
1041
1042    /**
1043     * Set if the systemServer made a call to enterSafeMode.
1044     */
1045    boolean mSafeMode;
1046
1047    String mDebugApp = null;
1048    boolean mWaitForDebugger = false;
1049    boolean mDebugTransient = false;
1050    String mOrigDebugApp = null;
1051    boolean mOrigWaitForDebugger = false;
1052    boolean mAlwaysFinishActivities = false;
1053    IActivityController mController = null;
1054    String mProfileApp = null;
1055    ProcessRecord mProfileProc = null;
1056    String mProfileFile;
1057    ParcelFileDescriptor mProfileFd;
1058    int mSamplingInterval = 0;
1059    boolean mAutoStopProfiler = false;
1060    int mProfileType = 0;
1061    String mOpenGlTraceApp = null;
1062
1063    static class ProcessChangeItem {
1064        static final int CHANGE_ACTIVITIES = 1<<0;
1065        static final int CHANGE_PROCESS_STATE = 1<<1;
1066        int changes;
1067        int uid;
1068        int pid;
1069        int processState;
1070        boolean foregroundActivities;
1071    }
1072
1073    final RemoteCallbackList<IProcessObserver> mProcessObservers
1074            = new RemoteCallbackList<IProcessObserver>();
1075    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1076
1077    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1078            = new ArrayList<ProcessChangeItem>();
1079    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1080            = new ArrayList<ProcessChangeItem>();
1081
1082    /**
1083     * Runtime CPU use collection thread.  This object's lock is used to
1084     * perform synchronization with the thread (notifying it to run).
1085     */
1086    final Thread mProcessCpuThread;
1087
1088    /**
1089     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1090     * Must acquire this object's lock when accessing it.
1091     * NOTE: this lock will be held while doing long operations (trawling
1092     * through all processes in /proc), so it should never be acquired by
1093     * any critical paths such as when holding the main activity manager lock.
1094     */
1095    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1096            MONITOR_THREAD_CPU_USAGE);
1097    final AtomicLong mLastCpuTime = new AtomicLong(0);
1098    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1099
1100    long mLastWriteTime = 0;
1101
1102    /**
1103     * Used to retain an update lock when the foreground activity is in
1104     * immersive mode.
1105     */
1106    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1107
1108    /**
1109     * Set to true after the system has finished booting.
1110     */
1111    boolean mBooted = false;
1112
1113    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1114    int mProcessLimitOverride = -1;
1115
1116    WindowManagerService mWindowManager;
1117
1118    final ActivityThread mSystemThread;
1119
1120    // Holds the current foreground user's id
1121    int mCurrentUserId = 0;
1122    // Holds the target user's id during a user switch
1123    int mTargetUserId = UserHandle.USER_NULL;
1124    // If there are multiple profiles for the current user, their ids are here
1125    // Currently only the primary user can have managed profiles
1126    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1127
1128    /**
1129     * Mapping from each known user ID to the profile group ID it is associated with.
1130     */
1131    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1132
1133    private UserManagerService mUserManager;
1134
1135    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1136        final ProcessRecord mApp;
1137        final int mPid;
1138        final IApplicationThread mAppThread;
1139
1140        AppDeathRecipient(ProcessRecord app, int pid,
1141                IApplicationThread thread) {
1142            if (localLOGV) Slog.v(
1143                TAG, "New death recipient " + this
1144                + " for thread " + thread.asBinder());
1145            mApp = app;
1146            mPid = pid;
1147            mAppThread = thread;
1148        }
1149
1150        @Override
1151        public void binderDied() {
1152            if (localLOGV) Slog.v(
1153                TAG, "Death received in " + this
1154                + " for thread " + mAppThread.asBinder());
1155            synchronized(ActivityManagerService.this) {
1156                appDiedLocked(mApp, mPid, mAppThread);
1157            }
1158        }
1159    }
1160
1161    static final int SHOW_ERROR_MSG = 1;
1162    static final int SHOW_NOT_RESPONDING_MSG = 2;
1163    static final int SHOW_FACTORY_ERROR_MSG = 3;
1164    static final int UPDATE_CONFIGURATION_MSG = 4;
1165    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1166    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1167    static final int SERVICE_TIMEOUT_MSG = 12;
1168    static final int UPDATE_TIME_ZONE = 13;
1169    static final int SHOW_UID_ERROR_MSG = 14;
1170    static final int IM_FEELING_LUCKY_MSG = 15;
1171    static final int PROC_START_TIMEOUT_MSG = 20;
1172    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1173    static final int KILL_APPLICATION_MSG = 22;
1174    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1175    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1176    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1177    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1178    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1179    static final int CLEAR_DNS_CACHE_MSG = 28;
1180    static final int UPDATE_HTTP_PROXY_MSG = 29;
1181    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1182    static final int DISPATCH_PROCESSES_CHANGED = 31;
1183    static final int DISPATCH_PROCESS_DIED = 32;
1184    static final int REPORT_MEM_USAGE_MSG = 33;
1185    static final int REPORT_USER_SWITCH_MSG = 34;
1186    static final int CONTINUE_USER_SWITCH_MSG = 35;
1187    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1188    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1189    static final int PERSIST_URI_GRANTS_MSG = 38;
1190    static final int REQUEST_ALL_PSS_MSG = 39;
1191    static final int START_PROFILES_MSG = 40;
1192    static final int UPDATE_TIME = 41;
1193    static final int SYSTEM_USER_START_MSG = 42;
1194    static final int SYSTEM_USER_CURRENT_MSG = 43;
1195    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1196    static final int FINISH_BOOTING_MSG = 45;
1197    static final int START_USER_SWITCH_MSG = 46;
1198    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1199
1200    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1201    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1202    static final int FIRST_COMPAT_MODE_MSG = 300;
1203    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1204
1205    AlertDialog mUidAlert;
1206    CompatModeDialog mCompatModeDialog;
1207    long mLastMemUsageReportTime = 0;
1208
1209    private LockToAppRequestDialog mLockToAppRequest;
1210
1211    /**
1212     * Flag whether the current user is a "monkey", i.e. whether
1213     * the UI is driven by a UI automation tool.
1214     */
1215    private boolean mUserIsMonkey;
1216
1217    /** Flag whether the device has a Recents UI */
1218    boolean mHasRecents;
1219
1220    /** The dimensions of the thumbnails in the Recents UI. */
1221    int mThumbnailWidth;
1222    int mThumbnailHeight;
1223
1224    final ServiceThread mHandlerThread;
1225    final MainHandler mHandler;
1226
1227    final class MainHandler extends Handler {
1228        public MainHandler(Looper looper) {
1229            super(looper, null, true);
1230        }
1231
1232        @Override
1233        public void handleMessage(Message msg) {
1234            switch (msg.what) {
1235            case SHOW_ERROR_MSG: {
1236                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1238                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1239                synchronized (ActivityManagerService.this) {
1240                    ProcessRecord proc = (ProcessRecord)data.get("app");
1241                    AppErrorResult res = (AppErrorResult) data.get("result");
1242                    if (proc != null && proc.crashDialog != null) {
1243                        Slog.e(TAG, "App already has crash dialog: " + proc);
1244                        if (res != null) {
1245                            res.set(0);
1246                        }
1247                        return;
1248                    }
1249                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1250                            >= Process.FIRST_APPLICATION_UID
1251                            && proc.pid != MY_PID);
1252                    for (int userId : mCurrentProfileIds) {
1253                        isBackground &= (proc.userId != userId);
1254                    }
1255                    if (isBackground && !showBackground) {
1256                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1257                        if (res != null) {
1258                            res.set(0);
1259                        }
1260                        return;
1261                    }
1262                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1263                        Dialog d = new AppErrorDialog(mContext,
1264                                ActivityManagerService.this, res, proc);
1265                        d.show();
1266                        proc.crashDialog = d;
1267                    } else {
1268                        // The device is asleep, so just pretend that the user
1269                        // saw a crash dialog and hit "force quit".
1270                        if (res != null) {
1271                            res.set(0);
1272                        }
1273                    }
1274                }
1275
1276                ensureBootCompleted();
1277            } break;
1278            case SHOW_NOT_RESPONDING_MSG: {
1279                synchronized (ActivityManagerService.this) {
1280                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1281                    ProcessRecord proc = (ProcessRecord)data.get("app");
1282                    if (proc != null && proc.anrDialog != null) {
1283                        Slog.e(TAG, "App already has anr dialog: " + proc);
1284                        return;
1285                    }
1286
1287                    Intent intent = new Intent("android.intent.action.ANR");
1288                    if (!mProcessesReady) {
1289                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1290                                | Intent.FLAG_RECEIVER_FOREGROUND);
1291                    }
1292                    broadcastIntentLocked(null, null, intent,
1293                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1294                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1295
1296                    if (mShowDialogs) {
1297                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1298                                mContext, proc, (ActivityRecord)data.get("activity"),
1299                                msg.arg1 != 0);
1300                        d.show();
1301                        proc.anrDialog = d;
1302                    } else {
1303                        // Just kill the app if there is no dialog to be shown.
1304                        killAppAtUsersRequest(proc, null);
1305                    }
1306                }
1307
1308                ensureBootCompleted();
1309            } break;
1310            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1311                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord proc = (ProcessRecord) data.get("app");
1314                    if (proc == null) {
1315                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1316                        break;
1317                    }
1318                    if (proc.crashDialog != null) {
1319                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1320                        return;
1321                    }
1322                    AppErrorResult res = (AppErrorResult) data.get("result");
1323                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1324                        Dialog d = new StrictModeViolationDialog(mContext,
1325                                ActivityManagerService.this, res, proc);
1326                        d.show();
1327                        proc.crashDialog = d;
1328                    } else {
1329                        // The device is asleep, so just pretend that the user
1330                        // saw a crash dialog and hit "force quit".
1331                        res.set(0);
1332                    }
1333                }
1334                ensureBootCompleted();
1335            } break;
1336            case SHOW_FACTORY_ERROR_MSG: {
1337                Dialog d = new FactoryErrorDialog(
1338                    mContext, msg.getData().getCharSequence("msg"));
1339                d.show();
1340                ensureBootCompleted();
1341            } break;
1342            case UPDATE_CONFIGURATION_MSG: {
1343                final ContentResolver resolver = mContext.getContentResolver();
1344                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1345            } break;
1346            case GC_BACKGROUND_PROCESSES_MSG: {
1347                synchronized (ActivityManagerService.this) {
1348                    performAppGcsIfAppropriateLocked();
1349                }
1350            } break;
1351            case WAIT_FOR_DEBUGGER_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    ProcessRecord app = (ProcessRecord)msg.obj;
1354                    if (msg.arg1 != 0) {
1355                        if (!app.waitedForDebugger) {
1356                            Dialog d = new AppWaitingForDebuggerDialog(
1357                                    ActivityManagerService.this,
1358                                    mContext, app);
1359                            app.waitDialog = d;
1360                            app.waitedForDebugger = true;
1361                            d.show();
1362                        }
1363                    } else {
1364                        if (app.waitDialog != null) {
1365                            app.waitDialog.dismiss();
1366                            app.waitDialog = null;
1367                        }
1368                    }
1369                }
1370            } break;
1371            case SERVICE_TIMEOUT_MSG: {
1372                if (mDidDexOpt) {
1373                    mDidDexOpt = false;
1374                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1375                    nmsg.obj = msg.obj;
1376                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1377                    return;
1378                }
1379                mServices.serviceTimeout((ProcessRecord)msg.obj);
1380            } break;
1381            case UPDATE_TIME_ZONE: {
1382                synchronized (ActivityManagerService.this) {
1383                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1384                        ProcessRecord r = mLruProcesses.get(i);
1385                        if (r.thread != null) {
1386                            try {
1387                                r.thread.updateTimeZone();
1388                            } catch (RemoteException ex) {
1389                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case CLEAR_DNS_CACHE_MSG: {
1396                synchronized (ActivityManagerService.this) {
1397                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1398                        ProcessRecord r = mLruProcesses.get(i);
1399                        if (r.thread != null) {
1400                            try {
1401                                r.thread.clearDnsCache();
1402                            } catch (RemoteException ex) {
1403                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1404                            }
1405                        }
1406                    }
1407                }
1408            } break;
1409            case UPDATE_HTTP_PROXY_MSG: {
1410                ProxyInfo proxy = (ProxyInfo)msg.obj;
1411                String host = "";
1412                String port = "";
1413                String exclList = "";
1414                Uri pacFileUrl = Uri.EMPTY;
1415                if (proxy != null) {
1416                    host = proxy.getHost();
1417                    port = Integer.toString(proxy.getPort());
1418                    exclList = proxy.getExclusionListAsString();
1419                    pacFileUrl = proxy.getPacFileUrl();
1420                }
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update http proxy for: " +
1429                                        r.info.processName);
1430                            }
1431                        }
1432                    }
1433                }
1434            } break;
1435            case SHOW_UID_ERROR_MSG: {
1436                String title = "System UIDs Inconsistent";
1437                String text = "UIDs on the system are inconsistent, you need to wipe your"
1438                        + " data partition or your device will be unstable.";
1439                Log.e(TAG, title + ": " + text);
1440                if (mShowDialogs) {
1441                    // XXX This is a temporary dialog, no need to localize.
1442                    AlertDialog d = new BaseErrorDialog(mContext);
1443                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1444                    d.setCancelable(false);
1445                    d.setTitle(title);
1446                    d.setMessage(text);
1447                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1448                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1449                    mUidAlert = d;
1450                    d.show();
1451                }
1452            } break;
1453            case IM_FEELING_LUCKY_MSG: {
1454                if (mUidAlert != null) {
1455                    mUidAlert.dismiss();
1456                    mUidAlert = null;
1457                }
1458            } break;
1459            case PROC_START_TIMEOUT_MSG: {
1460                if (mDidDexOpt) {
1461                    mDidDexOpt = false;
1462                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1463                    nmsg.obj = msg.obj;
1464                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1465                    return;
1466                }
1467                ProcessRecord app = (ProcessRecord)msg.obj;
1468                synchronized (ActivityManagerService.this) {
1469                    processStartTimedOutLocked(app);
1470                }
1471            } break;
1472            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1473                synchronized (ActivityManagerService.this) {
1474                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1475                }
1476            } break;
1477            case KILL_APPLICATION_MSG: {
1478                synchronized (ActivityManagerService.this) {
1479                    int appid = msg.arg1;
1480                    boolean restart = (msg.arg2 == 1);
1481                    Bundle bundle = (Bundle)msg.obj;
1482                    String pkg = bundle.getString("pkg");
1483                    String reason = bundle.getString("reason");
1484                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1485                            false, UserHandle.USER_ALL, reason);
1486                }
1487            } break;
1488            case FINALIZE_PENDING_INTENT_MSG: {
1489                ((PendingIntentRecord)msg.obj).completeFinalize();
1490            } break;
1491            case POST_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496
1497                ActivityRecord root = (ActivityRecord)msg.obj;
1498                ProcessRecord process = root.app;
1499                if (process == null) {
1500                    return;
1501                }
1502
1503                try {
1504                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1505                    String text = mContext.getString(R.string.heavy_weight_notification,
1506                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1507                    Notification notification = new Notification();
1508                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1509                    notification.when = 0;
1510                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1511                    notification.tickerText = text;
1512                    notification.defaults = 0; // please be quiet
1513                    notification.sound = null;
1514                    notification.vibrate = null;
1515                    notification.color = mContext.getResources().getColor(
1516                            com.android.internal.R.color.system_notification_accent_color);
1517                    notification.setLatestEventInfo(context, text,
1518                            mContext.getText(R.string.heavy_weight_notification_detail),
1519                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1520                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1521                                    new UserHandle(root.userId)));
1522
1523                    try {
1524                        int[] outId = new int[1];
1525                        inm.enqueueNotificationWithTag("android", "android", null,
1526                                R.string.heavy_weight_notification,
1527                                notification, outId, root.userId);
1528                    } catch (RuntimeException e) {
1529                        Slog.w(ActivityManagerService.TAG,
1530                                "Error showing notification for heavy-weight app", e);
1531                    } catch (RemoteException e) {
1532                    }
1533                } catch (NameNotFoundException e) {
1534                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1535                }
1536            } break;
1537            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1538                INotificationManager inm = NotificationManager.getService();
1539                if (inm == null) {
1540                    return;
1541                }
1542                try {
1543                    inm.cancelNotificationWithTag("android", null,
1544                            R.string.heavy_weight_notification,  msg.arg1);
1545                } catch (RuntimeException e) {
1546                    Slog.w(ActivityManagerService.TAG,
1547                            "Error canceling notification for service", e);
1548                } catch (RemoteException e) {
1549                }
1550            } break;
1551            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1552                synchronized (ActivityManagerService.this) {
1553                    checkExcessivePowerUsageLocked(true);
1554                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1555                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1556                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1557                }
1558            } break;
1559            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    ActivityRecord ar = (ActivityRecord)msg.obj;
1562                    if (mCompatModeDialog != null) {
1563                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1564                                ar.info.applicationInfo.packageName)) {
1565                            return;
1566                        }
1567                        mCompatModeDialog.dismiss();
1568                        mCompatModeDialog = null;
1569                    }
1570                    if (ar != null && false) {
1571                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1572                                ar.packageName)) {
1573                            int mode = mCompatModePackages.computeCompatModeLocked(
1574                                    ar.info.applicationInfo);
1575                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1576                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1577                                mCompatModeDialog = new CompatModeDialog(
1578                                        ActivityManagerService.this, mContext,
1579                                        ar.info.applicationInfo);
1580                                mCompatModeDialog.show();
1581                            }
1582                        }
1583                    }
1584                }
1585                break;
1586            }
1587            case DISPATCH_PROCESSES_CHANGED: {
1588                dispatchProcessesChanged();
1589                break;
1590            }
1591            case DISPATCH_PROCESS_DIED: {
1592                final int pid = msg.arg1;
1593                final int uid = msg.arg2;
1594                dispatchProcessDied(pid, uid);
1595                break;
1596            }
1597            case REPORT_MEM_USAGE_MSG: {
1598                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1599                Thread thread = new Thread() {
1600                    @Override public void run() {
1601                        final SparseArray<ProcessMemInfo> infoMap
1602                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1603                        for (int i=0, N=memInfos.size(); i<N; i++) {
1604                            ProcessMemInfo mi = memInfos.get(i);
1605                            infoMap.put(mi.pid, mi);
1606                        }
1607                        updateCpuStatsNow();
1608                        synchronized (mProcessCpuTracker) {
1609                            final int N = mProcessCpuTracker.countStats();
1610                            for (int i=0; i<N; i++) {
1611                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1612                                if (st.vsize > 0) {
1613                                    long pss = Debug.getPss(st.pid, null);
1614                                    if (pss > 0) {
1615                                        if (infoMap.indexOfKey(st.pid) < 0) {
1616                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1617                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1618                                            mi.pss = pss;
1619                                            memInfos.add(mi);
1620                                        }
1621                                    }
1622                                }
1623                            }
1624                        }
1625
1626                        long totalPss = 0;
1627                        for (int i=0, N=memInfos.size(); i<N; i++) {
1628                            ProcessMemInfo mi = memInfos.get(i);
1629                            if (mi.pss == 0) {
1630                                mi.pss = Debug.getPss(mi.pid, null);
1631                            }
1632                            totalPss += mi.pss;
1633                        }
1634                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1635                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1636                                if (lhs.oomAdj != rhs.oomAdj) {
1637                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1638                                }
1639                                if (lhs.pss != rhs.pss) {
1640                                    return lhs.pss < rhs.pss ? 1 : -1;
1641                                }
1642                                return 0;
1643                            }
1644                        });
1645
1646                        StringBuilder tag = new StringBuilder(128);
1647                        StringBuilder stack = new StringBuilder(128);
1648                        tag.append("Low on memory -- ");
1649                        appendMemBucket(tag, totalPss, "total", false);
1650                        appendMemBucket(stack, totalPss, "total", true);
1651
1652                        StringBuilder logBuilder = new StringBuilder(1024);
1653                        logBuilder.append("Low on memory:\n");
1654
1655                        boolean firstLine = true;
1656                        int lastOomAdj = Integer.MIN_VALUE;
1657                        for (int i=0, N=memInfos.size(); i<N; i++) {
1658                            ProcessMemInfo mi = memInfos.get(i);
1659
1660                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1661                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1662                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1663                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1664                                if (lastOomAdj != mi.oomAdj) {
1665                                    lastOomAdj = mi.oomAdj;
1666                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1667                                        tag.append(" / ");
1668                                    }
1669                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1670                                        if (firstLine) {
1671                                            stack.append(":");
1672                                            firstLine = false;
1673                                        }
1674                                        stack.append("\n\t at ");
1675                                    } else {
1676                                        stack.append("$");
1677                                    }
1678                                } else {
1679                                    tag.append(" ");
1680                                    stack.append("$");
1681                                }
1682                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1683                                    appendMemBucket(tag, mi.pss, mi.name, false);
1684                                }
1685                                appendMemBucket(stack, mi.pss, mi.name, true);
1686                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1687                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1688                                    stack.append("(");
1689                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1690                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1691                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1692                                            stack.append(":");
1693                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1694                                        }
1695                                    }
1696                                    stack.append(")");
1697                                }
1698                            }
1699
1700                            logBuilder.append("  ");
1701                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1702                            logBuilder.append(' ');
1703                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1704                            logBuilder.append(' ');
1705                            ProcessList.appendRamKb(logBuilder, mi.pss);
1706                            logBuilder.append(" kB: ");
1707                            logBuilder.append(mi.name);
1708                            logBuilder.append(" (");
1709                            logBuilder.append(mi.pid);
1710                            logBuilder.append(") ");
1711                            logBuilder.append(mi.adjType);
1712                            logBuilder.append('\n');
1713                            if (mi.adjReason != null) {
1714                                logBuilder.append("                      ");
1715                                logBuilder.append(mi.adjReason);
1716                                logBuilder.append('\n');
1717                            }
1718                        }
1719
1720                        logBuilder.append("           ");
1721                        ProcessList.appendRamKb(logBuilder, totalPss);
1722                        logBuilder.append(" kB: TOTAL\n");
1723
1724                        long[] infos = new long[Debug.MEMINFO_COUNT];
1725                        Debug.getMemInfo(infos);
1726                        logBuilder.append("  MemInfo: ");
1727                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1728                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1729                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1730                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1731                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1732                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1733                            logBuilder.append("  ZRAM: ");
1734                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1735                            logBuilder.append(" kB RAM, ");
1736                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1737                            logBuilder.append(" kB swap total, ");
1738                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1739                            logBuilder.append(" kB swap free\n");
1740                        }
1741                        Slog.i(TAG, logBuilder.toString());
1742
1743                        StringBuilder dropBuilder = new StringBuilder(1024);
1744                        /*
1745                        StringWriter oomSw = new StringWriter();
1746                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1747                        StringWriter catSw = new StringWriter();
1748                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1749                        String[] emptyArgs = new String[] { };
1750                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1751                        oomPw.flush();
1752                        String oomString = oomSw.toString();
1753                        */
1754                        dropBuilder.append(stack);
1755                        dropBuilder.append('\n');
1756                        dropBuilder.append('\n');
1757                        dropBuilder.append(logBuilder);
1758                        dropBuilder.append('\n');
1759                        /*
1760                        dropBuilder.append(oomString);
1761                        dropBuilder.append('\n');
1762                        */
1763                        StringWriter catSw = new StringWriter();
1764                        synchronized (ActivityManagerService.this) {
1765                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1766                            String[] emptyArgs = new String[] { };
1767                            catPw.println();
1768                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1769                            catPw.println();
1770                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1771                                    false, false, null);
1772                            catPw.println();
1773                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1774                            catPw.flush();
1775                        }
1776                        dropBuilder.append(catSw.toString());
1777                        addErrorToDropBox("lowmem", null, "system_server", null,
1778                                null, tag.toString(), dropBuilder.toString(), null, null);
1779                        //Slog.i(TAG, "Sent to dropbox:");
1780                        //Slog.i(TAG, dropBuilder.toString());
1781                        synchronized (ActivityManagerService.this) {
1782                            long now = SystemClock.uptimeMillis();
1783                            if (mLastMemUsageReportTime < now) {
1784                                mLastMemUsageReportTime = now;
1785                            }
1786                        }
1787                    }
1788                };
1789                thread.start();
1790                break;
1791            }
1792            case START_USER_SWITCH_MSG: {
1793                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1794                break;
1795            }
1796            case REPORT_USER_SWITCH_MSG: {
1797                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case CONTINUE_USER_SWITCH_MSG: {
1801                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1802                break;
1803            }
1804            case USER_SWITCH_TIMEOUT_MSG: {
1805                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1806                break;
1807            }
1808            case IMMERSIVE_MODE_LOCK_MSG: {
1809                final boolean nextState = (msg.arg1 != 0);
1810                if (mUpdateLock.isHeld() != nextState) {
1811                    if (DEBUG_IMMERSIVE) {
1812                        final ActivityRecord r = (ActivityRecord) msg.obj;
1813                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1814                    }
1815                    if (nextState) {
1816                        mUpdateLock.acquire();
1817                    } else {
1818                        mUpdateLock.release();
1819                    }
1820                }
1821                break;
1822            }
1823            case PERSIST_URI_GRANTS_MSG: {
1824                writeGrantedUriPermissions();
1825                break;
1826            }
1827            case REQUEST_ALL_PSS_MSG: {
1828                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1829                break;
1830            }
1831            case START_PROFILES_MSG: {
1832                synchronized (ActivityManagerService.this) {
1833                    startProfilesLocked();
1834                }
1835                break;
1836            }
1837            case UPDATE_TIME: {
1838                synchronized (ActivityManagerService.this) {
1839                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1840                        ProcessRecord r = mLruProcesses.get(i);
1841                        if (r.thread != null) {
1842                            try {
1843                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1844                            } catch (RemoteException ex) {
1845                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1846                            }
1847                        }
1848                    }
1849                }
1850                break;
1851            }
1852            case SYSTEM_USER_START_MSG: {
1853                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1854                        Integer.toString(msg.arg1), msg.arg1);
1855                mSystemServiceManager.startUser(msg.arg1);
1856                break;
1857            }
1858            case SYSTEM_USER_CURRENT_MSG: {
1859                mBatteryStatsService.noteEvent(
1860                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1861                        Integer.toString(msg.arg2), msg.arg2);
1862                mBatteryStatsService.noteEvent(
1863                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1864                        Integer.toString(msg.arg1), msg.arg1);
1865                mSystemServiceManager.switchUser(msg.arg1);
1866                mLockToAppRequest.clearPrompt();
1867                break;
1868            }
1869            case ENTER_ANIMATION_COMPLETE_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1872                    if (r != null && r.app != null && r.app.thread != null) {
1873                        try {
1874                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1875                        } catch (RemoteException e) {
1876                        }
1877                    }
1878                }
1879                break;
1880            }
1881            case FINISH_BOOTING_MSG: {
1882                if (msg.arg1 != 0) {
1883                    finishBooting();
1884                }
1885                if (msg.arg2 != 0) {
1886                    enableScreenAfterBoot();
1887                }
1888                break;
1889            }
1890            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1891                try {
1892                    Locale l = (Locale) msg.obj;
1893                    IBinder service = ServiceManager.getService("mount");
1894                    IMountService mountService = IMountService.Stub.asInterface(service);
1895                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1896                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1897                } catch (RemoteException e) {
1898                    Log.e(TAG, "Error storing locale for decryption UI", e);
1899                }
1900                break;
1901            }
1902            }
1903        }
1904    };
1905
1906    static final int COLLECT_PSS_BG_MSG = 1;
1907
1908    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1909        @Override
1910        public void handleMessage(Message msg) {
1911            switch (msg.what) {
1912            case COLLECT_PSS_BG_MSG: {
1913                long start = SystemClock.uptimeMillis();
1914                MemInfoReader memInfo = null;
1915                synchronized (ActivityManagerService.this) {
1916                    if (mFullPssPending) {
1917                        mFullPssPending = false;
1918                        memInfo = new MemInfoReader();
1919                    }
1920                }
1921                if (memInfo != null) {
1922                    updateCpuStatsNow();
1923                    long nativeTotalPss = 0;
1924                    synchronized (mProcessCpuTracker) {
1925                        final int N = mProcessCpuTracker.countStats();
1926                        for (int j=0; j<N; j++) {
1927                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1928                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1929                                // This is definitely an application process; skip it.
1930                                continue;
1931                            }
1932                            synchronized (mPidsSelfLocked) {
1933                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1934                                    // This is one of our own processes; skip it.
1935                                    continue;
1936                                }
1937                            }
1938                            nativeTotalPss += Debug.getPss(st.pid, null);
1939                        }
1940                    }
1941                    memInfo.readMemInfo();
1942                    synchronized (ActivityManagerService.this) {
1943                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1944                                + (SystemClock.uptimeMillis()-start) + "ms");
1945                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1946                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1947                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1948                                        +memInfo.getSlabSizeKb(),
1949                                nativeTotalPss);
1950                    }
1951                }
1952
1953                int i=0, num=0;
1954                long[] tmp = new long[1];
1955                do {
1956                    ProcessRecord proc;
1957                    int procState;
1958                    int pid;
1959                    synchronized (ActivityManagerService.this) {
1960                        if (i >= mPendingPssProcesses.size()) {
1961                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1962                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1963                            mPendingPssProcesses.clear();
1964                            return;
1965                        }
1966                        proc = mPendingPssProcesses.get(i);
1967                        procState = proc.pssProcState;
1968                        if (proc.thread != null && procState == proc.setProcState) {
1969                            pid = proc.pid;
1970                        } else {
1971                            proc = null;
1972                            pid = 0;
1973                        }
1974                        i++;
1975                    }
1976                    if (proc != null) {
1977                        long pss = Debug.getPss(pid, tmp);
1978                        synchronized (ActivityManagerService.this) {
1979                            if (proc.thread != null && proc.setProcState == procState
1980                                    && proc.pid == pid) {
1981                                num++;
1982                                proc.lastPssTime = SystemClock.uptimeMillis();
1983                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1984                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1985                                        + ": " + pss + " lastPss=" + proc.lastPss
1986                                        + " state=" + ProcessList.makeProcStateString(procState));
1987                                if (proc.initialIdlePss == 0) {
1988                                    proc.initialIdlePss = pss;
1989                                }
1990                                proc.lastPss = pss;
1991                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1992                                    proc.lastCachedPss = pss;
1993                                }
1994                            }
1995                        }
1996                    }
1997                } while (true);
1998            }
1999            }
2000        }
2001    };
2002
2003    /**
2004     * Monitor for package changes and update our internal state.
2005     */
2006    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2007        @Override
2008        public void onPackageRemoved(String packageName, int uid) {
2009            // Remove all tasks with activities in the specified package from the list of recent tasks
2010            final int eventUserId = getChangingUserId();
2011            synchronized (ActivityManagerService.this) {
2012                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2013                    TaskRecord tr = mRecentTasks.get(i);
2014                    if (tr.userId != eventUserId) continue;
2015
2016                    ComponentName cn = tr.intent.getComponent();
2017                    if (cn != null && cn.getPackageName().equals(packageName)) {
2018                        // If the package name matches, remove the task and kill the process
2019                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2020                    }
2021                }
2022            }
2023        }
2024
2025        @Override
2026        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2027            onPackageModified(packageName);
2028            return true;
2029        }
2030
2031        @Override
2032        public void onPackageModified(String packageName) {
2033            final int eventUserId = getChangingUserId();
2034            final PackageManager pm = mContext.getPackageManager();
2035            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2036                    new ArrayList<Pair<Intent, Integer>>();
2037            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2038            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2039            // Copy the list of recent tasks so that we don't hold onto the lock on
2040            // ActivityManagerService for long periods while checking if components exist.
2041            synchronized (ActivityManagerService.this) {
2042                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2043                    TaskRecord tr = mRecentTasks.get(i);
2044                    if (tr.userId != eventUserId) continue;
2045
2046                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2047                }
2048            }
2049            // Check the recent tasks and filter out all tasks with components that no longer exist.
2050            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2051                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2052                ComponentName cn = p.first.getComponent();
2053                if (cn != null && cn.getPackageName().equals(packageName)) {
2054                    if (componentsKnownToExist.contains(cn)) {
2055                        // If we know that the component still exists in the package, then skip
2056                        continue;
2057                    }
2058                    try {
2059                        ActivityInfo info = pm.getActivityInfo(cn, eventUserId);
2060                        if (info != null && info.isEnabled()) {
2061                            componentsKnownToExist.add(cn);
2062                        } else {
2063                            tasksToRemove.add(p.second);
2064                        }
2065                    } catch (Exception e) {}
2066                }
2067            }
2068            // Prune all the tasks with removed components from the list of recent tasks
2069            synchronized (ActivityManagerService.this) {
2070                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2071                    // Remove the task but don't kill the process (since other components in that
2072                    // package may still be running and in the background)
2073                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2074                }
2075            }
2076        }
2077
2078        @Override
2079        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2080            // Force stop the specified packages
2081            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2082            if (packages != null) {
2083                for (String pkg : packages) {
2084                    synchronized (ActivityManagerService.this) {
2085                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2086                                userId, "finished booting")) {
2087                            return true;
2088                        }
2089                    }
2090                }
2091            }
2092            return false;
2093        }
2094    };
2095
2096    public void setSystemProcess() {
2097        try {
2098            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2099            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2100            ServiceManager.addService("meminfo", new MemBinder(this));
2101            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2102            ServiceManager.addService("dbinfo", new DbBinder(this));
2103            if (MONITOR_CPU_USAGE) {
2104                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2105            }
2106            ServiceManager.addService("permission", new PermissionController(this));
2107
2108            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2109                    "android", STOCK_PM_FLAGS);
2110            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2111
2112            synchronized (this) {
2113                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2114                app.persistent = true;
2115                app.pid = MY_PID;
2116                app.maxAdj = ProcessList.SYSTEM_ADJ;
2117                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2118                mProcessNames.put(app.processName, app.uid, app);
2119                synchronized (mPidsSelfLocked) {
2120                    mPidsSelfLocked.put(app.pid, app);
2121                }
2122                updateLruProcessLocked(app, false, null);
2123                updateOomAdjLocked();
2124            }
2125        } catch (PackageManager.NameNotFoundException e) {
2126            throw new RuntimeException(
2127                    "Unable to find android system package", e);
2128        }
2129    }
2130
2131    public void setWindowManager(WindowManagerService wm) {
2132        mWindowManager = wm;
2133        mStackSupervisor.setWindowManager(wm);
2134    }
2135
2136    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2137        mUsageStatsService = usageStatsManager;
2138    }
2139
2140    public void startObservingNativeCrashes() {
2141        final NativeCrashListener ncl = new NativeCrashListener(this);
2142        ncl.start();
2143    }
2144
2145    public IAppOpsService getAppOpsService() {
2146        return mAppOpsService;
2147    }
2148
2149    static class MemBinder extends Binder {
2150        ActivityManagerService mActivityManagerService;
2151        MemBinder(ActivityManagerService activityManagerService) {
2152            mActivityManagerService = activityManagerService;
2153        }
2154
2155        @Override
2156        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2157            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2158                    != PackageManager.PERMISSION_GRANTED) {
2159                pw.println("Permission Denial: can't dump meminfo from from pid="
2160                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2161                        + " without permission " + android.Manifest.permission.DUMP);
2162                return;
2163            }
2164
2165            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2166        }
2167    }
2168
2169    static class GraphicsBinder extends Binder {
2170        ActivityManagerService mActivityManagerService;
2171        GraphicsBinder(ActivityManagerService activityManagerService) {
2172            mActivityManagerService = activityManagerService;
2173        }
2174
2175        @Override
2176        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2177            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2178                    != PackageManager.PERMISSION_GRANTED) {
2179                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2180                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2181                        + " without permission " + android.Manifest.permission.DUMP);
2182                return;
2183            }
2184
2185            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2186        }
2187    }
2188
2189    static class DbBinder extends Binder {
2190        ActivityManagerService mActivityManagerService;
2191        DbBinder(ActivityManagerService activityManagerService) {
2192            mActivityManagerService = activityManagerService;
2193        }
2194
2195        @Override
2196        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2197            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2198                    != PackageManager.PERMISSION_GRANTED) {
2199                pw.println("Permission Denial: can't dump dbinfo from from pid="
2200                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2201                        + " without permission " + android.Manifest.permission.DUMP);
2202                return;
2203            }
2204
2205            mActivityManagerService.dumpDbInfo(fd, pw, args);
2206        }
2207    }
2208
2209    static class CpuBinder extends Binder {
2210        ActivityManagerService mActivityManagerService;
2211        CpuBinder(ActivityManagerService activityManagerService) {
2212            mActivityManagerService = activityManagerService;
2213        }
2214
2215        @Override
2216        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2217            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2218                    != PackageManager.PERMISSION_GRANTED) {
2219                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2220                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2221                        + " without permission " + android.Manifest.permission.DUMP);
2222                return;
2223            }
2224
2225            synchronized (mActivityManagerService.mProcessCpuTracker) {
2226                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2227                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2228                        SystemClock.uptimeMillis()));
2229            }
2230        }
2231    }
2232
2233    public static final class Lifecycle extends SystemService {
2234        private final ActivityManagerService mService;
2235
2236        public Lifecycle(Context context) {
2237            super(context);
2238            mService = new ActivityManagerService(context);
2239        }
2240
2241        @Override
2242        public void onStart() {
2243            mService.start();
2244        }
2245
2246        public ActivityManagerService getService() {
2247            return mService;
2248        }
2249    }
2250
2251    // Note: This method is invoked on the main thread but may need to attach various
2252    // handlers to other threads.  So take care to be explicit about the looper.
2253    public ActivityManagerService(Context systemContext) {
2254        mContext = systemContext;
2255        mFactoryTest = FactoryTest.getMode();
2256        mSystemThread = ActivityThread.currentActivityThread();
2257
2258        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2259
2260        mHandlerThread = new ServiceThread(TAG,
2261                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2262        mHandlerThread.start();
2263        mHandler = new MainHandler(mHandlerThread.getLooper());
2264
2265        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2266                "foreground", BROADCAST_FG_TIMEOUT, false);
2267        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2268                "background", BROADCAST_BG_TIMEOUT, true);
2269        mBroadcastQueues[0] = mFgBroadcastQueue;
2270        mBroadcastQueues[1] = mBgBroadcastQueue;
2271
2272        mServices = new ActiveServices(this);
2273        mProviderMap = new ProviderMap(this);
2274
2275        // TODO: Move creation of battery stats service outside of activity manager service.
2276        File dataDir = Environment.getDataDirectory();
2277        File systemDir = new File(dataDir, "system");
2278        systemDir.mkdirs();
2279        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2280        mBatteryStatsService.getActiveStatistics().readLocked();
2281        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2282        mOnBattery = DEBUG_POWER ? true
2283                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2284        mBatteryStatsService.getActiveStatistics().setCallback(this);
2285
2286        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2287
2288        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2289
2290        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2291
2292        // User 0 is the first and only user that runs at boot.
2293        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2294        mUserLru.add(Integer.valueOf(0));
2295        updateStartedUserArrayLocked();
2296
2297        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2298            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2299
2300        mConfiguration.setToDefaults();
2301        mConfiguration.setLocale(Locale.getDefault());
2302
2303        mConfigurationSeq = mConfiguration.seq = 1;
2304        mProcessCpuTracker.init();
2305
2306        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2307        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2308        mStackSupervisor = new ActivityStackSupervisor(this);
2309        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2310
2311        mProcessCpuThread = new Thread("CpuTracker") {
2312            @Override
2313            public void run() {
2314                while (true) {
2315                    try {
2316                        try {
2317                            synchronized(this) {
2318                                final long now = SystemClock.uptimeMillis();
2319                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2320                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2321                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2322                                //        + ", write delay=" + nextWriteDelay);
2323                                if (nextWriteDelay < nextCpuDelay) {
2324                                    nextCpuDelay = nextWriteDelay;
2325                                }
2326                                if (nextCpuDelay > 0) {
2327                                    mProcessCpuMutexFree.set(true);
2328                                    this.wait(nextCpuDelay);
2329                                }
2330                            }
2331                        } catch (InterruptedException e) {
2332                        }
2333                        updateCpuStatsNow();
2334                    } catch (Exception e) {
2335                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2336                    }
2337                }
2338            }
2339        };
2340
2341        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2342
2343        Watchdog.getInstance().addMonitor(this);
2344        Watchdog.getInstance().addThread(mHandler);
2345    }
2346
2347    public void setSystemServiceManager(SystemServiceManager mgr) {
2348        mSystemServiceManager = mgr;
2349    }
2350
2351    private void start() {
2352        Process.removeAllProcessGroups();
2353        mProcessCpuThread.start();
2354
2355        mBatteryStatsService.publish(mContext);
2356        mAppOpsService.publish(mContext);
2357        Slog.d("AppOps", "AppOpsService published");
2358        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2359    }
2360
2361    public void initPowerManagement() {
2362        mStackSupervisor.initPowerManagement();
2363        mBatteryStatsService.initPowerManagement();
2364    }
2365
2366    @Override
2367    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2368            throws RemoteException {
2369        if (code == SYSPROPS_TRANSACTION) {
2370            // We need to tell all apps about the system property change.
2371            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2372            synchronized(this) {
2373                final int NP = mProcessNames.getMap().size();
2374                for (int ip=0; ip<NP; ip++) {
2375                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2376                    final int NA = apps.size();
2377                    for (int ia=0; ia<NA; ia++) {
2378                        ProcessRecord app = apps.valueAt(ia);
2379                        if (app.thread != null) {
2380                            procs.add(app.thread.asBinder());
2381                        }
2382                    }
2383                }
2384            }
2385
2386            int N = procs.size();
2387            for (int i=0; i<N; i++) {
2388                Parcel data2 = Parcel.obtain();
2389                try {
2390                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2391                } catch (RemoteException e) {
2392                }
2393                data2.recycle();
2394            }
2395        }
2396        try {
2397            return super.onTransact(code, data, reply, flags);
2398        } catch (RuntimeException e) {
2399            // The activity manager only throws security exceptions, so let's
2400            // log all others.
2401            if (!(e instanceof SecurityException)) {
2402                Slog.wtf(TAG, "Activity Manager Crash", e);
2403            }
2404            throw e;
2405        }
2406    }
2407
2408    void updateCpuStats() {
2409        final long now = SystemClock.uptimeMillis();
2410        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2411            return;
2412        }
2413        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2414            synchronized (mProcessCpuThread) {
2415                mProcessCpuThread.notify();
2416            }
2417        }
2418    }
2419
2420    void updateCpuStatsNow() {
2421        synchronized (mProcessCpuTracker) {
2422            mProcessCpuMutexFree.set(false);
2423            final long now = SystemClock.uptimeMillis();
2424            boolean haveNewCpuStats = false;
2425
2426            if (MONITOR_CPU_USAGE &&
2427                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2428                mLastCpuTime.set(now);
2429                haveNewCpuStats = true;
2430                mProcessCpuTracker.update();
2431                //Slog.i(TAG, mProcessCpu.printCurrentState());
2432                //Slog.i(TAG, "Total CPU usage: "
2433                //        + mProcessCpu.getTotalCpuPercent() + "%");
2434
2435                // Slog the cpu usage if the property is set.
2436                if ("true".equals(SystemProperties.get("events.cpu"))) {
2437                    int user = mProcessCpuTracker.getLastUserTime();
2438                    int system = mProcessCpuTracker.getLastSystemTime();
2439                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2440                    int irq = mProcessCpuTracker.getLastIrqTime();
2441                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2442                    int idle = mProcessCpuTracker.getLastIdleTime();
2443
2444                    int total = user + system + iowait + irq + softIrq + idle;
2445                    if (total == 0) total = 1;
2446
2447                    EventLog.writeEvent(EventLogTags.CPU,
2448                            ((user+system+iowait+irq+softIrq) * 100) / total,
2449                            (user * 100) / total,
2450                            (system * 100) / total,
2451                            (iowait * 100) / total,
2452                            (irq * 100) / total,
2453                            (softIrq * 100) / total);
2454                }
2455            }
2456
2457            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2458            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2459            synchronized(bstats) {
2460                synchronized(mPidsSelfLocked) {
2461                    if (haveNewCpuStats) {
2462                        if (mOnBattery) {
2463                            int perc = bstats.startAddingCpuLocked();
2464                            int totalUTime = 0;
2465                            int totalSTime = 0;
2466                            final int N = mProcessCpuTracker.countStats();
2467                            for (int i=0; i<N; i++) {
2468                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2469                                if (!st.working) {
2470                                    continue;
2471                                }
2472                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2473                                int otherUTime = (st.rel_utime*perc)/100;
2474                                int otherSTime = (st.rel_stime*perc)/100;
2475                                totalUTime += otherUTime;
2476                                totalSTime += otherSTime;
2477                                if (pr != null) {
2478                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2479                                    if (ps == null || !ps.isActive()) {
2480                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2481                                                pr.info.uid, pr.processName);
2482                                    }
2483                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2484                                            st.rel_stime-otherSTime);
2485                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2486                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2487                                } else {
2488                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2489                                    if (ps == null || !ps.isActive()) {
2490                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2491                                                bstats.mapUid(st.uid), st.name);
2492                                    }
2493                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2494                                            st.rel_stime-otherSTime);
2495                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2496                                }
2497                            }
2498                            bstats.finishAddingCpuLocked(perc, totalUTime,
2499                                    totalSTime, cpuSpeedTimes);
2500                        }
2501                    }
2502                }
2503
2504                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2505                    mLastWriteTime = now;
2506                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2507                }
2508            }
2509        }
2510    }
2511
2512    @Override
2513    public void batteryNeedsCpuUpdate() {
2514        updateCpuStatsNow();
2515    }
2516
2517    @Override
2518    public void batteryPowerChanged(boolean onBattery) {
2519        // When plugging in, update the CPU stats first before changing
2520        // the plug state.
2521        updateCpuStatsNow();
2522        synchronized (this) {
2523            synchronized(mPidsSelfLocked) {
2524                mOnBattery = DEBUG_POWER ? true : onBattery;
2525            }
2526        }
2527    }
2528
2529    /**
2530     * Initialize the application bind args. These are passed to each
2531     * process when the bindApplication() IPC is sent to the process. They're
2532     * lazily setup to make sure the services are running when they're asked for.
2533     */
2534    private HashMap<String, IBinder> getCommonServicesLocked() {
2535        if (mAppBindArgs == null) {
2536            mAppBindArgs = new HashMap<String, IBinder>();
2537
2538            // Setup the application init args
2539            mAppBindArgs.put("package", ServiceManager.getService("package"));
2540            mAppBindArgs.put("window", ServiceManager.getService("window"));
2541            mAppBindArgs.put(Context.ALARM_SERVICE,
2542                    ServiceManager.getService(Context.ALARM_SERVICE));
2543        }
2544        return mAppBindArgs;
2545    }
2546
2547    final void setFocusedActivityLocked(ActivityRecord r) {
2548        if (mFocusedActivity != r) {
2549            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2550            mFocusedActivity = r;
2551            if (r.task != null && r.task.voiceInteractor != null) {
2552                startRunningVoiceLocked();
2553            } else {
2554                finishRunningVoiceLocked();
2555            }
2556            mStackSupervisor.setFocusedStack(r);
2557            if (r != null) {
2558                mWindowManager.setFocusedApp(r.appToken, true);
2559            }
2560            applyUpdateLockStateLocked(r);
2561        }
2562    }
2563
2564    final void clearFocusedActivity(ActivityRecord r) {
2565        if (mFocusedActivity == r) {
2566            mFocusedActivity = null;
2567        }
2568    }
2569
2570    @Override
2571    public void setFocusedStack(int stackId) {
2572        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2573        synchronized (ActivityManagerService.this) {
2574            ActivityStack stack = mStackSupervisor.getStack(stackId);
2575            if (stack != null) {
2576                ActivityRecord r = stack.topRunningActivityLocked(null);
2577                if (r != null) {
2578                    setFocusedActivityLocked(r);
2579                }
2580            }
2581        }
2582    }
2583
2584    @Override
2585    public void notifyActivityDrawn(IBinder token) {
2586        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2587        synchronized (this) {
2588            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2589            if (r != null) {
2590                r.task.stack.notifyActivityDrawnLocked(r);
2591            }
2592        }
2593    }
2594
2595    final void applyUpdateLockStateLocked(ActivityRecord r) {
2596        // Modifications to the UpdateLock state are done on our handler, outside
2597        // the activity manager's locks.  The new state is determined based on the
2598        // state *now* of the relevant activity record.  The object is passed to
2599        // the handler solely for logging detail, not to be consulted/modified.
2600        final boolean nextState = r != null && r.immersive;
2601        mHandler.sendMessage(
2602                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2603    }
2604
2605    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2606        Message msg = Message.obtain();
2607        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2608        msg.obj = r.task.askedCompatMode ? null : r;
2609        mHandler.sendMessage(msg);
2610    }
2611
2612    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2613            String what, Object obj, ProcessRecord srcApp) {
2614        app.lastActivityTime = now;
2615
2616        if (app.activities.size() > 0) {
2617            // Don't want to touch dependent processes that are hosting activities.
2618            return index;
2619        }
2620
2621        int lrui = mLruProcesses.lastIndexOf(app);
2622        if (lrui < 0) {
2623            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2624                    + what + " " + obj + " from " + srcApp);
2625            return index;
2626        }
2627
2628        if (lrui >= index) {
2629            // Don't want to cause this to move dependent processes *back* in the
2630            // list as if they were less frequently used.
2631            return index;
2632        }
2633
2634        if (lrui >= mLruProcessActivityStart) {
2635            // Don't want to touch dependent processes that are hosting activities.
2636            return index;
2637        }
2638
2639        mLruProcesses.remove(lrui);
2640        if (index > 0) {
2641            index--;
2642        }
2643        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2644                + " in LRU list: " + app);
2645        mLruProcesses.add(index, app);
2646        return index;
2647    }
2648
2649    final void removeLruProcessLocked(ProcessRecord app) {
2650        int lrui = mLruProcesses.lastIndexOf(app);
2651        if (lrui >= 0) {
2652            if (!app.killed) {
2653                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2654                Process.killProcessQuiet(app.pid);
2655                Process.killProcessGroup(app.info.uid, app.pid);
2656            }
2657            if (lrui <= mLruProcessActivityStart) {
2658                mLruProcessActivityStart--;
2659            }
2660            if (lrui <= mLruProcessServiceStart) {
2661                mLruProcessServiceStart--;
2662            }
2663            mLruProcesses.remove(lrui);
2664        }
2665    }
2666
2667    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2668            ProcessRecord client) {
2669        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2670                || app.treatLikeActivity;
2671        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2672        if (!activityChange && hasActivity) {
2673            // The process has activities, so we are only allowing activity-based adjustments
2674            // to move it.  It should be kept in the front of the list with other
2675            // processes that have activities, and we don't want those to change their
2676            // order except due to activity operations.
2677            return;
2678        }
2679
2680        mLruSeq++;
2681        final long now = SystemClock.uptimeMillis();
2682        app.lastActivityTime = now;
2683
2684        // First a quick reject: if the app is already at the position we will
2685        // put it, then there is nothing to do.
2686        if (hasActivity) {
2687            final int N = mLruProcesses.size();
2688            if (N > 0 && mLruProcesses.get(N-1) == app) {
2689                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2690                return;
2691            }
2692        } else {
2693            if (mLruProcessServiceStart > 0
2694                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2695                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2696                return;
2697            }
2698        }
2699
2700        int lrui = mLruProcesses.lastIndexOf(app);
2701
2702        if (app.persistent && lrui >= 0) {
2703            // We don't care about the position of persistent processes, as long as
2704            // they are in the list.
2705            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2706            return;
2707        }
2708
2709        /* In progress: compute new position first, so we can avoid doing work
2710           if the process is not actually going to move.  Not yet working.
2711        int addIndex;
2712        int nextIndex;
2713        boolean inActivity = false, inService = false;
2714        if (hasActivity) {
2715            // Process has activities, put it at the very tipsy-top.
2716            addIndex = mLruProcesses.size();
2717            nextIndex = mLruProcessServiceStart;
2718            inActivity = true;
2719        } else if (hasService) {
2720            // Process has services, put it at the top of the service list.
2721            addIndex = mLruProcessActivityStart;
2722            nextIndex = mLruProcessServiceStart;
2723            inActivity = true;
2724            inService = true;
2725        } else  {
2726            // Process not otherwise of interest, it goes to the top of the non-service area.
2727            addIndex = mLruProcessServiceStart;
2728            if (client != null) {
2729                int clientIndex = mLruProcesses.lastIndexOf(client);
2730                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2731                        + app);
2732                if (clientIndex >= 0 && addIndex > clientIndex) {
2733                    addIndex = clientIndex;
2734                }
2735            }
2736            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2737        }
2738
2739        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2740                + mLruProcessActivityStart + "): " + app);
2741        */
2742
2743        if (lrui >= 0) {
2744            if (lrui < mLruProcessActivityStart) {
2745                mLruProcessActivityStart--;
2746            }
2747            if (lrui < mLruProcessServiceStart) {
2748                mLruProcessServiceStart--;
2749            }
2750            /*
2751            if (addIndex > lrui) {
2752                addIndex--;
2753            }
2754            if (nextIndex > lrui) {
2755                nextIndex--;
2756            }
2757            */
2758            mLruProcesses.remove(lrui);
2759        }
2760
2761        /*
2762        mLruProcesses.add(addIndex, app);
2763        if (inActivity) {
2764            mLruProcessActivityStart++;
2765        }
2766        if (inService) {
2767            mLruProcessActivityStart++;
2768        }
2769        */
2770
2771        int nextIndex;
2772        if (hasActivity) {
2773            final int N = mLruProcesses.size();
2774            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2775                // Process doesn't have activities, but has clients with
2776                // activities...  move it up, but one below the top (the top
2777                // should always have a real activity).
2778                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2779                mLruProcesses.add(N-1, app);
2780                // To keep it from spamming the LRU list (by making a bunch of clients),
2781                // we will push down any other entries owned by the app.
2782                final int uid = app.info.uid;
2783                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2784                    ProcessRecord subProc = mLruProcesses.get(i);
2785                    if (subProc.info.uid == uid) {
2786                        // We want to push this one down the list.  If the process after
2787                        // it is for the same uid, however, don't do so, because we don't
2788                        // want them internally to be re-ordered.
2789                        if (mLruProcesses.get(i-1).info.uid != uid) {
2790                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2791                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2792                            ProcessRecord tmp = mLruProcesses.get(i);
2793                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2794                            mLruProcesses.set(i-1, tmp);
2795                            i--;
2796                        }
2797                    } else {
2798                        // A gap, we can stop here.
2799                        break;
2800                    }
2801                }
2802            } else {
2803                // Process has activities, put it at the very tipsy-top.
2804                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2805                mLruProcesses.add(app);
2806            }
2807            nextIndex = mLruProcessServiceStart;
2808        } else if (hasService) {
2809            // Process has services, put it at the top of the service list.
2810            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2811            mLruProcesses.add(mLruProcessActivityStart, app);
2812            nextIndex = mLruProcessServiceStart;
2813            mLruProcessActivityStart++;
2814        } else  {
2815            // Process not otherwise of interest, it goes to the top of the non-service area.
2816            int index = mLruProcessServiceStart;
2817            if (client != null) {
2818                // If there is a client, don't allow the process to be moved up higher
2819                // in the list than that client.
2820                int clientIndex = mLruProcesses.lastIndexOf(client);
2821                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2822                        + " when updating " + app);
2823                if (clientIndex <= lrui) {
2824                    // Don't allow the client index restriction to push it down farther in the
2825                    // list than it already is.
2826                    clientIndex = lrui;
2827                }
2828                if (clientIndex >= 0 && index > clientIndex) {
2829                    index = clientIndex;
2830                }
2831            }
2832            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2833            mLruProcesses.add(index, app);
2834            nextIndex = index-1;
2835            mLruProcessActivityStart++;
2836            mLruProcessServiceStart++;
2837        }
2838
2839        // If the app is currently using a content provider or service,
2840        // bump those processes as well.
2841        for (int j=app.connections.size()-1; j>=0; j--) {
2842            ConnectionRecord cr = app.connections.valueAt(j);
2843            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2844                    && cr.binding.service.app != null
2845                    && cr.binding.service.app.lruSeq != mLruSeq
2846                    && !cr.binding.service.app.persistent) {
2847                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2848                        "service connection", cr, app);
2849            }
2850        }
2851        for (int j=app.conProviders.size()-1; j>=0; j--) {
2852            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2853            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2854                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2855                        "provider reference", cpr, app);
2856            }
2857        }
2858    }
2859
2860    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2861        if (uid == Process.SYSTEM_UID) {
2862            // The system gets to run in any process.  If there are multiple
2863            // processes with the same uid, just pick the first (this
2864            // should never happen).
2865            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2866            if (procs == null) return null;
2867            final int N = procs.size();
2868            for (int i = 0; i < N; i++) {
2869                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2870            }
2871        }
2872        ProcessRecord proc = mProcessNames.get(processName, uid);
2873        if (false && proc != null && !keepIfLarge
2874                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2875                && proc.lastCachedPss >= 4000) {
2876            // Turn this condition on to cause killing to happen regularly, for testing.
2877            if (proc.baseProcessTracker != null) {
2878                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2879            }
2880            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2881        } else if (proc != null && !keepIfLarge
2882                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2883                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2884            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2885            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2886                if (proc.baseProcessTracker != null) {
2887                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2888                }
2889                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2890            }
2891        }
2892        return proc;
2893    }
2894
2895    void ensurePackageDexOpt(String packageName) {
2896        IPackageManager pm = AppGlobals.getPackageManager();
2897        try {
2898            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2899                mDidDexOpt = true;
2900            }
2901        } catch (RemoteException e) {
2902        }
2903    }
2904
2905    boolean isNextTransitionForward() {
2906        int transit = mWindowManager.getPendingAppTransition();
2907        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2908                || transit == AppTransition.TRANSIT_TASK_OPEN
2909                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2910    }
2911
2912    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2913            String processName, String abiOverride, int uid, Runnable crashHandler) {
2914        synchronized(this) {
2915            ApplicationInfo info = new ApplicationInfo();
2916            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2917            // For isolated processes, the former contains the parent's uid and the latter the
2918            // actual uid of the isolated process.
2919            // In the special case introduced by this method (which is, starting an isolated
2920            // process directly from the SystemServer without an actual parent app process) the
2921            // closest thing to a parent's uid is SYSTEM_UID.
2922            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2923            // the |isolated| logic in the ProcessRecord constructor.
2924            info.uid = Process.SYSTEM_UID;
2925            info.processName = processName;
2926            info.className = entryPoint;
2927            info.packageName = "android";
2928            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2929                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2930                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2931                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2932                    crashHandler);
2933            return proc != null ? proc.pid : 0;
2934        }
2935    }
2936
2937    final ProcessRecord startProcessLocked(String processName,
2938            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2939            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2940            boolean isolated, boolean keepIfLarge) {
2941        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2942                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2943                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2944                null /* crashHandler */);
2945    }
2946
2947    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2948            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2949            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2950            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2951        long startTime = SystemClock.elapsedRealtime();
2952        ProcessRecord app;
2953        if (!isolated) {
2954            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2955            checkTime(startTime, "startProcess: after getProcessRecord");
2956        } else {
2957            // If this is an isolated process, it can't re-use an existing process.
2958            app = null;
2959        }
2960        // We don't have to do anything more if:
2961        // (1) There is an existing application record; and
2962        // (2) The caller doesn't think it is dead, OR there is no thread
2963        //     object attached to it so we know it couldn't have crashed; and
2964        // (3) There is a pid assigned to it, so it is either starting or
2965        //     already running.
2966        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2967                + " app=" + app + " knownToBeDead=" + knownToBeDead
2968                + " thread=" + (app != null ? app.thread : null)
2969                + " pid=" + (app != null ? app.pid : -1));
2970        if (app != null && app.pid > 0) {
2971            if (!knownToBeDead || app.thread == null) {
2972                // We already have the app running, or are waiting for it to
2973                // come up (we have a pid but not yet its thread), so keep it.
2974                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2975                // If this is a new package in the process, add the package to the list
2976                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2977                checkTime(startTime, "startProcess: done, added package to proc");
2978                return app;
2979            }
2980
2981            // An application record is attached to a previous process,
2982            // clean it up now.
2983            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2984            checkTime(startTime, "startProcess: bad proc running, killing");
2985            Process.killProcessGroup(app.info.uid, app.pid);
2986            handleAppDiedLocked(app, true, true);
2987            checkTime(startTime, "startProcess: done killing old proc");
2988        }
2989
2990        String hostingNameStr = hostingName != null
2991                ? hostingName.flattenToShortString() : null;
2992
2993        if (!isolated) {
2994            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2995                // If we are in the background, then check to see if this process
2996                // is bad.  If so, we will just silently fail.
2997                if (mBadProcesses.get(info.processName, info.uid) != null) {
2998                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2999                            + "/" + info.processName);
3000                    return null;
3001                }
3002            } else {
3003                // When the user is explicitly starting a process, then clear its
3004                // crash count so that we won't make it bad until they see at
3005                // least one crash dialog again, and make the process good again
3006                // if it had been bad.
3007                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3008                        + "/" + info.processName);
3009                mProcessCrashTimes.remove(info.processName, info.uid);
3010                if (mBadProcesses.get(info.processName, info.uid) != null) {
3011                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3012                            UserHandle.getUserId(info.uid), info.uid,
3013                            info.processName);
3014                    mBadProcesses.remove(info.processName, info.uid);
3015                    if (app != null) {
3016                        app.bad = false;
3017                    }
3018                }
3019            }
3020        }
3021
3022        if (app == null) {
3023            checkTime(startTime, "startProcess: creating new process record");
3024            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3025            app.crashHandler = crashHandler;
3026            if (app == null) {
3027                Slog.w(TAG, "Failed making new process record for "
3028                        + processName + "/" + info.uid + " isolated=" + isolated);
3029                return null;
3030            }
3031            mProcessNames.put(processName, app.uid, app);
3032            if (isolated) {
3033                mIsolatedProcesses.put(app.uid, app);
3034            }
3035            checkTime(startTime, "startProcess: done creating new process record");
3036        } else {
3037            // If this is a new package in the process, add the package to the list
3038            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3039            checkTime(startTime, "startProcess: added package to existing proc");
3040        }
3041
3042        // If the system is not ready yet, then hold off on starting this
3043        // process until it is.
3044        if (!mProcessesReady
3045                && !isAllowedWhileBooting(info)
3046                && !allowWhileBooting) {
3047            if (!mProcessesOnHold.contains(app)) {
3048                mProcessesOnHold.add(app);
3049            }
3050            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3051            checkTime(startTime, "startProcess: returning with proc on hold");
3052            return app;
3053        }
3054
3055        checkTime(startTime, "startProcess: stepping in to startProcess");
3056        startProcessLocked(
3057                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3058        checkTime(startTime, "startProcess: done starting proc!");
3059        return (app.pid != 0) ? app : null;
3060    }
3061
3062    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3063        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3064    }
3065
3066    private final void startProcessLocked(ProcessRecord app,
3067            String hostingType, String hostingNameStr) {
3068        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3069                null /* entryPoint */, null /* entryPointArgs */);
3070    }
3071
3072    private final void startProcessLocked(ProcessRecord app, String hostingType,
3073            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3074        long startTime = SystemClock.elapsedRealtime();
3075        if (app.pid > 0 && app.pid != MY_PID) {
3076            checkTime(startTime, "startProcess: removing from pids map");
3077            synchronized (mPidsSelfLocked) {
3078                mPidsSelfLocked.remove(app.pid);
3079                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3080            }
3081            checkTime(startTime, "startProcess: done removing from pids map");
3082            app.setPid(0);
3083        }
3084
3085        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3086                "startProcessLocked removing on hold: " + app);
3087        mProcessesOnHold.remove(app);
3088
3089        checkTime(startTime, "startProcess: starting to update cpu stats");
3090        updateCpuStats();
3091        checkTime(startTime, "startProcess: done updating cpu stats");
3092
3093        try {
3094            int uid = app.uid;
3095
3096            int[] gids = null;
3097            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3098            if (!app.isolated) {
3099                int[] permGids = null;
3100                try {
3101                    checkTime(startTime, "startProcess: getting gids from package manager");
3102                    final PackageManager pm = mContext.getPackageManager();
3103                    permGids = pm.getPackageGids(app.info.packageName);
3104
3105                    if (Environment.isExternalStorageEmulated()) {
3106                        checkTime(startTime, "startProcess: checking external storage perm");
3107                        if (pm.checkPermission(
3108                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3109                                app.info.packageName) == PERMISSION_GRANTED) {
3110                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3111                        } else {
3112                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3113                        }
3114                    }
3115                } catch (PackageManager.NameNotFoundException e) {
3116                    Slog.w(TAG, "Unable to retrieve gids", e);
3117                }
3118
3119                /*
3120                 * Add shared application and profile GIDs so applications can share some
3121                 * resources like shared libraries and access user-wide resources
3122                 */
3123                if (permGids == null) {
3124                    gids = new int[2];
3125                } else {
3126                    gids = new int[permGids.length + 2];
3127                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3128                }
3129                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3130                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3131            }
3132            checkTime(startTime, "startProcess: building args");
3133            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3134                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3135                        && mTopComponent != null
3136                        && app.processName.equals(mTopComponent.getPackageName())) {
3137                    uid = 0;
3138                }
3139                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3140                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3141                    uid = 0;
3142                }
3143            }
3144            int debugFlags = 0;
3145            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3146                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3147                // Also turn on CheckJNI for debuggable apps. It's quite
3148                // awkward to turn on otherwise.
3149                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3150            }
3151            // Run the app in safe mode if its manifest requests so or the
3152            // system is booted in safe mode.
3153            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3154                mSafeMode == true) {
3155                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3156            }
3157            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3158                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3159            }
3160            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3161                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3162            }
3163            if ("1".equals(SystemProperties.get("debug.assert"))) {
3164                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3165            }
3166
3167            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3168            if (requiredAbi == null) {
3169                requiredAbi = Build.SUPPORTED_ABIS[0];
3170            }
3171
3172            String instructionSet = null;
3173            if (app.info.primaryCpuAbi != null) {
3174                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3175            }
3176
3177            // Start the process.  It will either succeed and return a result containing
3178            // the PID of the new process, or else throw a RuntimeException.
3179            boolean isActivityProcess = (entryPoint == null);
3180            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3181            checkTime(startTime, "startProcess: asking zygote to start proc");
3182            Process.ProcessStartResult startResult = Process.start(entryPoint,
3183                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3184                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3185                    app.info.dataDir, entryPointArgs);
3186            checkTime(startTime, "startProcess: returned from zygote!");
3187
3188            if (app.isolated) {
3189                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3190            }
3191            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3192            checkTime(startTime, "startProcess: done updating battery stats");
3193
3194            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3195                    UserHandle.getUserId(uid), startResult.pid, uid,
3196                    app.processName, hostingType,
3197                    hostingNameStr != null ? hostingNameStr : "");
3198
3199            if (app.persistent) {
3200                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3201            }
3202
3203            checkTime(startTime, "startProcess: building log message");
3204            StringBuilder buf = mStringBuilder;
3205            buf.setLength(0);
3206            buf.append("Start proc ");
3207            buf.append(app.processName);
3208            if (!isActivityProcess) {
3209                buf.append(" [");
3210                buf.append(entryPoint);
3211                buf.append("]");
3212            }
3213            buf.append(" for ");
3214            buf.append(hostingType);
3215            if (hostingNameStr != null) {
3216                buf.append(" ");
3217                buf.append(hostingNameStr);
3218            }
3219            buf.append(": pid=");
3220            buf.append(startResult.pid);
3221            buf.append(" uid=");
3222            buf.append(uid);
3223            buf.append(" gids={");
3224            if (gids != null) {
3225                for (int gi=0; gi<gids.length; gi++) {
3226                    if (gi != 0) buf.append(", ");
3227                    buf.append(gids[gi]);
3228
3229                }
3230            }
3231            buf.append("}");
3232            if (requiredAbi != null) {
3233                buf.append(" abi=");
3234                buf.append(requiredAbi);
3235            }
3236            Slog.i(TAG, buf.toString());
3237            app.setPid(startResult.pid);
3238            app.usingWrapper = startResult.usingWrapper;
3239            app.removed = false;
3240            app.killed = false;
3241            app.killedByAm = false;
3242            checkTime(startTime, "startProcess: starting to update pids map");
3243            synchronized (mPidsSelfLocked) {
3244                this.mPidsSelfLocked.put(startResult.pid, app);
3245                if (isActivityProcess) {
3246                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3247                    msg.obj = app;
3248                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3249                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3250                }
3251            }
3252            checkTime(startTime, "startProcess: done updating pids map");
3253        } catch (RuntimeException e) {
3254            // XXX do better error recovery.
3255            app.setPid(0);
3256            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3257            if (app.isolated) {
3258                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3259            }
3260            Slog.e(TAG, "Failure starting process " + app.processName, e);
3261        }
3262    }
3263
3264    void updateUsageStats(ActivityRecord component, boolean resumed) {
3265        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3266        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3267        if (resumed) {
3268            if (mUsageStatsService != null) {
3269                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3270                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3271            }
3272            synchronized (stats) {
3273                stats.noteActivityResumedLocked(component.app.uid);
3274            }
3275        } else {
3276            if (mUsageStatsService != null) {
3277                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3278                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3279            }
3280            synchronized (stats) {
3281                stats.noteActivityPausedLocked(component.app.uid);
3282            }
3283        }
3284    }
3285
3286    Intent getHomeIntent() {
3287        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3288        intent.setComponent(mTopComponent);
3289        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3290            intent.addCategory(Intent.CATEGORY_HOME);
3291        }
3292        return intent;
3293    }
3294
3295    boolean startHomeActivityLocked(int userId) {
3296        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3297                && mTopAction == null) {
3298            // We are running in factory test mode, but unable to find
3299            // the factory test app, so just sit around displaying the
3300            // error message and don't try to start anything.
3301            return false;
3302        }
3303        Intent intent = getHomeIntent();
3304        ActivityInfo aInfo =
3305            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3306        if (aInfo != null) {
3307            intent.setComponent(new ComponentName(
3308                    aInfo.applicationInfo.packageName, aInfo.name));
3309            // Don't do this if the home app is currently being
3310            // instrumented.
3311            aInfo = new ActivityInfo(aInfo);
3312            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3313            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3314                    aInfo.applicationInfo.uid, true);
3315            if (app == null || app.instrumentationClass == null) {
3316                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3317                mStackSupervisor.startHomeActivity(intent, aInfo);
3318            }
3319        }
3320
3321        return true;
3322    }
3323
3324    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3325        ActivityInfo ai = null;
3326        ComponentName comp = intent.getComponent();
3327        try {
3328            if (comp != null) {
3329                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3330            } else {
3331                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3332                        intent,
3333                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3334                            flags, userId);
3335
3336                if (info != null) {
3337                    ai = info.activityInfo;
3338                }
3339            }
3340        } catch (RemoteException e) {
3341            // ignore
3342        }
3343
3344        return ai;
3345    }
3346
3347    /**
3348     * Starts the "new version setup screen" if appropriate.
3349     */
3350    void startSetupActivityLocked() {
3351        // Only do this once per boot.
3352        if (mCheckedForSetup) {
3353            return;
3354        }
3355
3356        // We will show this screen if the current one is a different
3357        // version than the last one shown, and we are not running in
3358        // low-level factory test mode.
3359        final ContentResolver resolver = mContext.getContentResolver();
3360        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3361                Settings.Global.getInt(resolver,
3362                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3363            mCheckedForSetup = true;
3364
3365            // See if we should be showing the platform update setup UI.
3366            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3367            List<ResolveInfo> ris = mContext.getPackageManager()
3368                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3369
3370            // We don't allow third party apps to replace this.
3371            ResolveInfo ri = null;
3372            for (int i=0; ris != null && i<ris.size(); i++) {
3373                if ((ris.get(i).activityInfo.applicationInfo.flags
3374                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3375                    ri = ris.get(i);
3376                    break;
3377                }
3378            }
3379
3380            if (ri != null) {
3381                String vers = ri.activityInfo.metaData != null
3382                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3383                        : null;
3384                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3385                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3386                            Intent.METADATA_SETUP_VERSION);
3387                }
3388                String lastVers = Settings.Secure.getString(
3389                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3390                if (vers != null && !vers.equals(lastVers)) {
3391                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3392                    intent.setComponent(new ComponentName(
3393                            ri.activityInfo.packageName, ri.activityInfo.name));
3394                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3395                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3396                            null);
3397                }
3398            }
3399        }
3400    }
3401
3402    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3403        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3404    }
3405
3406    void enforceNotIsolatedCaller(String caller) {
3407        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3408            throw new SecurityException("Isolated process not allowed to call " + caller);
3409        }
3410    }
3411
3412    void enforceShellRestriction(String restriction, int userHandle) {
3413        if (Binder.getCallingUid() == Process.SHELL_UID) {
3414            if (userHandle < 0
3415                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3416                throw new SecurityException("Shell does not have permission to access user "
3417                        + userHandle);
3418            }
3419        }
3420    }
3421
3422    @Override
3423    public int getFrontActivityScreenCompatMode() {
3424        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3425        synchronized (this) {
3426            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3427        }
3428    }
3429
3430    @Override
3431    public void setFrontActivityScreenCompatMode(int mode) {
3432        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3433                "setFrontActivityScreenCompatMode");
3434        synchronized (this) {
3435            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3436        }
3437    }
3438
3439    @Override
3440    public int getPackageScreenCompatMode(String packageName) {
3441        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3442        synchronized (this) {
3443            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3444        }
3445    }
3446
3447    @Override
3448    public void setPackageScreenCompatMode(String packageName, int mode) {
3449        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3450                "setPackageScreenCompatMode");
3451        synchronized (this) {
3452            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3453        }
3454    }
3455
3456    @Override
3457    public boolean getPackageAskScreenCompat(String packageName) {
3458        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3459        synchronized (this) {
3460            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3461        }
3462    }
3463
3464    @Override
3465    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3466        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3467                "setPackageAskScreenCompat");
3468        synchronized (this) {
3469            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3470        }
3471    }
3472
3473    private void dispatchProcessesChanged() {
3474        int N;
3475        synchronized (this) {
3476            N = mPendingProcessChanges.size();
3477            if (mActiveProcessChanges.length < N) {
3478                mActiveProcessChanges = new ProcessChangeItem[N];
3479            }
3480            mPendingProcessChanges.toArray(mActiveProcessChanges);
3481            mAvailProcessChanges.addAll(mPendingProcessChanges);
3482            mPendingProcessChanges.clear();
3483            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3484        }
3485
3486        int i = mProcessObservers.beginBroadcast();
3487        while (i > 0) {
3488            i--;
3489            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3490            if (observer != null) {
3491                try {
3492                    for (int j=0; j<N; j++) {
3493                        ProcessChangeItem item = mActiveProcessChanges[j];
3494                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3495                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3496                                    + item.pid + " uid=" + item.uid + ": "
3497                                    + item.foregroundActivities);
3498                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3499                                    item.foregroundActivities);
3500                        }
3501                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3502                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3503                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3504                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3505                        }
3506                    }
3507                } catch (RemoteException e) {
3508                }
3509            }
3510        }
3511        mProcessObservers.finishBroadcast();
3512    }
3513
3514    private void dispatchProcessDied(int pid, int uid) {
3515        int i = mProcessObservers.beginBroadcast();
3516        while (i > 0) {
3517            i--;
3518            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3519            if (observer != null) {
3520                try {
3521                    observer.onProcessDied(pid, uid);
3522                } catch (RemoteException e) {
3523                }
3524            }
3525        }
3526        mProcessObservers.finishBroadcast();
3527    }
3528
3529    @Override
3530    public final int startActivity(IApplicationThread caller, String callingPackage,
3531            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3532            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3533        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3534            resultWho, requestCode, startFlags, profilerInfo, options,
3535            UserHandle.getCallingUserId());
3536    }
3537
3538    @Override
3539    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3540            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3541            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3542        enforceNotIsolatedCaller("startActivity");
3543        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3544                false, ALLOW_FULL_ONLY, "startActivity", null);
3545        // TODO: Switch to user app stacks here.
3546        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3547                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3548                profilerInfo, null, null, options, userId, null, null);
3549    }
3550
3551    @Override
3552    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3553            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3554            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3555
3556        // This is very dangerous -- it allows you to perform a start activity (including
3557        // permission grants) as any app that may launch one of your own activities.  So
3558        // we will only allow this to be done from activities that are part of the core framework,
3559        // and then only when they are running as the system.
3560        final ActivityRecord sourceRecord;
3561        final int targetUid;
3562        final String targetPackage;
3563        synchronized (this) {
3564            if (resultTo == null) {
3565                throw new SecurityException("Must be called from an activity");
3566            }
3567            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3568            if (sourceRecord == null) {
3569                throw new SecurityException("Called with bad activity token: " + resultTo);
3570            }
3571            if (!sourceRecord.info.packageName.equals("android")) {
3572                throw new SecurityException(
3573                        "Must be called from an activity that is declared in the android package");
3574            }
3575            if (sourceRecord.app == null) {
3576                throw new SecurityException("Called without a process attached to activity");
3577            }
3578            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3579                // This is still okay, as long as this activity is running under the
3580                // uid of the original calling activity.
3581                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3582                    throw new SecurityException(
3583                            "Calling activity in uid " + sourceRecord.app.uid
3584                                    + " must be system uid or original calling uid "
3585                                    + sourceRecord.launchedFromUid);
3586                }
3587            }
3588            targetUid = sourceRecord.launchedFromUid;
3589            targetPackage = sourceRecord.launchedFromPackage;
3590        }
3591
3592        // TODO: Switch to user app stacks here.
3593        try {
3594            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3595                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3596                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3597            return ret;
3598        } catch (SecurityException e) {
3599            // XXX need to figure out how to propagate to original app.
3600            // A SecurityException here is generally actually a fault of the original
3601            // calling activity (such as a fairly granting permissions), so propagate it
3602            // back to them.
3603            /*
3604            StringBuilder msg = new StringBuilder();
3605            msg.append("While launching");
3606            msg.append(intent.toString());
3607            msg.append(": ");
3608            msg.append(e.getMessage());
3609            */
3610            throw e;
3611        }
3612    }
3613
3614    @Override
3615    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3616            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3617            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3618        enforceNotIsolatedCaller("startActivityAndWait");
3619        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3620                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3621        WaitResult res = new WaitResult();
3622        // TODO: Switch to user app stacks here.
3623        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3624                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3625                options, userId, null, null);
3626        return res;
3627    }
3628
3629    @Override
3630    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3632            int startFlags, Configuration config, Bundle options, int userId) {
3633        enforceNotIsolatedCaller("startActivityWithConfig");
3634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3635                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3636        // TODO: Switch to user app stacks here.
3637        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3638                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3639                null, null, config, options, userId, null, null);
3640        return ret;
3641    }
3642
3643    @Override
3644    public int startActivityIntentSender(IApplicationThread caller,
3645            IntentSender intent, Intent fillInIntent, String resolvedType,
3646            IBinder resultTo, String resultWho, int requestCode,
3647            int flagsMask, int flagsValues, Bundle options) {
3648        enforceNotIsolatedCaller("startActivityIntentSender");
3649        // Refuse possible leaked file descriptors
3650        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3651            throw new IllegalArgumentException("File descriptors passed in Intent");
3652        }
3653
3654        IIntentSender sender = intent.getTarget();
3655        if (!(sender instanceof PendingIntentRecord)) {
3656            throw new IllegalArgumentException("Bad PendingIntent object");
3657        }
3658
3659        PendingIntentRecord pir = (PendingIntentRecord)sender;
3660
3661        synchronized (this) {
3662            // If this is coming from the currently resumed activity, it is
3663            // effectively saying that app switches are allowed at this point.
3664            final ActivityStack stack = getFocusedStack();
3665            if (stack.mResumedActivity != null &&
3666                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3667                mAppSwitchesAllowedTime = 0;
3668            }
3669        }
3670        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3671                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3672        return ret;
3673    }
3674
3675    @Override
3676    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3677            Intent intent, String resolvedType, IVoiceInteractionSession session,
3678            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3679            Bundle options, int userId) {
3680        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3681                != PackageManager.PERMISSION_GRANTED) {
3682            String msg = "Permission Denial: startVoiceActivity() from pid="
3683                    + Binder.getCallingPid()
3684                    + ", uid=" + Binder.getCallingUid()
3685                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3686            Slog.w(TAG, msg);
3687            throw new SecurityException(msg);
3688        }
3689        if (session == null || interactor == null) {
3690            throw new NullPointerException("null session or interactor");
3691        }
3692        userId = handleIncomingUser(callingPid, callingUid, userId,
3693                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3694        // TODO: Switch to user app stacks here.
3695        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3696                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3697                null, options, userId, null, null);
3698    }
3699
3700    @Override
3701    public boolean startNextMatchingActivity(IBinder callingActivity,
3702            Intent intent, Bundle options) {
3703        // Refuse possible leaked file descriptors
3704        if (intent != null && intent.hasFileDescriptors() == true) {
3705            throw new IllegalArgumentException("File descriptors passed in Intent");
3706        }
3707
3708        synchronized (this) {
3709            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3710            if (r == null) {
3711                ActivityOptions.abort(options);
3712                return false;
3713            }
3714            if (r.app == null || r.app.thread == null) {
3715                // The caller is not running...  d'oh!
3716                ActivityOptions.abort(options);
3717                return false;
3718            }
3719            intent = new Intent(intent);
3720            // The caller is not allowed to change the data.
3721            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3722            // And we are resetting to find the next component...
3723            intent.setComponent(null);
3724
3725            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3726
3727            ActivityInfo aInfo = null;
3728            try {
3729                List<ResolveInfo> resolves =
3730                    AppGlobals.getPackageManager().queryIntentActivities(
3731                            intent, r.resolvedType,
3732                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3733                            UserHandle.getCallingUserId());
3734
3735                // Look for the original activity in the list...
3736                final int N = resolves != null ? resolves.size() : 0;
3737                for (int i=0; i<N; i++) {
3738                    ResolveInfo rInfo = resolves.get(i);
3739                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3740                            && rInfo.activityInfo.name.equals(r.info.name)) {
3741                        // We found the current one...  the next matching is
3742                        // after it.
3743                        i++;
3744                        if (i<N) {
3745                            aInfo = resolves.get(i).activityInfo;
3746                        }
3747                        if (debug) {
3748                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3749                                    + "/" + r.info.name);
3750                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3751                                    + "/" + aInfo.name);
3752                        }
3753                        break;
3754                    }
3755                }
3756            } catch (RemoteException e) {
3757            }
3758
3759            if (aInfo == null) {
3760                // Nobody who is next!
3761                ActivityOptions.abort(options);
3762                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3763                return false;
3764            }
3765
3766            intent.setComponent(new ComponentName(
3767                    aInfo.applicationInfo.packageName, aInfo.name));
3768            intent.setFlags(intent.getFlags()&~(
3769                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3770                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3771                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3772                    Intent.FLAG_ACTIVITY_NEW_TASK));
3773
3774            // Okay now we need to start the new activity, replacing the
3775            // currently running activity.  This is a little tricky because
3776            // we want to start the new one as if the current one is finished,
3777            // but not finish the current one first so that there is no flicker.
3778            // And thus...
3779            final boolean wasFinishing = r.finishing;
3780            r.finishing = true;
3781
3782            // Propagate reply information over to the new activity.
3783            final ActivityRecord resultTo = r.resultTo;
3784            final String resultWho = r.resultWho;
3785            final int requestCode = r.requestCode;
3786            r.resultTo = null;
3787            if (resultTo != null) {
3788                resultTo.removeResultsLocked(r, resultWho, requestCode);
3789            }
3790
3791            final long origId = Binder.clearCallingIdentity();
3792            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3793                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3794                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3795                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3796            Binder.restoreCallingIdentity(origId);
3797
3798            r.finishing = wasFinishing;
3799            if (res != ActivityManager.START_SUCCESS) {
3800                return false;
3801            }
3802            return true;
3803        }
3804    }
3805
3806    @Override
3807    public final int startActivityFromRecents(int taskId, Bundle options) {
3808        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3809            String msg = "Permission Denial: startActivityFromRecents called without " +
3810                    START_TASKS_FROM_RECENTS;
3811            Slog.w(TAG, msg);
3812            throw new SecurityException(msg);
3813        }
3814        return startActivityFromRecentsInner(taskId, options);
3815    }
3816
3817    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3818        final TaskRecord task;
3819        final int callingUid;
3820        final String callingPackage;
3821        final Intent intent;
3822        final int userId;
3823        synchronized (this) {
3824            task = recentTaskForIdLocked(taskId);
3825            if (task == null) {
3826                throw new IllegalArgumentException("Task " + taskId + " not found.");
3827            }
3828            callingUid = task.mCallingUid;
3829            callingPackage = task.mCallingPackage;
3830            intent = task.intent;
3831            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3832            userId = task.userId;
3833        }
3834        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3835                options, userId, null, task);
3836    }
3837
3838    final int startActivityInPackage(int uid, String callingPackage,
3839            Intent intent, String resolvedType, IBinder resultTo,
3840            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3841            IActivityContainer container, TaskRecord inTask) {
3842
3843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3844                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3845
3846        // TODO: Switch to user app stacks here.
3847        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3848                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3849                null, null, null, options, userId, container, inTask);
3850        return ret;
3851    }
3852
3853    @Override
3854    public final int startActivities(IApplicationThread caller, String callingPackage,
3855            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3856            int userId) {
3857        enforceNotIsolatedCaller("startActivities");
3858        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3859                false, ALLOW_FULL_ONLY, "startActivity", null);
3860        // TODO: Switch to user app stacks here.
3861        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3862                resolvedTypes, resultTo, options, userId);
3863        return ret;
3864    }
3865
3866    final int startActivitiesInPackage(int uid, String callingPackage,
3867            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3868            Bundle options, int userId) {
3869
3870        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3871                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3872        // TODO: Switch to user app stacks here.
3873        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3874                resultTo, options, userId);
3875        return ret;
3876    }
3877
3878    //explicitly remove thd old information in mRecentTasks when removing existing user.
3879    private void removeRecentTasksForUserLocked(int userId) {
3880        if(userId <= 0) {
3881            Slog.i(TAG, "Can't remove recent task on user " + userId);
3882            return;
3883        }
3884
3885        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3886            TaskRecord tr = mRecentTasks.get(i);
3887            if (tr.userId == userId) {
3888                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3889                        + " when finishing user" + userId);
3890                mRecentTasks.remove(i);
3891                tr.removedFromRecents(mTaskPersister);
3892            }
3893        }
3894
3895        // Remove tasks from persistent storage.
3896        mTaskPersister.wakeup(null, true);
3897    }
3898
3899    // Sort by taskId
3900    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3901        @Override
3902        public int compare(TaskRecord lhs, TaskRecord rhs) {
3903            return rhs.taskId - lhs.taskId;
3904        }
3905    };
3906
3907    // Extract the affiliates of the chain containing mRecentTasks[start].
3908    private int processNextAffiliateChain(int start) {
3909        final TaskRecord startTask = mRecentTasks.get(start);
3910        final int affiliateId = startTask.mAffiliatedTaskId;
3911
3912        // Quick identification of isolated tasks. I.e. those not launched behind.
3913        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3914                startTask.mNextAffiliate == null) {
3915            // There is still a slim chance that there are other tasks that point to this task
3916            // and that the chain is so messed up that this task no longer points to them but
3917            // the gain of this optimization outweighs the risk.
3918            startTask.inRecents = true;
3919            return start + 1;
3920        }
3921
3922        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3923        mTmpRecents.clear();
3924        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3925            final TaskRecord task = mRecentTasks.get(i);
3926            if (task.mAffiliatedTaskId == affiliateId) {
3927                mRecentTasks.remove(i);
3928                mTmpRecents.add(task);
3929            }
3930        }
3931
3932        // Sort them all by taskId. That is the order they were create in and that order will
3933        // always be correct.
3934        Collections.sort(mTmpRecents, mTaskRecordComparator);
3935
3936        // Go through and fix up the linked list.
3937        // The first one is the end of the chain and has no next.
3938        final TaskRecord first = mTmpRecents.get(0);
3939        first.inRecents = true;
3940        if (first.mNextAffiliate != null) {
3941            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3942            first.setNextAffiliate(null);
3943            mTaskPersister.wakeup(first, false);
3944        }
3945        // Everything in the middle is doubly linked from next to prev.
3946        final int tmpSize = mTmpRecents.size();
3947        for (int i = 0; i < tmpSize - 1; ++i) {
3948            final TaskRecord next = mTmpRecents.get(i);
3949            final TaskRecord prev = mTmpRecents.get(i + 1);
3950            if (next.mPrevAffiliate != prev) {
3951                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3952                        " setting prev=" + prev);
3953                next.setPrevAffiliate(prev);
3954                mTaskPersister.wakeup(next, false);
3955            }
3956            if (prev.mNextAffiliate != next) {
3957                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3958                        " setting next=" + next);
3959                prev.setNextAffiliate(next);
3960                mTaskPersister.wakeup(prev, false);
3961            }
3962            prev.inRecents = true;
3963        }
3964        // The last one is the beginning of the list and has no prev.
3965        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3966        if (last.mPrevAffiliate != null) {
3967            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3968            last.setPrevAffiliate(null);
3969            mTaskPersister.wakeup(last, false);
3970        }
3971
3972        // Insert the group back into mRecentTasks at start.
3973        mRecentTasks.addAll(start, mTmpRecents);
3974
3975        // Let the caller know where we left off.
3976        return start + tmpSize;
3977    }
3978
3979    /**
3980     * Update the recent tasks lists: make sure tasks should still be here (their
3981     * applications / activities still exist), update their availability, fixup ordering
3982     * of affiliations.
3983     */
3984    void cleanupRecentTasksLocked(int userId) {
3985        if (mRecentTasks == null) {
3986            // Happens when called from the packagemanager broadcast before boot.
3987            return;
3988        }
3989
3990        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3991        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3992        final IPackageManager pm = AppGlobals.getPackageManager();
3993        final ActivityInfo dummyAct = new ActivityInfo();
3994        final ApplicationInfo dummyApp = new ApplicationInfo();
3995
3996        int N = mRecentTasks.size();
3997
3998        int[] users = userId == UserHandle.USER_ALL
3999                ? getUsersLocked() : new int[] { userId };
4000        for (int user : users) {
4001            for (int i = 0; i < N; i++) {
4002                TaskRecord task = mRecentTasks.get(i);
4003                if (task.userId != user) {
4004                    // Only look at tasks for the user ID of interest.
4005                    continue;
4006                }
4007                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4008                    // This situation is broken, and we should just get rid of it now.
4009                    mRecentTasks.remove(i);
4010                    task.removedFromRecents(mTaskPersister);
4011                    i--;
4012                    N--;
4013                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4014                    continue;
4015                }
4016                // Check whether this activity is currently available.
4017                if (task.realActivity != null) {
4018                    ActivityInfo ai = availActCache.get(task.realActivity);
4019                    if (ai == null) {
4020                        try {
4021                            ai = pm.getActivityInfo(task.realActivity,
4022                                    PackageManager.GET_UNINSTALLED_PACKAGES
4023                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4024                        } catch (RemoteException e) {
4025                            // Will never happen.
4026                            continue;
4027                        }
4028                        if (ai == null) {
4029                            ai = dummyAct;
4030                        }
4031                        availActCache.put(task.realActivity, ai);
4032                    }
4033                    if (ai == dummyAct) {
4034                        // This could be either because the activity no longer exists, or the
4035                        // app is temporarily gone.  For the former we want to remove the recents
4036                        // entry; for the latter we want to mark it as unavailable.
4037                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4038                        if (app == null) {
4039                            try {
4040                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4041                                        PackageManager.GET_UNINSTALLED_PACKAGES
4042                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4043                            } catch (RemoteException e) {
4044                                // Will never happen.
4045                                continue;
4046                            }
4047                            if (app == null) {
4048                                app = dummyApp;
4049                            }
4050                            availAppCache.put(task.realActivity.getPackageName(), app);
4051                        }
4052                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4053                            // Doesn't exist any more!  Good-bye.
4054                            mRecentTasks.remove(i);
4055                            task.removedFromRecents(mTaskPersister);
4056                            i--;
4057                            N--;
4058                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4059                            continue;
4060                        } else {
4061                            // Otherwise just not available for now.
4062                            if (task.isAvailable) {
4063                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4064                                        + task);
4065                            }
4066                            task.isAvailable = false;
4067                        }
4068                    } else {
4069                        if (!ai.enabled || !ai.applicationInfo.enabled
4070                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4071                            if (task.isAvailable) {
4072                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4073                                        + task + " (enabled=" + ai.enabled + "/"
4074                                        + ai.applicationInfo.enabled +  " flags="
4075                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4076                            }
4077                            task.isAvailable = false;
4078                        } else {
4079                            if (!task.isAvailable) {
4080                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4081                                        + task);
4082                            }
4083                            task.isAvailable = true;
4084                        }
4085                    }
4086                }
4087            }
4088        }
4089
4090        // Verify the affiliate chain for each task.
4091        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4092        }
4093
4094        mTmpRecents.clear();
4095        // mRecentTasks is now in sorted, affiliated order.
4096    }
4097
4098    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4099        int N = mRecentTasks.size();
4100        TaskRecord top = task;
4101        int topIndex = taskIndex;
4102        while (top.mNextAffiliate != null && topIndex > 0) {
4103            top = top.mNextAffiliate;
4104            topIndex--;
4105        }
4106        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4107                + topIndex + " from intial " + taskIndex);
4108        // Find the end of the chain, doing a sanity check along the way.
4109        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4110        int endIndex = topIndex;
4111        TaskRecord prev = top;
4112        while (endIndex < N) {
4113            TaskRecord cur = mRecentTasks.get(endIndex);
4114            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4115                    + endIndex + " " + cur);
4116            if (cur == top) {
4117                // Verify start of the chain.
4118                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4119                    Slog.wtf(TAG, "Bad chain @" + endIndex
4120                            + ": first task has next affiliate: " + prev);
4121                    sane = false;
4122                    break;
4123                }
4124            } else {
4125                // Verify middle of the chain's next points back to the one before.
4126                if (cur.mNextAffiliate != prev
4127                        || cur.mNextAffiliateTaskId != prev.taskId) {
4128                    Slog.wtf(TAG, "Bad chain @" + endIndex
4129                            + ": middle task " + cur + " @" + endIndex
4130                            + " has bad next affiliate "
4131                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4132                            + ", expected " + prev);
4133                    sane = false;
4134                    break;
4135                }
4136            }
4137            if (cur.mPrevAffiliateTaskId == -1) {
4138                // Chain ends here.
4139                if (cur.mPrevAffiliate != null) {
4140                    Slog.wtf(TAG, "Bad chain @" + endIndex
4141                            + ": last task " + cur + " has previous affiliate "
4142                            + cur.mPrevAffiliate);
4143                    sane = false;
4144                }
4145                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4146                break;
4147            } else {
4148                // Verify middle of the chain's prev points to a valid item.
4149                if (cur.mPrevAffiliate == null) {
4150                    Slog.wtf(TAG, "Bad chain @" + endIndex
4151                            + ": task " + cur + " has previous affiliate "
4152                            + cur.mPrevAffiliate + " but should be id "
4153                            + cur.mPrevAffiliate);
4154                    sane = false;
4155                    break;
4156                }
4157            }
4158            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4159                Slog.wtf(TAG, "Bad chain @" + endIndex
4160                        + ": task " + cur + " has affiliated id "
4161                        + cur.mAffiliatedTaskId + " but should be "
4162                        + task.mAffiliatedTaskId);
4163                sane = false;
4164                break;
4165            }
4166            prev = cur;
4167            endIndex++;
4168            if (endIndex >= N) {
4169                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4170                        + ": last task " + prev);
4171                sane = false;
4172                break;
4173            }
4174        }
4175        if (sane) {
4176            if (endIndex < taskIndex) {
4177                Slog.wtf(TAG, "Bad chain @" + endIndex
4178                        + ": did not extend to task " + task + " @" + taskIndex);
4179                sane = false;
4180            }
4181        }
4182        if (sane) {
4183            // All looks good, we can just move all of the affiliated tasks
4184            // to the top.
4185            for (int i=topIndex; i<=endIndex; i++) {
4186                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4187                        + " from " + i + " to " + (i-topIndex));
4188                TaskRecord cur = mRecentTasks.remove(i);
4189                mRecentTasks.add(i-topIndex, cur);
4190            }
4191            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4192                    + " to " + endIndex);
4193            return true;
4194        }
4195
4196        // Whoops, couldn't do it.
4197        return false;
4198    }
4199
4200    final void addRecentTaskLocked(TaskRecord task) {
4201        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4202                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4203
4204        int N = mRecentTasks.size();
4205        // Quick case: check if the top-most recent task is the same.
4206        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4207            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4208            return;
4209        }
4210        // Another quick case: check if this is part of a set of affiliated
4211        // tasks that are at the top.
4212        if (isAffiliated && N > 0 && task.inRecents
4213                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4214            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4215                    + " at top when adding " + task);
4216            return;
4217        }
4218        // Another quick case: never add voice sessions.
4219        if (task.voiceSession != null) {
4220            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4221            return;
4222        }
4223
4224        boolean needAffiliationFix = false;
4225
4226        // Slightly less quick case: the task is already in recents, so all we need
4227        // to do is move it.
4228        if (task.inRecents) {
4229            int taskIndex = mRecentTasks.indexOf(task);
4230            if (taskIndex >= 0) {
4231                if (!isAffiliated) {
4232                    // Simple case: this is not an affiliated task, so we just move it to the front.
4233                    mRecentTasks.remove(taskIndex);
4234                    mRecentTasks.add(0, task);
4235                    notifyTaskPersisterLocked(task, false);
4236                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4237                            + " from " + taskIndex);
4238                    return;
4239                } else {
4240                    // More complicated: need to keep all affiliated tasks together.
4241                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4242                        // All went well.
4243                        return;
4244                    }
4245
4246                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4247                    // everything and then go through our general path of adding a new task.
4248                    needAffiliationFix = true;
4249                }
4250            } else {
4251                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4252                needAffiliationFix = true;
4253            }
4254        }
4255
4256        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4257        trimRecentsForTask(task, true);
4258
4259        N = mRecentTasks.size();
4260        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4261            final TaskRecord tr = mRecentTasks.remove(N - 1);
4262            tr.removedFromRecents(mTaskPersister);
4263            N--;
4264        }
4265        task.inRecents = true;
4266        if (!isAffiliated || needAffiliationFix) {
4267            // If this is a simple non-affiliated task, or we had some failure trying to
4268            // handle it as part of an affilated task, then just place it at the top.
4269            mRecentTasks.add(0, task);
4270        } else if (isAffiliated) {
4271            // If this is a new affiliated task, then move all of the affiliated tasks
4272            // to the front and insert this new one.
4273            TaskRecord other = task.mNextAffiliate;
4274            if (other == null) {
4275                other = task.mPrevAffiliate;
4276            }
4277            if (other != null) {
4278                int otherIndex = mRecentTasks.indexOf(other);
4279                if (otherIndex >= 0) {
4280                    // Insert new task at appropriate location.
4281                    int taskIndex;
4282                    if (other == task.mNextAffiliate) {
4283                        // We found the index of our next affiliation, which is who is
4284                        // before us in the list, so add after that point.
4285                        taskIndex = otherIndex+1;
4286                    } else {
4287                        // We found the index of our previous affiliation, which is who is
4288                        // after us in the list, so add at their position.
4289                        taskIndex = otherIndex;
4290                    }
4291                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4292                            + taskIndex + ": " + task);
4293                    mRecentTasks.add(taskIndex, task);
4294
4295                    // Now move everything to the front.
4296                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4297                        // All went well.
4298                        return;
4299                    }
4300
4301                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4302                    // everything and then go through our general path of adding a new task.
4303                    needAffiliationFix = true;
4304                } else {
4305                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4306                            + other);
4307                    needAffiliationFix = true;
4308                }
4309            } else {
4310                if (DEBUG_RECENTS) Slog.d(TAG,
4311                        "addRecent: adding affiliated task without next/prev:" + task);
4312                needAffiliationFix = true;
4313            }
4314        }
4315        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4316
4317        if (needAffiliationFix) {
4318            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4319            cleanupRecentTasksLocked(task.userId);
4320        }
4321    }
4322
4323    /**
4324     * If needed, remove oldest existing entries in recents that are for the same kind
4325     * of task as the given one.
4326     */
4327    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4328        int N = mRecentTasks.size();
4329        final Intent intent = task.intent;
4330        final boolean document = intent != null && intent.isDocument();
4331
4332        int maxRecents = task.maxRecents - 1;
4333        for (int i=0; i<N; i++) {
4334            final TaskRecord tr = mRecentTasks.get(i);
4335            if (task != tr) {
4336                if (task.userId != tr.userId) {
4337                    continue;
4338                }
4339                if (i > MAX_RECENT_BITMAPS) {
4340                    tr.freeLastThumbnail();
4341                }
4342                final Intent trIntent = tr.intent;
4343                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4344                    (intent == null || !intent.filterEquals(trIntent))) {
4345                    continue;
4346                }
4347                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4348                if (document && trIsDocument) {
4349                    // These are the same document activity (not necessarily the same doc).
4350                    if (maxRecents > 0) {
4351                        --maxRecents;
4352                        continue;
4353                    }
4354                    // Hit the maximum number of documents for this task. Fall through
4355                    // and remove this document from recents.
4356                } else if (document || trIsDocument) {
4357                    // Only one of these is a document. Not the droid we're looking for.
4358                    continue;
4359                }
4360            }
4361
4362            if (!doTrim) {
4363                // If the caller is not actually asking for a trim, just tell them we reached
4364                // a point where the trim would happen.
4365                return i;
4366            }
4367
4368            // Either task and tr are the same or, their affinities match or their intents match
4369            // and neither of them is a document, or they are documents using the same activity
4370            // and their maxRecents has been reached.
4371            tr.disposeThumbnail();
4372            mRecentTasks.remove(i);
4373            if (task != tr) {
4374                tr.removedFromRecents(mTaskPersister);
4375            }
4376            i--;
4377            N--;
4378            if (task.intent == null) {
4379                // If the new recent task we are adding is not fully
4380                // specified, then replace it with the existing recent task.
4381                task = tr;
4382            }
4383            notifyTaskPersisterLocked(tr, false);
4384        }
4385
4386        return -1;
4387    }
4388
4389    @Override
4390    public void reportActivityFullyDrawn(IBinder token) {
4391        synchronized (this) {
4392            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4393            if (r == null) {
4394                return;
4395            }
4396            r.reportFullyDrawnLocked();
4397        }
4398    }
4399
4400    @Override
4401    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4402        synchronized (this) {
4403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404            if (r == null) {
4405                return;
4406            }
4407            final long origId = Binder.clearCallingIdentity();
4408            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4409            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4410                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4411            if (config != null) {
4412                r.frozenBeforeDestroy = true;
4413                if (!updateConfigurationLocked(config, r, false, false)) {
4414                    mStackSupervisor.resumeTopActivitiesLocked();
4415                }
4416            }
4417            Binder.restoreCallingIdentity(origId);
4418        }
4419    }
4420
4421    @Override
4422    public int getRequestedOrientation(IBinder token) {
4423        synchronized (this) {
4424            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4425            if (r == null) {
4426                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4427            }
4428            return mWindowManager.getAppOrientation(r.appToken);
4429        }
4430    }
4431
4432    /**
4433     * This is the internal entry point for handling Activity.finish().
4434     *
4435     * @param token The Binder token referencing the Activity we want to finish.
4436     * @param resultCode Result code, if any, from this Activity.
4437     * @param resultData Result data (Intent), if any, from this Activity.
4438     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4439     *            the root Activity in the task.
4440     *
4441     * @return Returns true if the activity successfully finished, or false if it is still running.
4442     */
4443    @Override
4444    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4445            boolean finishTask) {
4446        // Refuse possible leaked file descriptors
4447        if (resultData != null && resultData.hasFileDescriptors() == true) {
4448            throw new IllegalArgumentException("File descriptors passed in Intent");
4449        }
4450
4451        synchronized(this) {
4452            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4453            if (r == null) {
4454                return true;
4455            }
4456            // Keep track of the root activity of the task before we finish it
4457            TaskRecord tr = r.task;
4458            ActivityRecord rootR = tr.getRootActivity();
4459            // Do not allow task to finish in Lock Task mode.
4460            if (tr == mStackSupervisor.mLockTaskModeTask) {
4461                if (rootR == r) {
4462                    mStackSupervisor.showLockTaskToast();
4463                    return false;
4464                }
4465            }
4466            if (mController != null) {
4467                // Find the first activity that is not finishing.
4468                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4469                if (next != null) {
4470                    // ask watcher if this is allowed
4471                    boolean resumeOK = true;
4472                    try {
4473                        resumeOK = mController.activityResuming(next.packageName);
4474                    } catch (RemoteException e) {
4475                        mController = null;
4476                        Watchdog.getInstance().setActivityController(null);
4477                    }
4478
4479                    if (!resumeOK) {
4480                        return false;
4481                    }
4482                }
4483            }
4484            final long origId = Binder.clearCallingIdentity();
4485            try {
4486                boolean res;
4487                if (finishTask && r == rootR) {
4488                    // If requested, remove the task that is associated to this activity only if it
4489                    // was the root activity in the task.  The result code and data is ignored because
4490                    // we don't support returning them across task boundaries.
4491                    res = removeTaskByIdLocked(tr.taskId, 0);
4492                } else {
4493                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4494                            resultData, "app-request", true);
4495                }
4496                return res;
4497            } finally {
4498                Binder.restoreCallingIdentity(origId);
4499            }
4500        }
4501    }
4502
4503    @Override
4504    public final void finishHeavyWeightApp() {
4505        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4506                != PackageManager.PERMISSION_GRANTED) {
4507            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4508                    + Binder.getCallingPid()
4509                    + ", uid=" + Binder.getCallingUid()
4510                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4511            Slog.w(TAG, msg);
4512            throw new SecurityException(msg);
4513        }
4514
4515        synchronized(this) {
4516            if (mHeavyWeightProcess == null) {
4517                return;
4518            }
4519
4520            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4521                    mHeavyWeightProcess.activities);
4522            for (int i=0; i<activities.size(); i++) {
4523                ActivityRecord r = activities.get(i);
4524                if (!r.finishing) {
4525                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4526                            null, "finish-heavy", true);
4527                }
4528            }
4529
4530            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4531                    mHeavyWeightProcess.userId, 0));
4532            mHeavyWeightProcess = null;
4533        }
4534    }
4535
4536    @Override
4537    public void crashApplication(int uid, int initialPid, String packageName,
4538            String message) {
4539        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4540                != PackageManager.PERMISSION_GRANTED) {
4541            String msg = "Permission Denial: crashApplication() from pid="
4542                    + Binder.getCallingPid()
4543                    + ", uid=" + Binder.getCallingUid()
4544                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4545            Slog.w(TAG, msg);
4546            throw new SecurityException(msg);
4547        }
4548
4549        synchronized(this) {
4550            ProcessRecord proc = null;
4551
4552            // Figure out which process to kill.  We don't trust that initialPid
4553            // still has any relation to current pids, so must scan through the
4554            // list.
4555            synchronized (mPidsSelfLocked) {
4556                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4557                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4558                    if (p.uid != uid) {
4559                        continue;
4560                    }
4561                    if (p.pid == initialPid) {
4562                        proc = p;
4563                        break;
4564                    }
4565                    if (p.pkgList.containsKey(packageName)) {
4566                        proc = p;
4567                    }
4568                }
4569            }
4570
4571            if (proc == null) {
4572                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4573                        + " initialPid=" + initialPid
4574                        + " packageName=" + packageName);
4575                return;
4576            }
4577
4578            if (proc.thread != null) {
4579                if (proc.pid == Process.myPid()) {
4580                    Log.w(TAG, "crashApplication: trying to crash self!");
4581                    return;
4582                }
4583                long ident = Binder.clearCallingIdentity();
4584                try {
4585                    proc.thread.scheduleCrash(message);
4586                } catch (RemoteException e) {
4587                }
4588                Binder.restoreCallingIdentity(ident);
4589            }
4590        }
4591    }
4592
4593    @Override
4594    public final void finishSubActivity(IBinder token, String resultWho,
4595            int requestCode) {
4596        synchronized(this) {
4597            final long origId = Binder.clearCallingIdentity();
4598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4599            if (r != null) {
4600                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4601            }
4602            Binder.restoreCallingIdentity(origId);
4603        }
4604    }
4605
4606    @Override
4607    public boolean finishActivityAffinity(IBinder token) {
4608        synchronized(this) {
4609            final long origId = Binder.clearCallingIdentity();
4610            try {
4611                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4612
4613                ActivityRecord rootR = r.task.getRootActivity();
4614                // Do not allow task to finish in Lock Task mode.
4615                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4616                    if (rootR == r) {
4617                        mStackSupervisor.showLockTaskToast();
4618                        return false;
4619                    }
4620                }
4621                boolean res = false;
4622                if (r != null) {
4623                    res = r.task.stack.finishActivityAffinityLocked(r);
4624                }
4625                return res;
4626            } finally {
4627                Binder.restoreCallingIdentity(origId);
4628            }
4629        }
4630    }
4631
4632    @Override
4633    public void finishVoiceTask(IVoiceInteractionSession session) {
4634        synchronized(this) {
4635            final long origId = Binder.clearCallingIdentity();
4636            try {
4637                mStackSupervisor.finishVoiceTask(session);
4638            } finally {
4639                Binder.restoreCallingIdentity(origId);
4640            }
4641        }
4642
4643    }
4644
4645    @Override
4646    public boolean releaseActivityInstance(IBinder token) {
4647        synchronized(this) {
4648            final long origId = Binder.clearCallingIdentity();
4649            try {
4650                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4651                if (r.task == null || r.task.stack == null) {
4652                    return false;
4653                }
4654                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4655            } finally {
4656                Binder.restoreCallingIdentity(origId);
4657            }
4658        }
4659    }
4660
4661    @Override
4662    public void releaseSomeActivities(IApplicationThread appInt) {
4663        synchronized(this) {
4664            final long origId = Binder.clearCallingIdentity();
4665            try {
4666                ProcessRecord app = getRecordForAppLocked(appInt);
4667                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4668            } finally {
4669                Binder.restoreCallingIdentity(origId);
4670            }
4671        }
4672    }
4673
4674    @Override
4675    public boolean willActivityBeVisible(IBinder token) {
4676        synchronized(this) {
4677            ActivityStack stack = ActivityRecord.getStackLocked(token);
4678            if (stack != null) {
4679                return stack.willActivityBeVisibleLocked(token);
4680            }
4681            return false;
4682        }
4683    }
4684
4685    @Override
4686    public void overridePendingTransition(IBinder token, String packageName,
4687            int enterAnim, int exitAnim) {
4688        synchronized(this) {
4689            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4690            if (self == null) {
4691                return;
4692            }
4693
4694            final long origId = Binder.clearCallingIdentity();
4695
4696            if (self.state == ActivityState.RESUMED
4697                    || self.state == ActivityState.PAUSING) {
4698                mWindowManager.overridePendingAppTransition(packageName,
4699                        enterAnim, exitAnim, null);
4700            }
4701
4702            Binder.restoreCallingIdentity(origId);
4703        }
4704    }
4705
4706    /**
4707     * Main function for removing an existing process from the activity manager
4708     * as a result of that process going away.  Clears out all connections
4709     * to the process.
4710     */
4711    private final void handleAppDiedLocked(ProcessRecord app,
4712            boolean restarting, boolean allowRestart) {
4713        int pid = app.pid;
4714        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4715        if (!kept && !restarting) {
4716            removeLruProcessLocked(app);
4717            if (pid > 0) {
4718                ProcessList.remove(pid);
4719            }
4720        }
4721
4722        if (mProfileProc == app) {
4723            clearProfilerLocked();
4724        }
4725
4726        // Remove this application's activities from active lists.
4727        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4728
4729        app.activities.clear();
4730
4731        if (app.instrumentationClass != null) {
4732            Slog.w(TAG, "Crash of app " + app.processName
4733                  + " running instrumentation " + app.instrumentationClass);
4734            Bundle info = new Bundle();
4735            info.putString("shortMsg", "Process crashed.");
4736            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4737        }
4738
4739        if (!restarting) {
4740            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4741                // If there was nothing to resume, and we are not already
4742                // restarting this process, but there is a visible activity that
4743                // is hosted by the process...  then make sure all visible
4744                // activities are running, taking care of restarting this
4745                // process.
4746                if (hasVisibleActivities) {
4747                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4748                }
4749            }
4750        }
4751    }
4752
4753    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4754        IBinder threadBinder = thread.asBinder();
4755        // Find the application record.
4756        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4757            ProcessRecord rec = mLruProcesses.get(i);
4758            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4759                return i;
4760            }
4761        }
4762        return -1;
4763    }
4764
4765    final ProcessRecord getRecordForAppLocked(
4766            IApplicationThread thread) {
4767        if (thread == null) {
4768            return null;
4769        }
4770
4771        int appIndex = getLRURecordIndexForAppLocked(thread);
4772        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4773    }
4774
4775    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4776        // If there are no longer any background processes running,
4777        // and the app that died was not running instrumentation,
4778        // then tell everyone we are now low on memory.
4779        boolean haveBg = false;
4780        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4781            ProcessRecord rec = mLruProcesses.get(i);
4782            if (rec.thread != null
4783                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4784                haveBg = true;
4785                break;
4786            }
4787        }
4788
4789        if (!haveBg) {
4790            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4791            if (doReport) {
4792                long now = SystemClock.uptimeMillis();
4793                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4794                    doReport = false;
4795                } else {
4796                    mLastMemUsageReportTime = now;
4797                }
4798            }
4799            final ArrayList<ProcessMemInfo> memInfos
4800                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4801            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4802            long now = SystemClock.uptimeMillis();
4803            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4804                ProcessRecord rec = mLruProcesses.get(i);
4805                if (rec == dyingProc || rec.thread == null) {
4806                    continue;
4807                }
4808                if (doReport) {
4809                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4810                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4811                }
4812                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4813                    // The low memory report is overriding any current
4814                    // state for a GC request.  Make sure to do
4815                    // heavy/important/visible/foreground processes first.
4816                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4817                        rec.lastRequestedGc = 0;
4818                    } else {
4819                        rec.lastRequestedGc = rec.lastLowMemory;
4820                    }
4821                    rec.reportLowMemory = true;
4822                    rec.lastLowMemory = now;
4823                    mProcessesToGc.remove(rec);
4824                    addProcessToGcListLocked(rec);
4825                }
4826            }
4827            if (doReport) {
4828                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4829                mHandler.sendMessage(msg);
4830            }
4831            scheduleAppGcsLocked();
4832        }
4833    }
4834
4835    final void appDiedLocked(ProcessRecord app) {
4836       appDiedLocked(app, app.pid, app.thread);
4837    }
4838
4839    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4840        // First check if this ProcessRecord is actually active for the pid.
4841        synchronized (mPidsSelfLocked) {
4842            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4843            if (curProc != app) {
4844                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4845                return;
4846            }
4847        }
4848
4849        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4850        synchronized (stats) {
4851            stats.noteProcessDiedLocked(app.info.uid, pid);
4852        }
4853
4854        Process.killProcessQuiet(pid);
4855        Process.killProcessGroup(app.info.uid, pid);
4856        app.killed = true;
4857
4858        // Clean up already done if the process has been re-started.
4859        if (app.pid == pid && app.thread != null &&
4860                app.thread.asBinder() == thread.asBinder()) {
4861            boolean doLowMem = app.instrumentationClass == null;
4862            boolean doOomAdj = doLowMem;
4863            if (!app.killedByAm) {
4864                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4865                        + ") has died");
4866                mAllowLowerMemLevel = true;
4867            } else {
4868                // Note that we always want to do oom adj to update our state with the
4869                // new number of procs.
4870                mAllowLowerMemLevel = false;
4871                doLowMem = false;
4872            }
4873            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4874            if (DEBUG_CLEANUP) Slog.v(
4875                TAG, "Dying app: " + app + ", pid: " + pid
4876                + ", thread: " + thread.asBinder());
4877            handleAppDiedLocked(app, false, true);
4878
4879            if (doOomAdj) {
4880                updateOomAdjLocked();
4881            }
4882            if (doLowMem) {
4883                doLowMemReportIfNeededLocked(app);
4884            }
4885        } else if (app.pid != pid) {
4886            // A new process has already been started.
4887            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4888                    + ") has died and restarted (pid " + app.pid + ").");
4889            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4890        } else if (DEBUG_PROCESSES) {
4891            Slog.d(TAG, "Received spurious death notification for thread "
4892                    + thread.asBinder());
4893        }
4894    }
4895
4896    /**
4897     * If a stack trace dump file is configured, dump process stack traces.
4898     * @param clearTraces causes the dump file to be erased prior to the new
4899     *    traces being written, if true; when false, the new traces will be
4900     *    appended to any existing file content.
4901     * @param firstPids of dalvik VM processes to dump stack traces for first
4902     * @param lastPids of dalvik VM processes to dump stack traces for last
4903     * @param nativeProcs optional list of native process names to dump stack crawls
4904     * @return file containing stack traces, or null if no dump file is configured
4905     */
4906    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4907            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4908        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4909        if (tracesPath == null || tracesPath.length() == 0) {
4910            return null;
4911        }
4912
4913        File tracesFile = new File(tracesPath);
4914        try {
4915            File tracesDir = tracesFile.getParentFile();
4916            if (!tracesDir.exists()) {
4917                tracesDir.mkdirs();
4918                if (!SELinux.restorecon(tracesDir)) {
4919                    return null;
4920                }
4921            }
4922            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4923
4924            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4925            tracesFile.createNewFile();
4926            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4927        } catch (IOException e) {
4928            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4929            return null;
4930        }
4931
4932        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4933        return tracesFile;
4934    }
4935
4936    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4937            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4938        // Use a FileObserver to detect when traces finish writing.
4939        // The order of traces is considered important to maintain for legibility.
4940        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4941            @Override
4942            public synchronized void onEvent(int event, String path) { notify(); }
4943        };
4944
4945        try {
4946            observer.startWatching();
4947
4948            // First collect all of the stacks of the most important pids.
4949            if (firstPids != null) {
4950                try {
4951                    int num = firstPids.size();
4952                    for (int i = 0; i < num; i++) {
4953                        synchronized (observer) {
4954                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4955                            observer.wait(200);  // Wait for write-close, give up after 200msec
4956                        }
4957                    }
4958                } catch (InterruptedException e) {
4959                    Log.wtf(TAG, e);
4960                }
4961            }
4962
4963            // Next collect the stacks of the native pids
4964            if (nativeProcs != null) {
4965                int[] pids = Process.getPidsForCommands(nativeProcs);
4966                if (pids != null) {
4967                    for (int pid : pids) {
4968                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4969                    }
4970                }
4971            }
4972
4973            // Lastly, measure CPU usage.
4974            if (processCpuTracker != null) {
4975                processCpuTracker.init();
4976                System.gc();
4977                processCpuTracker.update();
4978                try {
4979                    synchronized (processCpuTracker) {
4980                        processCpuTracker.wait(500); // measure over 1/2 second.
4981                    }
4982                } catch (InterruptedException e) {
4983                }
4984                processCpuTracker.update();
4985
4986                // We'll take the stack crawls of just the top apps using CPU.
4987                final int N = processCpuTracker.countWorkingStats();
4988                int numProcs = 0;
4989                for (int i=0; i<N && numProcs<5; i++) {
4990                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4991                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4992                        numProcs++;
4993                        try {
4994                            synchronized (observer) {
4995                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4996                                observer.wait(200);  // Wait for write-close, give up after 200msec
4997                            }
4998                        } catch (InterruptedException e) {
4999                            Log.wtf(TAG, e);
5000                        }
5001
5002                    }
5003                }
5004            }
5005        } finally {
5006            observer.stopWatching();
5007        }
5008    }
5009
5010    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5011        if (true || IS_USER_BUILD) {
5012            return;
5013        }
5014        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5015        if (tracesPath == null || tracesPath.length() == 0) {
5016            return;
5017        }
5018
5019        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5020        StrictMode.allowThreadDiskWrites();
5021        try {
5022            final File tracesFile = new File(tracesPath);
5023            final File tracesDir = tracesFile.getParentFile();
5024            final File tracesTmp = new File(tracesDir, "__tmp__");
5025            try {
5026                if (!tracesDir.exists()) {
5027                    tracesDir.mkdirs();
5028                    if (!SELinux.restorecon(tracesDir.getPath())) {
5029                        return;
5030                    }
5031                }
5032                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5033
5034                if (tracesFile.exists()) {
5035                    tracesTmp.delete();
5036                    tracesFile.renameTo(tracesTmp);
5037                }
5038                StringBuilder sb = new StringBuilder();
5039                Time tobj = new Time();
5040                tobj.set(System.currentTimeMillis());
5041                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5042                sb.append(": ");
5043                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5044                sb.append(" since ");
5045                sb.append(msg);
5046                FileOutputStream fos = new FileOutputStream(tracesFile);
5047                fos.write(sb.toString().getBytes());
5048                if (app == null) {
5049                    fos.write("\n*** No application process!".getBytes());
5050                }
5051                fos.close();
5052                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5053            } catch (IOException e) {
5054                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5055                return;
5056            }
5057
5058            if (app != null) {
5059                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5060                firstPids.add(app.pid);
5061                dumpStackTraces(tracesPath, firstPids, null, null, null);
5062            }
5063
5064            File lastTracesFile = null;
5065            File curTracesFile = null;
5066            for (int i=9; i>=0; i--) {
5067                String name = String.format(Locale.US, "slow%02d.txt", i);
5068                curTracesFile = new File(tracesDir, name);
5069                if (curTracesFile.exists()) {
5070                    if (lastTracesFile != null) {
5071                        curTracesFile.renameTo(lastTracesFile);
5072                    } else {
5073                        curTracesFile.delete();
5074                    }
5075                }
5076                lastTracesFile = curTracesFile;
5077            }
5078            tracesFile.renameTo(curTracesFile);
5079            if (tracesTmp.exists()) {
5080                tracesTmp.renameTo(tracesFile);
5081            }
5082        } finally {
5083            StrictMode.setThreadPolicy(oldPolicy);
5084        }
5085    }
5086
5087    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5088            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5089        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5090        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5091
5092        if (mController != null) {
5093            try {
5094                // 0 == continue, -1 = kill process immediately
5095                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5096                if (res < 0 && app.pid != MY_PID) {
5097                    app.kill("anr", true);
5098                }
5099            } catch (RemoteException e) {
5100                mController = null;
5101                Watchdog.getInstance().setActivityController(null);
5102            }
5103        }
5104
5105        long anrTime = SystemClock.uptimeMillis();
5106        if (MONITOR_CPU_USAGE) {
5107            updateCpuStatsNow();
5108        }
5109
5110        synchronized (this) {
5111            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5112            if (mShuttingDown) {
5113                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5114                return;
5115            } else if (app.notResponding) {
5116                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5117                return;
5118            } else if (app.crashing) {
5119                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5120                return;
5121            }
5122
5123            // In case we come through here for the same app before completing
5124            // this one, mark as anring now so we will bail out.
5125            app.notResponding = true;
5126
5127            // Log the ANR to the event log.
5128            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5129                    app.processName, app.info.flags, annotation);
5130
5131            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5132            firstPids.add(app.pid);
5133
5134            int parentPid = app.pid;
5135            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5136            if (parentPid != app.pid) firstPids.add(parentPid);
5137
5138            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5139
5140            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5141                ProcessRecord r = mLruProcesses.get(i);
5142                if (r != null && r.thread != null) {
5143                    int pid = r.pid;
5144                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5145                        if (r.persistent) {
5146                            firstPids.add(pid);
5147                        } else {
5148                            lastPids.put(pid, Boolean.TRUE);
5149                        }
5150                    }
5151                }
5152            }
5153        }
5154
5155        // Log the ANR to the main log.
5156        StringBuilder info = new StringBuilder();
5157        info.setLength(0);
5158        info.append("ANR in ").append(app.processName);
5159        if (activity != null && activity.shortComponentName != null) {
5160            info.append(" (").append(activity.shortComponentName).append(")");
5161        }
5162        info.append("\n");
5163        info.append("PID: ").append(app.pid).append("\n");
5164        if (annotation != null) {
5165            info.append("Reason: ").append(annotation).append("\n");
5166        }
5167        if (parent != null && parent != activity) {
5168            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5169        }
5170
5171        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5172
5173        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5174                NATIVE_STACKS_OF_INTEREST);
5175
5176        String cpuInfo = null;
5177        if (MONITOR_CPU_USAGE) {
5178            updateCpuStatsNow();
5179            synchronized (mProcessCpuTracker) {
5180                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5181            }
5182            info.append(processCpuTracker.printCurrentLoad());
5183            info.append(cpuInfo);
5184        }
5185
5186        info.append(processCpuTracker.printCurrentState(anrTime));
5187
5188        Slog.e(TAG, info.toString());
5189        if (tracesFile == null) {
5190            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5191            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5192        }
5193
5194        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5195                cpuInfo, tracesFile, null);
5196
5197        if (mController != null) {
5198            try {
5199                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5200                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5201                if (res != 0) {
5202                    if (res < 0 && app.pid != MY_PID) {
5203                        app.kill("anr", true);
5204                    } else {
5205                        synchronized (this) {
5206                            mServices.scheduleServiceTimeoutLocked(app);
5207                        }
5208                    }
5209                    return;
5210                }
5211            } catch (RemoteException e) {
5212                mController = null;
5213                Watchdog.getInstance().setActivityController(null);
5214            }
5215        }
5216
5217        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5218        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5219                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5220
5221        synchronized (this) {
5222            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5223                app.kill("bg anr", true);
5224                return;
5225            }
5226
5227            // Set the app's notResponding state, and look up the errorReportReceiver
5228            makeAppNotRespondingLocked(app,
5229                    activity != null ? activity.shortComponentName : null,
5230                    annotation != null ? "ANR " + annotation : "ANR",
5231                    info.toString());
5232
5233            // Bring up the infamous App Not Responding dialog
5234            Message msg = Message.obtain();
5235            HashMap<String, Object> map = new HashMap<String, Object>();
5236            msg.what = SHOW_NOT_RESPONDING_MSG;
5237            msg.obj = map;
5238            msg.arg1 = aboveSystem ? 1 : 0;
5239            map.put("app", app);
5240            if (activity != null) {
5241                map.put("activity", activity);
5242            }
5243
5244            mHandler.sendMessage(msg);
5245        }
5246    }
5247
5248    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5249        if (!mLaunchWarningShown) {
5250            mLaunchWarningShown = true;
5251            mHandler.post(new Runnable() {
5252                @Override
5253                public void run() {
5254                    synchronized (ActivityManagerService.this) {
5255                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5256                        d.show();
5257                        mHandler.postDelayed(new Runnable() {
5258                            @Override
5259                            public void run() {
5260                                synchronized (ActivityManagerService.this) {
5261                                    d.dismiss();
5262                                    mLaunchWarningShown = false;
5263                                }
5264                            }
5265                        }, 4000);
5266                    }
5267                }
5268            });
5269        }
5270    }
5271
5272    @Override
5273    public boolean clearApplicationUserData(final String packageName,
5274            final IPackageDataObserver observer, int userId) {
5275        enforceNotIsolatedCaller("clearApplicationUserData");
5276        int uid = Binder.getCallingUid();
5277        int pid = Binder.getCallingPid();
5278        userId = handleIncomingUser(pid, uid,
5279                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5280        long callingId = Binder.clearCallingIdentity();
5281        try {
5282            IPackageManager pm = AppGlobals.getPackageManager();
5283            int pkgUid = -1;
5284            synchronized(this) {
5285                try {
5286                    pkgUid = pm.getPackageUid(packageName, userId);
5287                } catch (RemoteException e) {
5288                }
5289                if (pkgUid == -1) {
5290                    Slog.w(TAG, "Invalid packageName: " + packageName);
5291                    if (observer != null) {
5292                        try {
5293                            observer.onRemoveCompleted(packageName, false);
5294                        } catch (RemoteException e) {
5295                            Slog.i(TAG, "Observer no longer exists.");
5296                        }
5297                    }
5298                    return false;
5299                }
5300                if (uid == pkgUid || checkComponentPermission(
5301                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5302                        pid, uid, -1, true)
5303                        == PackageManager.PERMISSION_GRANTED) {
5304                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5305                } else {
5306                    throw new SecurityException("PID " + pid + " does not have permission "
5307                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5308                                    + " of package " + packageName);
5309                }
5310
5311                // Remove all tasks match the cleared application package and user
5312                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5313                    final TaskRecord tr = mRecentTasks.get(i);
5314                    final String taskPackageName =
5315                            tr.getBaseIntent().getComponent().getPackageName();
5316                    if (tr.userId != userId) continue;
5317                    if (!taskPackageName.equals(packageName)) continue;
5318                    removeTaskByIdLocked(tr.taskId, 0);
5319                }
5320            }
5321
5322            try {
5323                // Clear application user data
5324                pm.clearApplicationUserData(packageName, observer, userId);
5325
5326                synchronized(this) {
5327                    // Remove all permissions granted from/to this package
5328                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5329                }
5330
5331                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5332                        Uri.fromParts("package", packageName, null));
5333                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5334                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5335                        null, null, 0, null, null, null, false, false, userId);
5336            } catch (RemoteException e) {
5337            }
5338        } finally {
5339            Binder.restoreCallingIdentity(callingId);
5340        }
5341        return true;
5342    }
5343
5344    @Override
5345    public void killBackgroundProcesses(final String packageName, int userId) {
5346        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5347                != PackageManager.PERMISSION_GRANTED &&
5348                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5349                        != PackageManager.PERMISSION_GRANTED) {
5350            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5351                    + Binder.getCallingPid()
5352                    + ", uid=" + Binder.getCallingUid()
5353                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5354            Slog.w(TAG, msg);
5355            throw new SecurityException(msg);
5356        }
5357
5358        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5359                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5360        long callingId = Binder.clearCallingIdentity();
5361        try {
5362            IPackageManager pm = AppGlobals.getPackageManager();
5363            synchronized(this) {
5364                int appId = -1;
5365                try {
5366                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5367                } catch (RemoteException e) {
5368                }
5369                if (appId == -1) {
5370                    Slog.w(TAG, "Invalid packageName: " + packageName);
5371                    return;
5372                }
5373                killPackageProcessesLocked(packageName, appId, userId,
5374                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5375            }
5376        } finally {
5377            Binder.restoreCallingIdentity(callingId);
5378        }
5379    }
5380
5381    @Override
5382    public void killAllBackgroundProcesses() {
5383        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5384                != PackageManager.PERMISSION_GRANTED) {
5385            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5386                    + Binder.getCallingPid()
5387                    + ", uid=" + Binder.getCallingUid()
5388                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5389            Slog.w(TAG, msg);
5390            throw new SecurityException(msg);
5391        }
5392
5393        long callingId = Binder.clearCallingIdentity();
5394        try {
5395            synchronized(this) {
5396                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5397                final int NP = mProcessNames.getMap().size();
5398                for (int ip=0; ip<NP; ip++) {
5399                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5400                    final int NA = apps.size();
5401                    for (int ia=0; ia<NA; ia++) {
5402                        ProcessRecord app = apps.valueAt(ia);
5403                        if (app.persistent) {
5404                            // we don't kill persistent processes
5405                            continue;
5406                        }
5407                        if (app.removed) {
5408                            procs.add(app);
5409                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5410                            app.removed = true;
5411                            procs.add(app);
5412                        }
5413                    }
5414                }
5415
5416                int N = procs.size();
5417                for (int i=0; i<N; i++) {
5418                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5419                }
5420                mAllowLowerMemLevel = true;
5421                updateOomAdjLocked();
5422                doLowMemReportIfNeededLocked(null);
5423            }
5424        } finally {
5425            Binder.restoreCallingIdentity(callingId);
5426        }
5427    }
5428
5429    @Override
5430    public void forceStopPackage(final String packageName, int userId) {
5431        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5432                != PackageManager.PERMISSION_GRANTED) {
5433            String msg = "Permission Denial: forceStopPackage() from pid="
5434                    + Binder.getCallingPid()
5435                    + ", uid=" + Binder.getCallingUid()
5436                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5437            Slog.w(TAG, msg);
5438            throw new SecurityException(msg);
5439        }
5440        final int callingPid = Binder.getCallingPid();
5441        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5442                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5443        long callingId = Binder.clearCallingIdentity();
5444        try {
5445            IPackageManager pm = AppGlobals.getPackageManager();
5446            synchronized(this) {
5447                int[] users = userId == UserHandle.USER_ALL
5448                        ? getUsersLocked() : new int[] { userId };
5449                for (int user : users) {
5450                    int pkgUid = -1;
5451                    try {
5452                        pkgUid = pm.getPackageUid(packageName, user);
5453                    } catch (RemoteException e) {
5454                    }
5455                    if (pkgUid == -1) {
5456                        Slog.w(TAG, "Invalid packageName: " + packageName);
5457                        continue;
5458                    }
5459                    try {
5460                        pm.setPackageStoppedState(packageName, true, user);
5461                    } catch (RemoteException e) {
5462                    } catch (IllegalArgumentException e) {
5463                        Slog.w(TAG, "Failed trying to unstop package "
5464                                + packageName + ": " + e);
5465                    }
5466                    if (isUserRunningLocked(user, false)) {
5467                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5468                    }
5469                }
5470            }
5471        } finally {
5472            Binder.restoreCallingIdentity(callingId);
5473        }
5474    }
5475
5476    @Override
5477    public void addPackageDependency(String packageName) {
5478        synchronized (this) {
5479            int callingPid = Binder.getCallingPid();
5480            if (callingPid == Process.myPid()) {
5481                //  Yeah, um, no.
5482                Slog.w(TAG, "Can't addPackageDependency on system process");
5483                return;
5484            }
5485            ProcessRecord proc;
5486            synchronized (mPidsSelfLocked) {
5487                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5488            }
5489            if (proc != null) {
5490                if (proc.pkgDeps == null) {
5491                    proc.pkgDeps = new ArraySet<String>(1);
5492                }
5493                proc.pkgDeps.add(packageName);
5494            }
5495        }
5496    }
5497
5498    /*
5499     * The pkg name and app id have to be specified.
5500     */
5501    @Override
5502    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5503        if (pkg == null) {
5504            return;
5505        }
5506        // Make sure the uid is valid.
5507        if (appid < 0) {
5508            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5509            return;
5510        }
5511        int callerUid = Binder.getCallingUid();
5512        // Only the system server can kill an application
5513        if (callerUid == Process.SYSTEM_UID) {
5514            // Post an aysnc message to kill the application
5515            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5516            msg.arg1 = appid;
5517            msg.arg2 = 0;
5518            Bundle bundle = new Bundle();
5519            bundle.putString("pkg", pkg);
5520            bundle.putString("reason", reason);
5521            msg.obj = bundle;
5522            mHandler.sendMessage(msg);
5523        } else {
5524            throw new SecurityException(callerUid + " cannot kill pkg: " +
5525                    pkg);
5526        }
5527    }
5528
5529    @Override
5530    public void closeSystemDialogs(String reason) {
5531        enforceNotIsolatedCaller("closeSystemDialogs");
5532
5533        final int pid = Binder.getCallingPid();
5534        final int uid = Binder.getCallingUid();
5535        final long origId = Binder.clearCallingIdentity();
5536        try {
5537            synchronized (this) {
5538                // Only allow this from foreground processes, so that background
5539                // applications can't abuse it to prevent system UI from being shown.
5540                if (uid >= Process.FIRST_APPLICATION_UID) {
5541                    ProcessRecord proc;
5542                    synchronized (mPidsSelfLocked) {
5543                        proc = mPidsSelfLocked.get(pid);
5544                    }
5545                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5546                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5547                                + " from background process " + proc);
5548                        return;
5549                    }
5550                }
5551                closeSystemDialogsLocked(reason);
5552            }
5553        } finally {
5554            Binder.restoreCallingIdentity(origId);
5555        }
5556    }
5557
5558    void closeSystemDialogsLocked(String reason) {
5559        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5560        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5561                | Intent.FLAG_RECEIVER_FOREGROUND);
5562        if (reason != null) {
5563            intent.putExtra("reason", reason);
5564        }
5565        mWindowManager.closeSystemDialogs(reason);
5566
5567        mStackSupervisor.closeSystemDialogsLocked();
5568
5569        broadcastIntentLocked(null, null, intent, null,
5570                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5571                Process.SYSTEM_UID, UserHandle.USER_ALL);
5572    }
5573
5574    @Override
5575    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5576        enforceNotIsolatedCaller("getProcessMemoryInfo");
5577        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5578        for (int i=pids.length-1; i>=0; i--) {
5579            ProcessRecord proc;
5580            int oomAdj;
5581            synchronized (this) {
5582                synchronized (mPidsSelfLocked) {
5583                    proc = mPidsSelfLocked.get(pids[i]);
5584                    oomAdj = proc != null ? proc.setAdj : 0;
5585                }
5586            }
5587            infos[i] = new Debug.MemoryInfo();
5588            Debug.getMemoryInfo(pids[i], infos[i]);
5589            if (proc != null) {
5590                synchronized (this) {
5591                    if (proc.thread != null && proc.setAdj == oomAdj) {
5592                        // Record this for posterity if the process has been stable.
5593                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5594                                infos[i].getTotalUss(), false, proc.pkgList);
5595                    }
5596                }
5597            }
5598        }
5599        return infos;
5600    }
5601
5602    @Override
5603    public long[] getProcessPss(int[] pids) {
5604        enforceNotIsolatedCaller("getProcessPss");
5605        long[] pss = new long[pids.length];
5606        for (int i=pids.length-1; i>=0; i--) {
5607            ProcessRecord proc;
5608            int oomAdj;
5609            synchronized (this) {
5610                synchronized (mPidsSelfLocked) {
5611                    proc = mPidsSelfLocked.get(pids[i]);
5612                    oomAdj = proc != null ? proc.setAdj : 0;
5613                }
5614            }
5615            long[] tmpUss = new long[1];
5616            pss[i] = Debug.getPss(pids[i], tmpUss);
5617            if (proc != null) {
5618                synchronized (this) {
5619                    if (proc.thread != null && proc.setAdj == oomAdj) {
5620                        // Record this for posterity if the process has been stable.
5621                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5622                    }
5623                }
5624            }
5625        }
5626        return pss;
5627    }
5628
5629    @Override
5630    public void killApplicationProcess(String processName, int uid) {
5631        if (processName == null) {
5632            return;
5633        }
5634
5635        int callerUid = Binder.getCallingUid();
5636        // Only the system server can kill an application
5637        if (callerUid == Process.SYSTEM_UID) {
5638            synchronized (this) {
5639                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5640                if (app != null && app.thread != null) {
5641                    try {
5642                        app.thread.scheduleSuicide();
5643                    } catch (RemoteException e) {
5644                        // If the other end already died, then our work here is done.
5645                    }
5646                } else {
5647                    Slog.w(TAG, "Process/uid not found attempting kill of "
5648                            + processName + " / " + uid);
5649                }
5650            }
5651        } else {
5652            throw new SecurityException(callerUid + " cannot kill app process: " +
5653                    processName);
5654        }
5655    }
5656
5657    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5658        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5659                false, true, false, false, UserHandle.getUserId(uid), reason);
5660        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5661                Uri.fromParts("package", packageName, null));
5662        if (!mProcessesReady) {
5663            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5664                    | Intent.FLAG_RECEIVER_FOREGROUND);
5665        }
5666        intent.putExtra(Intent.EXTRA_UID, uid);
5667        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5668        broadcastIntentLocked(null, null, intent,
5669                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5670                false, false,
5671                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5672    }
5673
5674    private void forceStopUserLocked(int userId, String reason) {
5675        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5676        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5677        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5678                | Intent.FLAG_RECEIVER_FOREGROUND);
5679        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5680        broadcastIntentLocked(null, null, intent,
5681                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5682                false, false,
5683                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5684    }
5685
5686    private final boolean killPackageProcessesLocked(String packageName, int appId,
5687            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5688            boolean doit, boolean evenPersistent, String reason) {
5689        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5690
5691        // Remove all processes this package may have touched: all with the
5692        // same UID (except for the system or root user), and all whose name
5693        // matches the package name.
5694        final int NP = mProcessNames.getMap().size();
5695        for (int ip=0; ip<NP; ip++) {
5696            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5697            final int NA = apps.size();
5698            for (int ia=0; ia<NA; ia++) {
5699                ProcessRecord app = apps.valueAt(ia);
5700                if (app.persistent && !evenPersistent) {
5701                    // we don't kill persistent processes
5702                    continue;
5703                }
5704                if (app.removed) {
5705                    if (doit) {
5706                        procs.add(app);
5707                    }
5708                    continue;
5709                }
5710
5711                // Skip process if it doesn't meet our oom adj requirement.
5712                if (app.setAdj < minOomAdj) {
5713                    continue;
5714                }
5715
5716                // If no package is specified, we call all processes under the
5717                // give user id.
5718                if (packageName == null) {
5719                    if (app.userId != userId) {
5720                        continue;
5721                    }
5722                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5723                        continue;
5724                    }
5725                // Package has been specified, we want to hit all processes
5726                // that match it.  We need to qualify this by the processes
5727                // that are running under the specified app and user ID.
5728                } else {
5729                    final boolean isDep = app.pkgDeps != null
5730                            && app.pkgDeps.contains(packageName);
5731                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5732                        continue;
5733                    }
5734                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5735                        continue;
5736                    }
5737                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5738                        continue;
5739                    }
5740                }
5741
5742                // Process has passed all conditions, kill it!
5743                if (!doit) {
5744                    return true;
5745                }
5746                app.removed = true;
5747                procs.add(app);
5748            }
5749        }
5750
5751        int N = procs.size();
5752        for (int i=0; i<N; i++) {
5753            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5754        }
5755        updateOomAdjLocked();
5756        return N > 0;
5757    }
5758
5759    private final boolean forceStopPackageLocked(String name, int appId,
5760            boolean callerWillRestart, boolean purgeCache, boolean doit,
5761            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5762        int i;
5763        int N;
5764
5765        if (userId == UserHandle.USER_ALL && name == null) {
5766            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5767        }
5768
5769        if (appId < 0 && name != null) {
5770            try {
5771                appId = UserHandle.getAppId(
5772                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5773            } catch (RemoteException e) {
5774            }
5775        }
5776
5777        if (doit) {
5778            if (name != null) {
5779                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5780                        + " user=" + userId + ": " + reason);
5781            } else {
5782                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5783            }
5784
5785            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5786            for (int ip=pmap.size()-1; ip>=0; ip--) {
5787                SparseArray<Long> ba = pmap.valueAt(ip);
5788                for (i=ba.size()-1; i>=0; i--) {
5789                    boolean remove = false;
5790                    final int entUid = ba.keyAt(i);
5791                    if (name != null) {
5792                        if (userId == UserHandle.USER_ALL) {
5793                            if (UserHandle.getAppId(entUid) == appId) {
5794                                remove = true;
5795                            }
5796                        } else {
5797                            if (entUid == UserHandle.getUid(userId, appId)) {
5798                                remove = true;
5799                            }
5800                        }
5801                    } else if (UserHandle.getUserId(entUid) == userId) {
5802                        remove = true;
5803                    }
5804                    if (remove) {
5805                        ba.removeAt(i);
5806                    }
5807                }
5808                if (ba.size() == 0) {
5809                    pmap.removeAt(ip);
5810                }
5811            }
5812        }
5813
5814        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5815                -100, callerWillRestart, true, doit, evenPersistent,
5816                name == null ? ("stop user " + userId) : ("stop " + name));
5817
5818        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5819            if (!doit) {
5820                return true;
5821            }
5822            didSomething = true;
5823        }
5824
5825        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5826            if (!doit) {
5827                return true;
5828            }
5829            didSomething = true;
5830        }
5831
5832        if (name == null) {
5833            // Remove all sticky broadcasts from this user.
5834            mStickyBroadcasts.remove(userId);
5835        }
5836
5837        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5838        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5839                userId, providers)) {
5840            if (!doit) {
5841                return true;
5842            }
5843            didSomething = true;
5844        }
5845        N = providers.size();
5846        for (i=0; i<N; i++) {
5847            removeDyingProviderLocked(null, providers.get(i), true);
5848        }
5849
5850        // Remove transient permissions granted from/to this package/user
5851        removeUriPermissionsForPackageLocked(name, userId, false);
5852
5853        if (name == null || uninstalling) {
5854            // Remove pending intents.  For now we only do this when force
5855            // stopping users, because we have some problems when doing this
5856            // for packages -- app widgets are not currently cleaned up for
5857            // such packages, so they can be left with bad pending intents.
5858            if (mIntentSenderRecords.size() > 0) {
5859                Iterator<WeakReference<PendingIntentRecord>> it
5860                        = mIntentSenderRecords.values().iterator();
5861                while (it.hasNext()) {
5862                    WeakReference<PendingIntentRecord> wpir = it.next();
5863                    if (wpir == null) {
5864                        it.remove();
5865                        continue;
5866                    }
5867                    PendingIntentRecord pir = wpir.get();
5868                    if (pir == null) {
5869                        it.remove();
5870                        continue;
5871                    }
5872                    if (name == null) {
5873                        // Stopping user, remove all objects for the user.
5874                        if (pir.key.userId != userId) {
5875                            // Not the same user, skip it.
5876                            continue;
5877                        }
5878                    } else {
5879                        if (UserHandle.getAppId(pir.uid) != appId) {
5880                            // Different app id, skip it.
5881                            continue;
5882                        }
5883                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5884                            // Different user, skip it.
5885                            continue;
5886                        }
5887                        if (!pir.key.packageName.equals(name)) {
5888                            // Different package, skip it.
5889                            continue;
5890                        }
5891                    }
5892                    if (!doit) {
5893                        return true;
5894                    }
5895                    didSomething = true;
5896                    it.remove();
5897                    pir.canceled = true;
5898                    if (pir.key.activity != null) {
5899                        pir.key.activity.pendingResults.remove(pir.ref);
5900                    }
5901                }
5902            }
5903        }
5904
5905        if (doit) {
5906            if (purgeCache && name != null) {
5907                AttributeCache ac = AttributeCache.instance();
5908                if (ac != null) {
5909                    ac.removePackage(name);
5910                }
5911            }
5912            if (mBooted) {
5913                mStackSupervisor.resumeTopActivitiesLocked();
5914                mStackSupervisor.scheduleIdleLocked();
5915            }
5916        }
5917
5918        return didSomething;
5919    }
5920
5921    private final boolean removeProcessLocked(ProcessRecord app,
5922            boolean callerWillRestart, boolean allowRestart, String reason) {
5923        final String name = app.processName;
5924        final int uid = app.uid;
5925        if (DEBUG_PROCESSES) Slog.d(
5926            TAG, "Force removing proc " + app.toShortString() + " (" + name
5927            + "/" + uid + ")");
5928
5929        mProcessNames.remove(name, uid);
5930        mIsolatedProcesses.remove(app.uid);
5931        if (mHeavyWeightProcess == app) {
5932            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5933                    mHeavyWeightProcess.userId, 0));
5934            mHeavyWeightProcess = null;
5935        }
5936        boolean needRestart = false;
5937        if (app.pid > 0 && app.pid != MY_PID) {
5938            int pid = app.pid;
5939            synchronized (mPidsSelfLocked) {
5940                mPidsSelfLocked.remove(pid);
5941                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5942            }
5943            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5944            if (app.isolated) {
5945                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5946            }
5947            app.kill(reason, true);
5948            handleAppDiedLocked(app, true, allowRestart);
5949            removeLruProcessLocked(app);
5950
5951            if (app.persistent && !app.isolated) {
5952                if (!callerWillRestart) {
5953                    addAppLocked(app.info, false, null /* ABI override */);
5954                } else {
5955                    needRestart = true;
5956                }
5957            }
5958        } else {
5959            mRemovedProcesses.add(app);
5960        }
5961
5962        return needRestart;
5963    }
5964
5965    private final void processStartTimedOutLocked(ProcessRecord app) {
5966        final int pid = app.pid;
5967        boolean gone = false;
5968        synchronized (mPidsSelfLocked) {
5969            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5970            if (knownApp != null && knownApp.thread == null) {
5971                mPidsSelfLocked.remove(pid);
5972                gone = true;
5973            }
5974        }
5975
5976        if (gone) {
5977            Slog.w(TAG, "Process " + app + " failed to attach");
5978            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5979                    pid, app.uid, app.processName);
5980            mProcessNames.remove(app.processName, app.uid);
5981            mIsolatedProcesses.remove(app.uid);
5982            if (mHeavyWeightProcess == app) {
5983                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5984                        mHeavyWeightProcess.userId, 0));
5985                mHeavyWeightProcess = null;
5986            }
5987            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5988            if (app.isolated) {
5989                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5990            }
5991            // Take care of any launching providers waiting for this process.
5992            checkAppInLaunchingProvidersLocked(app, true);
5993            // Take care of any services that are waiting for the process.
5994            mServices.processStartTimedOutLocked(app);
5995            app.kill("start timeout", true);
5996            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5997                Slog.w(TAG, "Unattached app died before backup, skipping");
5998                try {
5999                    IBackupManager bm = IBackupManager.Stub.asInterface(
6000                            ServiceManager.getService(Context.BACKUP_SERVICE));
6001                    bm.agentDisconnected(app.info.packageName);
6002                } catch (RemoteException e) {
6003                    // Can't happen; the backup manager is local
6004                }
6005            }
6006            if (isPendingBroadcastProcessLocked(pid)) {
6007                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6008                skipPendingBroadcastLocked(pid);
6009            }
6010        } else {
6011            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6012        }
6013    }
6014
6015    private final boolean attachApplicationLocked(IApplicationThread thread,
6016            int pid) {
6017
6018        // Find the application record that is being attached...  either via
6019        // the pid if we are running in multiple processes, or just pull the
6020        // next app record if we are emulating process with anonymous threads.
6021        ProcessRecord app;
6022        if (pid != MY_PID && pid >= 0) {
6023            synchronized (mPidsSelfLocked) {
6024                app = mPidsSelfLocked.get(pid);
6025            }
6026        } else {
6027            app = null;
6028        }
6029
6030        if (app == null) {
6031            Slog.w(TAG, "No pending application record for pid " + pid
6032                    + " (IApplicationThread " + thread + "); dropping process");
6033            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6034            if (pid > 0 && pid != MY_PID) {
6035                Process.killProcessQuiet(pid);
6036                //TODO: Process.killProcessGroup(app.info.uid, pid);
6037            } else {
6038                try {
6039                    thread.scheduleExit();
6040                } catch (Exception e) {
6041                    // Ignore exceptions.
6042                }
6043            }
6044            return false;
6045        }
6046
6047        // If this application record is still attached to a previous
6048        // process, clean it up now.
6049        if (app.thread != null) {
6050            handleAppDiedLocked(app, true, true);
6051        }
6052
6053        // Tell the process all about itself.
6054
6055        if (localLOGV) Slog.v(
6056                TAG, "Binding process pid " + pid + " to record " + app);
6057
6058        final String processName = app.processName;
6059        try {
6060            AppDeathRecipient adr = new AppDeathRecipient(
6061                    app, pid, thread);
6062            thread.asBinder().linkToDeath(adr, 0);
6063            app.deathRecipient = adr;
6064        } catch (RemoteException e) {
6065            app.resetPackageList(mProcessStats);
6066            startProcessLocked(app, "link fail", processName);
6067            return false;
6068        }
6069
6070        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6071
6072        app.makeActive(thread, mProcessStats);
6073        app.curAdj = app.setAdj = -100;
6074        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6075        app.forcingToForeground = null;
6076        updateProcessForegroundLocked(app, false, false);
6077        app.hasShownUi = false;
6078        app.debugging = false;
6079        app.cached = false;
6080
6081        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6082
6083        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6084        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6085
6086        if (!normalMode) {
6087            Slog.i(TAG, "Launching preboot mode app: " + app);
6088        }
6089
6090        if (localLOGV) Slog.v(
6091            TAG, "New app record " + app
6092            + " thread=" + thread.asBinder() + " pid=" + pid);
6093        try {
6094            int testMode = IApplicationThread.DEBUG_OFF;
6095            if (mDebugApp != null && mDebugApp.equals(processName)) {
6096                testMode = mWaitForDebugger
6097                    ? IApplicationThread.DEBUG_WAIT
6098                    : IApplicationThread.DEBUG_ON;
6099                app.debugging = true;
6100                if (mDebugTransient) {
6101                    mDebugApp = mOrigDebugApp;
6102                    mWaitForDebugger = mOrigWaitForDebugger;
6103                }
6104            }
6105            String profileFile = app.instrumentationProfileFile;
6106            ParcelFileDescriptor profileFd = null;
6107            int samplingInterval = 0;
6108            boolean profileAutoStop = false;
6109            if (mProfileApp != null && mProfileApp.equals(processName)) {
6110                mProfileProc = app;
6111                profileFile = mProfileFile;
6112                profileFd = mProfileFd;
6113                samplingInterval = mSamplingInterval;
6114                profileAutoStop = mAutoStopProfiler;
6115            }
6116            boolean enableOpenGlTrace = false;
6117            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6118                enableOpenGlTrace = true;
6119                mOpenGlTraceApp = null;
6120            }
6121
6122            // If the app is being launched for restore or full backup, set it up specially
6123            boolean isRestrictedBackupMode = false;
6124            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6125                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6126                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6127                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6128            }
6129
6130            ensurePackageDexOpt(app.instrumentationInfo != null
6131                    ? app.instrumentationInfo.packageName
6132                    : app.info.packageName);
6133            if (app.instrumentationClass != null) {
6134                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6135            }
6136            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6137                    + processName + " with config " + mConfiguration);
6138            ApplicationInfo appInfo = app.instrumentationInfo != null
6139                    ? app.instrumentationInfo : app.info;
6140            app.compat = compatibilityInfoForPackageLocked(appInfo);
6141            if (profileFd != null) {
6142                profileFd = profileFd.dup();
6143            }
6144            ProfilerInfo profilerInfo = profileFile == null ? null
6145                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6146            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6147                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6148                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6149                    isRestrictedBackupMode || !normalMode, app.persistent,
6150                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6151                    mCoreSettingsObserver.getCoreSettingsLocked());
6152            updateLruProcessLocked(app, false, null);
6153            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6154        } catch (Exception e) {
6155            // todo: Yikes!  What should we do?  For now we will try to
6156            // start another process, but that could easily get us in
6157            // an infinite loop of restarting processes...
6158            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6159
6160            app.resetPackageList(mProcessStats);
6161            app.unlinkDeathRecipient();
6162            startProcessLocked(app, "bind fail", processName);
6163            return false;
6164        }
6165
6166        // Remove this record from the list of starting applications.
6167        mPersistentStartingProcesses.remove(app);
6168        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6169                "Attach application locked removing on hold: " + app);
6170        mProcessesOnHold.remove(app);
6171
6172        boolean badApp = false;
6173        boolean didSomething = false;
6174
6175        // See if the top visible activity is waiting to run in this process...
6176        if (normalMode) {
6177            try {
6178                if (mStackSupervisor.attachApplicationLocked(app)) {
6179                    didSomething = true;
6180                }
6181            } catch (Exception e) {
6182                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6183                badApp = true;
6184            }
6185        }
6186
6187        // Find any services that should be running in this process...
6188        if (!badApp) {
6189            try {
6190                didSomething |= mServices.attachApplicationLocked(app, processName);
6191            } catch (Exception e) {
6192                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6193                badApp = true;
6194            }
6195        }
6196
6197        // Check if a next-broadcast receiver is in this process...
6198        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6199            try {
6200                didSomething |= sendPendingBroadcastsLocked(app);
6201            } catch (Exception e) {
6202                // If the app died trying to launch the receiver we declare it 'bad'
6203                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6204                badApp = true;
6205            }
6206        }
6207
6208        // Check whether the next backup agent is in this process...
6209        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6210            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6211            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6212            try {
6213                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6214                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6215                        mBackupTarget.backupMode);
6216            } catch (Exception e) {
6217                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6218                badApp = true;
6219            }
6220        }
6221
6222        if (badApp) {
6223            app.kill("error during init", true);
6224            handleAppDiedLocked(app, false, true);
6225            return false;
6226        }
6227
6228        if (!didSomething) {
6229            updateOomAdjLocked();
6230        }
6231
6232        return true;
6233    }
6234
6235    @Override
6236    public final void attachApplication(IApplicationThread thread) {
6237        synchronized (this) {
6238            int callingPid = Binder.getCallingPid();
6239            final long origId = Binder.clearCallingIdentity();
6240            attachApplicationLocked(thread, callingPid);
6241            Binder.restoreCallingIdentity(origId);
6242        }
6243    }
6244
6245    @Override
6246    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6247        final long origId = Binder.clearCallingIdentity();
6248        synchronized (this) {
6249            ActivityStack stack = ActivityRecord.getStackLocked(token);
6250            if (stack != null) {
6251                ActivityRecord r =
6252                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6253                if (stopProfiling) {
6254                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6255                        try {
6256                            mProfileFd.close();
6257                        } catch (IOException e) {
6258                        }
6259                        clearProfilerLocked();
6260                    }
6261                }
6262            }
6263        }
6264        Binder.restoreCallingIdentity(origId);
6265    }
6266
6267    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6268        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6269                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6270    }
6271
6272    void enableScreenAfterBoot() {
6273        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6274                SystemClock.uptimeMillis());
6275        mWindowManager.enableScreenAfterBoot();
6276
6277        synchronized (this) {
6278            updateEventDispatchingLocked();
6279        }
6280    }
6281
6282    @Override
6283    public void showBootMessage(final CharSequence msg, final boolean always) {
6284        enforceNotIsolatedCaller("showBootMessage");
6285        mWindowManager.showBootMessage(msg, always);
6286    }
6287
6288    @Override
6289    public void keyguardWaitingForActivityDrawn() {
6290        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6291        final long token = Binder.clearCallingIdentity();
6292        try {
6293            synchronized (this) {
6294                if (DEBUG_LOCKSCREEN) logLockScreen("");
6295                mWindowManager.keyguardWaitingForActivityDrawn();
6296                if (mLockScreenShown) {
6297                    mLockScreenShown = false;
6298                    comeOutOfSleepIfNeededLocked();
6299                }
6300            }
6301        } finally {
6302            Binder.restoreCallingIdentity(token);
6303        }
6304    }
6305
6306    final void finishBooting() {
6307        synchronized (this) {
6308            if (!mBootAnimationComplete) {
6309                mCallFinishBooting = true;
6310                return;
6311            }
6312            mCallFinishBooting = false;
6313        }
6314
6315        // Register receivers to handle package update events
6316        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6317
6318        // Let system services know.
6319        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6320
6321        synchronized (this) {
6322            // Ensure that any processes we had put on hold are now started
6323            // up.
6324            final int NP = mProcessesOnHold.size();
6325            if (NP > 0) {
6326                ArrayList<ProcessRecord> procs =
6327                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6328                for (int ip=0; ip<NP; ip++) {
6329                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6330                            + procs.get(ip));
6331                    startProcessLocked(procs.get(ip), "on-hold", null);
6332                }
6333            }
6334
6335            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6336                // Start looking for apps that are abusing wake locks.
6337                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6338                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6339                // Tell anyone interested that we are done booting!
6340                SystemProperties.set("sys.boot_completed", "1");
6341
6342                // And trigger dev.bootcomplete if we are not showing encryption progress
6343                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6344                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6345                    SystemProperties.set("dev.bootcomplete", "1");
6346                }
6347                for (int i=0; i<mStartedUsers.size(); i++) {
6348                    UserStartedState uss = mStartedUsers.valueAt(i);
6349                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6350                        uss.mState = UserStartedState.STATE_RUNNING;
6351                        final int userId = mStartedUsers.keyAt(i);
6352                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6353                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6354                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6355                        broadcastIntentLocked(null, null, intent, null,
6356                                new IIntentReceiver.Stub() {
6357                                    @Override
6358                                    public void performReceive(Intent intent, int resultCode,
6359                                            String data, Bundle extras, boolean ordered,
6360                                            boolean sticky, int sendingUser) {
6361                                        synchronized (ActivityManagerService.this) {
6362                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6363                                                    true, false);
6364                                        }
6365                                    }
6366                                },
6367                                0, null, null,
6368                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6369                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6370                                userId);
6371                    }
6372                }
6373                scheduleStartProfilesLocked();
6374            }
6375        }
6376    }
6377
6378    @Override
6379    public void bootAnimationComplete() {
6380        final boolean callFinishBooting;
6381        synchronized (this) {
6382            callFinishBooting = mCallFinishBooting;
6383            mBootAnimationComplete = true;
6384        }
6385        if (callFinishBooting) {
6386            finishBooting();
6387        }
6388    }
6389
6390    final void ensureBootCompleted() {
6391        boolean booting;
6392        boolean enableScreen;
6393        synchronized (this) {
6394            booting = mBooting;
6395            mBooting = false;
6396            enableScreen = !mBooted;
6397            mBooted = true;
6398        }
6399
6400        if (booting) {
6401            finishBooting();
6402        }
6403
6404        if (enableScreen) {
6405            enableScreenAfterBoot();
6406        }
6407    }
6408
6409    @Override
6410    public final void activityResumed(IBinder token) {
6411        final long origId = Binder.clearCallingIdentity();
6412        synchronized(this) {
6413            ActivityStack stack = ActivityRecord.getStackLocked(token);
6414            if (stack != null) {
6415                ActivityRecord.activityResumedLocked(token);
6416            }
6417        }
6418        Binder.restoreCallingIdentity(origId);
6419    }
6420
6421    @Override
6422    public final void activityPaused(IBinder token) {
6423        final long origId = Binder.clearCallingIdentity();
6424        synchronized(this) {
6425            ActivityStack stack = ActivityRecord.getStackLocked(token);
6426            if (stack != null) {
6427                stack.activityPausedLocked(token, false);
6428            }
6429        }
6430        Binder.restoreCallingIdentity(origId);
6431    }
6432
6433    @Override
6434    public final void activityStopped(IBinder token, Bundle icicle,
6435            PersistableBundle persistentState, CharSequence description) {
6436        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6437
6438        // Refuse possible leaked file descriptors
6439        if (icicle != null && icicle.hasFileDescriptors()) {
6440            throw new IllegalArgumentException("File descriptors passed in Bundle");
6441        }
6442
6443        final long origId = Binder.clearCallingIdentity();
6444
6445        synchronized (this) {
6446            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6447            if (r != null) {
6448                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6449            }
6450        }
6451
6452        trimApplications();
6453
6454        Binder.restoreCallingIdentity(origId);
6455    }
6456
6457    @Override
6458    public final void activityDestroyed(IBinder token) {
6459        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6460        synchronized (this) {
6461            ActivityStack stack = ActivityRecord.getStackLocked(token);
6462            if (stack != null) {
6463                stack.activityDestroyedLocked(token);
6464            }
6465        }
6466    }
6467
6468    @Override
6469    public final void backgroundResourcesReleased(IBinder token) {
6470        final long origId = Binder.clearCallingIdentity();
6471        try {
6472            synchronized (this) {
6473                ActivityStack stack = ActivityRecord.getStackLocked(token);
6474                if (stack != null) {
6475                    stack.backgroundResourcesReleased(token);
6476                }
6477            }
6478        } finally {
6479            Binder.restoreCallingIdentity(origId);
6480        }
6481    }
6482
6483    @Override
6484    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6485        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6486    }
6487
6488    @Override
6489    public final void notifyEnterAnimationComplete(IBinder token) {
6490        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6491    }
6492
6493    @Override
6494    public String getCallingPackage(IBinder token) {
6495        synchronized (this) {
6496            ActivityRecord r = getCallingRecordLocked(token);
6497            return r != null ? r.info.packageName : null;
6498        }
6499    }
6500
6501    @Override
6502    public ComponentName getCallingActivity(IBinder token) {
6503        synchronized (this) {
6504            ActivityRecord r = getCallingRecordLocked(token);
6505            return r != null ? r.intent.getComponent() : null;
6506        }
6507    }
6508
6509    private ActivityRecord getCallingRecordLocked(IBinder token) {
6510        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6511        if (r == null) {
6512            return null;
6513        }
6514        return r.resultTo;
6515    }
6516
6517    @Override
6518    public ComponentName getActivityClassForToken(IBinder token) {
6519        synchronized(this) {
6520            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6521            if (r == null) {
6522                return null;
6523            }
6524            return r.intent.getComponent();
6525        }
6526    }
6527
6528    @Override
6529    public String getPackageForToken(IBinder token) {
6530        synchronized(this) {
6531            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6532            if (r == null) {
6533                return null;
6534            }
6535            return r.packageName;
6536        }
6537    }
6538
6539    @Override
6540    public IIntentSender getIntentSender(int type,
6541            String packageName, IBinder token, String resultWho,
6542            int requestCode, Intent[] intents, String[] resolvedTypes,
6543            int flags, Bundle options, int userId) {
6544        enforceNotIsolatedCaller("getIntentSender");
6545        // Refuse possible leaked file descriptors
6546        if (intents != null) {
6547            if (intents.length < 1) {
6548                throw new IllegalArgumentException("Intents array length must be >= 1");
6549            }
6550            for (int i=0; i<intents.length; i++) {
6551                Intent intent = intents[i];
6552                if (intent != null) {
6553                    if (intent.hasFileDescriptors()) {
6554                        throw new IllegalArgumentException("File descriptors passed in Intent");
6555                    }
6556                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6557                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6558                        throw new IllegalArgumentException(
6559                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6560                    }
6561                    intents[i] = new Intent(intent);
6562                }
6563            }
6564            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6565                throw new IllegalArgumentException(
6566                        "Intent array length does not match resolvedTypes length");
6567            }
6568        }
6569        if (options != null) {
6570            if (options.hasFileDescriptors()) {
6571                throw new IllegalArgumentException("File descriptors passed in options");
6572            }
6573        }
6574
6575        synchronized(this) {
6576            int callingUid = Binder.getCallingUid();
6577            int origUserId = userId;
6578            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6579                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6580                    ALLOW_NON_FULL, "getIntentSender", null);
6581            if (origUserId == UserHandle.USER_CURRENT) {
6582                // We don't want to evaluate this until the pending intent is
6583                // actually executed.  However, we do want to always do the
6584                // security checking for it above.
6585                userId = UserHandle.USER_CURRENT;
6586            }
6587            try {
6588                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6589                    int uid = AppGlobals.getPackageManager()
6590                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6591                    if (!UserHandle.isSameApp(callingUid, uid)) {
6592                        String msg = "Permission Denial: getIntentSender() from pid="
6593                            + Binder.getCallingPid()
6594                            + ", uid=" + Binder.getCallingUid()
6595                            + ", (need uid=" + uid + ")"
6596                            + " is not allowed to send as package " + packageName;
6597                        Slog.w(TAG, msg);
6598                        throw new SecurityException(msg);
6599                    }
6600                }
6601
6602                return getIntentSenderLocked(type, packageName, callingUid, userId,
6603                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6604
6605            } catch (RemoteException e) {
6606                throw new SecurityException(e);
6607            }
6608        }
6609    }
6610
6611    IIntentSender getIntentSenderLocked(int type, String packageName,
6612            int callingUid, int userId, IBinder token, String resultWho,
6613            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6614            Bundle options) {
6615        if (DEBUG_MU)
6616            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6617        ActivityRecord activity = null;
6618        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6619            activity = ActivityRecord.isInStackLocked(token);
6620            if (activity == null) {
6621                return null;
6622            }
6623            if (activity.finishing) {
6624                return null;
6625            }
6626        }
6627
6628        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6629        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6630        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6631        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6632                |PendingIntent.FLAG_UPDATE_CURRENT);
6633
6634        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6635                type, packageName, activity, resultWho,
6636                requestCode, intents, resolvedTypes, flags, options, userId);
6637        WeakReference<PendingIntentRecord> ref;
6638        ref = mIntentSenderRecords.get(key);
6639        PendingIntentRecord rec = ref != null ? ref.get() : null;
6640        if (rec != null) {
6641            if (!cancelCurrent) {
6642                if (updateCurrent) {
6643                    if (rec.key.requestIntent != null) {
6644                        rec.key.requestIntent.replaceExtras(intents != null ?
6645                                intents[intents.length - 1] : null);
6646                    }
6647                    if (intents != null) {
6648                        intents[intents.length-1] = rec.key.requestIntent;
6649                        rec.key.allIntents = intents;
6650                        rec.key.allResolvedTypes = resolvedTypes;
6651                    } else {
6652                        rec.key.allIntents = null;
6653                        rec.key.allResolvedTypes = null;
6654                    }
6655                }
6656                return rec;
6657            }
6658            rec.canceled = true;
6659            mIntentSenderRecords.remove(key);
6660        }
6661        if (noCreate) {
6662            return rec;
6663        }
6664        rec = new PendingIntentRecord(this, key, callingUid);
6665        mIntentSenderRecords.put(key, rec.ref);
6666        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6667            if (activity.pendingResults == null) {
6668                activity.pendingResults
6669                        = new HashSet<WeakReference<PendingIntentRecord>>();
6670            }
6671            activity.pendingResults.add(rec.ref);
6672        }
6673        return rec;
6674    }
6675
6676    @Override
6677    public void cancelIntentSender(IIntentSender sender) {
6678        if (!(sender instanceof PendingIntentRecord)) {
6679            return;
6680        }
6681        synchronized(this) {
6682            PendingIntentRecord rec = (PendingIntentRecord)sender;
6683            try {
6684                int uid = AppGlobals.getPackageManager()
6685                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6686                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6687                    String msg = "Permission Denial: cancelIntentSender() from pid="
6688                        + Binder.getCallingPid()
6689                        + ", uid=" + Binder.getCallingUid()
6690                        + " is not allowed to cancel packges "
6691                        + rec.key.packageName;
6692                    Slog.w(TAG, msg);
6693                    throw new SecurityException(msg);
6694                }
6695            } catch (RemoteException e) {
6696                throw new SecurityException(e);
6697            }
6698            cancelIntentSenderLocked(rec, true);
6699        }
6700    }
6701
6702    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6703        rec.canceled = true;
6704        mIntentSenderRecords.remove(rec.key);
6705        if (cleanActivity && rec.key.activity != null) {
6706            rec.key.activity.pendingResults.remove(rec.ref);
6707        }
6708    }
6709
6710    @Override
6711    public String getPackageForIntentSender(IIntentSender pendingResult) {
6712        if (!(pendingResult instanceof PendingIntentRecord)) {
6713            return null;
6714        }
6715        try {
6716            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6717            return res.key.packageName;
6718        } catch (ClassCastException e) {
6719        }
6720        return null;
6721    }
6722
6723    @Override
6724    public int getUidForIntentSender(IIntentSender sender) {
6725        if (sender instanceof PendingIntentRecord) {
6726            try {
6727                PendingIntentRecord res = (PendingIntentRecord)sender;
6728                return res.uid;
6729            } catch (ClassCastException e) {
6730            }
6731        }
6732        return -1;
6733    }
6734
6735    @Override
6736    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6737        if (!(pendingResult instanceof PendingIntentRecord)) {
6738            return false;
6739        }
6740        try {
6741            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6742            if (res.key.allIntents == null) {
6743                return false;
6744            }
6745            for (int i=0; i<res.key.allIntents.length; i++) {
6746                Intent intent = res.key.allIntents[i];
6747                if (intent.getPackage() != null && intent.getComponent() != null) {
6748                    return false;
6749                }
6750            }
6751            return true;
6752        } catch (ClassCastException e) {
6753        }
6754        return false;
6755    }
6756
6757    @Override
6758    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6759        if (!(pendingResult instanceof PendingIntentRecord)) {
6760            return false;
6761        }
6762        try {
6763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6764            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6765                return true;
6766            }
6767            return false;
6768        } catch (ClassCastException e) {
6769        }
6770        return false;
6771    }
6772
6773    @Override
6774    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6775        if (!(pendingResult instanceof PendingIntentRecord)) {
6776            return null;
6777        }
6778        try {
6779            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6780            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6781        } catch (ClassCastException e) {
6782        }
6783        return null;
6784    }
6785
6786    @Override
6787    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6788        if (!(pendingResult instanceof PendingIntentRecord)) {
6789            return null;
6790        }
6791        try {
6792            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6793            Intent intent = res.key.requestIntent;
6794            if (intent != null) {
6795                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6796                        || res.lastTagPrefix.equals(prefix))) {
6797                    return res.lastTag;
6798                }
6799                res.lastTagPrefix = prefix;
6800                StringBuilder sb = new StringBuilder(128);
6801                if (prefix != null) {
6802                    sb.append(prefix);
6803                }
6804                if (intent.getAction() != null) {
6805                    sb.append(intent.getAction());
6806                } else if (intent.getComponent() != null) {
6807                    intent.getComponent().appendShortString(sb);
6808                } else {
6809                    sb.append("?");
6810                }
6811                return res.lastTag = sb.toString();
6812            }
6813        } catch (ClassCastException e) {
6814        }
6815        return null;
6816    }
6817
6818    @Override
6819    public void setProcessLimit(int max) {
6820        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6821                "setProcessLimit()");
6822        synchronized (this) {
6823            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6824            mProcessLimitOverride = max;
6825        }
6826        trimApplications();
6827    }
6828
6829    @Override
6830    public int getProcessLimit() {
6831        synchronized (this) {
6832            return mProcessLimitOverride;
6833        }
6834    }
6835
6836    void foregroundTokenDied(ForegroundToken token) {
6837        synchronized (ActivityManagerService.this) {
6838            synchronized (mPidsSelfLocked) {
6839                ForegroundToken cur
6840                    = mForegroundProcesses.get(token.pid);
6841                if (cur != token) {
6842                    return;
6843                }
6844                mForegroundProcesses.remove(token.pid);
6845                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6846                if (pr == null) {
6847                    return;
6848                }
6849                pr.forcingToForeground = null;
6850                updateProcessForegroundLocked(pr, false, false);
6851            }
6852            updateOomAdjLocked();
6853        }
6854    }
6855
6856    @Override
6857    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6858        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6859                "setProcessForeground()");
6860        synchronized(this) {
6861            boolean changed = false;
6862
6863            synchronized (mPidsSelfLocked) {
6864                ProcessRecord pr = mPidsSelfLocked.get(pid);
6865                if (pr == null && isForeground) {
6866                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6867                    return;
6868                }
6869                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6870                if (oldToken != null) {
6871                    oldToken.token.unlinkToDeath(oldToken, 0);
6872                    mForegroundProcesses.remove(pid);
6873                    if (pr != null) {
6874                        pr.forcingToForeground = null;
6875                    }
6876                    changed = true;
6877                }
6878                if (isForeground && token != null) {
6879                    ForegroundToken newToken = new ForegroundToken() {
6880                        @Override
6881                        public void binderDied() {
6882                            foregroundTokenDied(this);
6883                        }
6884                    };
6885                    newToken.pid = pid;
6886                    newToken.token = token;
6887                    try {
6888                        token.linkToDeath(newToken, 0);
6889                        mForegroundProcesses.put(pid, newToken);
6890                        pr.forcingToForeground = token;
6891                        changed = true;
6892                    } catch (RemoteException e) {
6893                        // If the process died while doing this, we will later
6894                        // do the cleanup with the process death link.
6895                    }
6896                }
6897            }
6898
6899            if (changed) {
6900                updateOomAdjLocked();
6901            }
6902        }
6903    }
6904
6905    // =========================================================
6906    // PERMISSIONS
6907    // =========================================================
6908
6909    static class PermissionController extends IPermissionController.Stub {
6910        ActivityManagerService mActivityManagerService;
6911        PermissionController(ActivityManagerService activityManagerService) {
6912            mActivityManagerService = activityManagerService;
6913        }
6914
6915        @Override
6916        public boolean checkPermission(String permission, int pid, int uid) {
6917            return mActivityManagerService.checkPermission(permission, pid,
6918                    uid) == PackageManager.PERMISSION_GRANTED;
6919        }
6920    }
6921
6922    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6923        @Override
6924        public int checkComponentPermission(String permission, int pid, int uid,
6925                int owningUid, boolean exported) {
6926            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6927                    owningUid, exported);
6928        }
6929
6930        @Override
6931        public Object getAMSLock() {
6932            return ActivityManagerService.this;
6933        }
6934    }
6935
6936    /**
6937     * This can be called with or without the global lock held.
6938     */
6939    int checkComponentPermission(String permission, int pid, int uid,
6940            int owningUid, boolean exported) {
6941        // We might be performing an operation on behalf of an indirect binder
6942        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6943        // client identity accordingly before proceeding.
6944        Identity tlsIdentity = sCallerIdentity.get();
6945        if (tlsIdentity != null) {
6946            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6947                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6948            uid = tlsIdentity.uid;
6949            pid = tlsIdentity.pid;
6950        }
6951
6952        if (pid == MY_PID) {
6953            return PackageManager.PERMISSION_GRANTED;
6954        }
6955
6956        return ActivityManager.checkComponentPermission(permission, uid,
6957                owningUid, exported);
6958    }
6959
6960    /**
6961     * As the only public entry point for permissions checking, this method
6962     * can enforce the semantic that requesting a check on a null global
6963     * permission is automatically denied.  (Internally a null permission
6964     * string is used when calling {@link #checkComponentPermission} in cases
6965     * when only uid-based security is needed.)
6966     *
6967     * This can be called with or without the global lock held.
6968     */
6969    @Override
6970    public int checkPermission(String permission, int pid, int uid) {
6971        if (permission == null) {
6972            return PackageManager.PERMISSION_DENIED;
6973        }
6974        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6975    }
6976
6977    /**
6978     * Binder IPC calls go through the public entry point.
6979     * This can be called with or without the global lock held.
6980     */
6981    int checkCallingPermission(String permission) {
6982        return checkPermission(permission,
6983                Binder.getCallingPid(),
6984                UserHandle.getAppId(Binder.getCallingUid()));
6985    }
6986
6987    /**
6988     * This can be called with or without the global lock held.
6989     */
6990    void enforceCallingPermission(String permission, String func) {
6991        if (checkCallingPermission(permission)
6992                == PackageManager.PERMISSION_GRANTED) {
6993            return;
6994        }
6995
6996        String msg = "Permission Denial: " + func + " from pid="
6997                + Binder.getCallingPid()
6998                + ", uid=" + Binder.getCallingUid()
6999                + " requires " + permission;
7000        Slog.w(TAG, msg);
7001        throw new SecurityException(msg);
7002    }
7003
7004    /**
7005     * Determine if UID is holding permissions required to access {@link Uri} in
7006     * the given {@link ProviderInfo}. Final permission checking is always done
7007     * in {@link ContentProvider}.
7008     */
7009    private final boolean checkHoldingPermissionsLocked(
7010            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7011        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7012                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7013        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7014            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7015                    != PERMISSION_GRANTED) {
7016                return false;
7017            }
7018        }
7019        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7020    }
7021
7022    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7023            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7024        if (pi.applicationInfo.uid == uid) {
7025            return true;
7026        } else if (!pi.exported) {
7027            return false;
7028        }
7029
7030        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7031        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7032        try {
7033            // check if target holds top-level <provider> permissions
7034            if (!readMet && pi.readPermission != null && considerUidPermissions
7035                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7036                readMet = true;
7037            }
7038            if (!writeMet && pi.writePermission != null && considerUidPermissions
7039                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7040                writeMet = true;
7041            }
7042
7043            // track if unprotected read/write is allowed; any denied
7044            // <path-permission> below removes this ability
7045            boolean allowDefaultRead = pi.readPermission == null;
7046            boolean allowDefaultWrite = pi.writePermission == null;
7047
7048            // check if target holds any <path-permission> that match uri
7049            final PathPermission[] pps = pi.pathPermissions;
7050            if (pps != null) {
7051                final String path = grantUri.uri.getPath();
7052                int i = pps.length;
7053                while (i > 0 && (!readMet || !writeMet)) {
7054                    i--;
7055                    PathPermission pp = pps[i];
7056                    if (pp.match(path)) {
7057                        if (!readMet) {
7058                            final String pprperm = pp.getReadPermission();
7059                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7060                                    + pprperm + " for " + pp.getPath()
7061                                    + ": match=" + pp.match(path)
7062                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7063                            if (pprperm != null) {
7064                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7065                                        == PERMISSION_GRANTED) {
7066                                    readMet = true;
7067                                } else {
7068                                    allowDefaultRead = false;
7069                                }
7070                            }
7071                        }
7072                        if (!writeMet) {
7073                            final String ppwperm = pp.getWritePermission();
7074                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7075                                    + ppwperm + " for " + pp.getPath()
7076                                    + ": match=" + pp.match(path)
7077                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7078                            if (ppwperm != null) {
7079                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7080                                        == PERMISSION_GRANTED) {
7081                                    writeMet = true;
7082                                } else {
7083                                    allowDefaultWrite = false;
7084                                }
7085                            }
7086                        }
7087                    }
7088                }
7089            }
7090
7091            // grant unprotected <provider> read/write, if not blocked by
7092            // <path-permission> above
7093            if (allowDefaultRead) readMet = true;
7094            if (allowDefaultWrite) writeMet = true;
7095
7096        } catch (RemoteException e) {
7097            return false;
7098        }
7099
7100        return readMet && writeMet;
7101    }
7102
7103    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7104        ProviderInfo pi = null;
7105        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7106        if (cpr != null) {
7107            pi = cpr.info;
7108        } else {
7109            try {
7110                pi = AppGlobals.getPackageManager().resolveContentProvider(
7111                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7112            } catch (RemoteException ex) {
7113            }
7114        }
7115        return pi;
7116    }
7117
7118    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7119        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7120        if (targetUris != null) {
7121            return targetUris.get(grantUri);
7122        }
7123        return null;
7124    }
7125
7126    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7127            String targetPkg, int targetUid, GrantUri grantUri) {
7128        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7129        if (targetUris == null) {
7130            targetUris = Maps.newArrayMap();
7131            mGrantedUriPermissions.put(targetUid, targetUris);
7132        }
7133
7134        UriPermission perm = targetUris.get(grantUri);
7135        if (perm == null) {
7136            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7137            targetUris.put(grantUri, perm);
7138        }
7139
7140        return perm;
7141    }
7142
7143    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7144            final int modeFlags) {
7145        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7146        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7147                : UriPermission.STRENGTH_OWNED;
7148
7149        // Root gets to do everything.
7150        if (uid == 0) {
7151            return true;
7152        }
7153
7154        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7155        if (perms == null) return false;
7156
7157        // First look for exact match
7158        final UriPermission exactPerm = perms.get(grantUri);
7159        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7160            return true;
7161        }
7162
7163        // No exact match, look for prefixes
7164        final int N = perms.size();
7165        for (int i = 0; i < N; i++) {
7166            final UriPermission perm = perms.valueAt(i);
7167            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7168                    && perm.getStrength(modeFlags) >= minStrength) {
7169                return true;
7170            }
7171        }
7172
7173        return false;
7174    }
7175
7176    /**
7177     * @param uri This uri must NOT contain an embedded userId.
7178     * @param userId The userId in which the uri is to be resolved.
7179     */
7180    @Override
7181    public int checkUriPermission(Uri uri, int pid, int uid,
7182            final int modeFlags, int userId) {
7183        enforceNotIsolatedCaller("checkUriPermission");
7184
7185        // Another redirected-binder-call permissions check as in
7186        // {@link checkComponentPermission}.
7187        Identity tlsIdentity = sCallerIdentity.get();
7188        if (tlsIdentity != null) {
7189            uid = tlsIdentity.uid;
7190            pid = tlsIdentity.pid;
7191        }
7192
7193        // Our own process gets to do everything.
7194        if (pid == MY_PID) {
7195            return PackageManager.PERMISSION_GRANTED;
7196        }
7197        synchronized (this) {
7198            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7199                    ? PackageManager.PERMISSION_GRANTED
7200                    : PackageManager.PERMISSION_DENIED;
7201        }
7202    }
7203
7204    /**
7205     * Check if the targetPkg can be granted permission to access uri by
7206     * the callingUid using the given modeFlags.  Throws a security exception
7207     * if callingUid is not allowed to do this.  Returns the uid of the target
7208     * if the URI permission grant should be performed; returns -1 if it is not
7209     * needed (for example targetPkg already has permission to access the URI).
7210     * If you already know the uid of the target, you can supply it in
7211     * lastTargetUid else set that to -1.
7212     */
7213    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7214            final int modeFlags, int lastTargetUid) {
7215        if (!Intent.isAccessUriMode(modeFlags)) {
7216            return -1;
7217        }
7218
7219        if (targetPkg != null) {
7220            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7221                    "Checking grant " + targetPkg + " permission to " + grantUri);
7222        }
7223
7224        final IPackageManager pm = AppGlobals.getPackageManager();
7225
7226        // If this is not a content: uri, we can't do anything with it.
7227        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7228            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7229                    "Can't grant URI permission for non-content URI: " + grantUri);
7230            return -1;
7231        }
7232
7233        final String authority = grantUri.uri.getAuthority();
7234        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7235        if (pi == null) {
7236            Slog.w(TAG, "No content provider found for permission check: " +
7237                    grantUri.uri.toSafeString());
7238            return -1;
7239        }
7240
7241        int targetUid = lastTargetUid;
7242        if (targetUid < 0 && targetPkg != null) {
7243            try {
7244                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7245                if (targetUid < 0) {
7246                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7247                            "Can't grant URI permission no uid for: " + targetPkg);
7248                    return -1;
7249                }
7250            } catch (RemoteException ex) {
7251                return -1;
7252            }
7253        }
7254
7255        if (targetUid >= 0) {
7256            // First...  does the target actually need this permission?
7257            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7258                // No need to grant the target this permission.
7259                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7260                        "Target " + targetPkg + " already has full permission to " + grantUri);
7261                return -1;
7262            }
7263        } else {
7264            // First...  there is no target package, so can anyone access it?
7265            boolean allowed = pi.exported;
7266            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7267                if (pi.readPermission != null) {
7268                    allowed = false;
7269                }
7270            }
7271            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7272                if (pi.writePermission != null) {
7273                    allowed = false;
7274                }
7275            }
7276            if (allowed) {
7277                return -1;
7278            }
7279        }
7280
7281        /* There is a special cross user grant if:
7282         * - The target is on another user.
7283         * - Apps on the current user can access the uri without any uid permissions.
7284         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7285         * grant uri permissions.
7286         */
7287        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7288                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7289                modeFlags, false /*without considering the uid permissions*/);
7290
7291        // Second...  is the provider allowing granting of URI permissions?
7292        if (!specialCrossUserGrant) {
7293            if (!pi.grantUriPermissions) {
7294                throw new SecurityException("Provider " + pi.packageName
7295                        + "/" + pi.name
7296                        + " does not allow granting of Uri permissions (uri "
7297                        + grantUri + ")");
7298            }
7299            if (pi.uriPermissionPatterns != null) {
7300                final int N = pi.uriPermissionPatterns.length;
7301                boolean allowed = false;
7302                for (int i=0; i<N; i++) {
7303                    if (pi.uriPermissionPatterns[i] != null
7304                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7305                        allowed = true;
7306                        break;
7307                    }
7308                }
7309                if (!allowed) {
7310                    throw new SecurityException("Provider " + pi.packageName
7311                            + "/" + pi.name
7312                            + " does not allow granting of permission to path of Uri "
7313                            + grantUri);
7314                }
7315            }
7316        }
7317
7318        // Third...  does the caller itself have permission to access
7319        // this uri?
7320        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7321            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7322                // Require they hold a strong enough Uri permission
7323                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7324                    throw new SecurityException("Uid " + callingUid
7325                            + " does not have permission to uri " + grantUri);
7326                }
7327            }
7328        }
7329        return targetUid;
7330    }
7331
7332    /**
7333     * @param uri This uri must NOT contain an embedded userId.
7334     * @param userId The userId in which the uri is to be resolved.
7335     */
7336    @Override
7337    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7338            final int modeFlags, int userId) {
7339        enforceNotIsolatedCaller("checkGrantUriPermission");
7340        synchronized(this) {
7341            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7342                    new GrantUri(userId, uri, false), modeFlags, -1);
7343        }
7344    }
7345
7346    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7347            final int modeFlags, UriPermissionOwner owner) {
7348        if (!Intent.isAccessUriMode(modeFlags)) {
7349            return;
7350        }
7351
7352        // So here we are: the caller has the assumed permission
7353        // to the uri, and the target doesn't.  Let's now give this to
7354        // the target.
7355
7356        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7357                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7358
7359        final String authority = grantUri.uri.getAuthority();
7360        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7361        if (pi == null) {
7362            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7363            return;
7364        }
7365
7366        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7367            grantUri.prefix = true;
7368        }
7369        final UriPermission perm = findOrCreateUriPermissionLocked(
7370                pi.packageName, targetPkg, targetUid, grantUri);
7371        perm.grantModes(modeFlags, owner);
7372    }
7373
7374    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7375            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7376        if (targetPkg == null) {
7377            throw new NullPointerException("targetPkg");
7378        }
7379        int targetUid;
7380        final IPackageManager pm = AppGlobals.getPackageManager();
7381        try {
7382            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7383        } catch (RemoteException ex) {
7384            return;
7385        }
7386
7387        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7388                targetUid);
7389        if (targetUid < 0) {
7390            return;
7391        }
7392
7393        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7394                owner);
7395    }
7396
7397    static class NeededUriGrants extends ArrayList<GrantUri> {
7398        final String targetPkg;
7399        final int targetUid;
7400        final int flags;
7401
7402        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7403            this.targetPkg = targetPkg;
7404            this.targetUid = targetUid;
7405            this.flags = flags;
7406        }
7407    }
7408
7409    /**
7410     * Like checkGrantUriPermissionLocked, but takes an Intent.
7411     */
7412    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7413            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7414        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7415                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7416                + " clip=" + (intent != null ? intent.getClipData() : null)
7417                + " from " + intent + "; flags=0x"
7418                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7419
7420        if (targetPkg == null) {
7421            throw new NullPointerException("targetPkg");
7422        }
7423
7424        if (intent == null) {
7425            return null;
7426        }
7427        Uri data = intent.getData();
7428        ClipData clip = intent.getClipData();
7429        if (data == null && clip == null) {
7430            return null;
7431        }
7432        // Default userId for uris in the intent (if they don't specify it themselves)
7433        int contentUserHint = intent.getContentUserHint();
7434        if (contentUserHint == UserHandle.USER_CURRENT) {
7435            contentUserHint = UserHandle.getUserId(callingUid);
7436        }
7437        final IPackageManager pm = AppGlobals.getPackageManager();
7438        int targetUid;
7439        if (needed != null) {
7440            targetUid = needed.targetUid;
7441        } else {
7442            try {
7443                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7444            } catch (RemoteException ex) {
7445                return null;
7446            }
7447            if (targetUid < 0) {
7448                if (DEBUG_URI_PERMISSION) {
7449                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7450                            + " on user " + targetUserId);
7451                }
7452                return null;
7453            }
7454        }
7455        if (data != null) {
7456            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7457            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7458                    targetUid);
7459            if (targetUid > 0) {
7460                if (needed == null) {
7461                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7462                }
7463                needed.add(grantUri);
7464            }
7465        }
7466        if (clip != null) {
7467            for (int i=0; i<clip.getItemCount(); i++) {
7468                Uri uri = clip.getItemAt(i).getUri();
7469                if (uri != null) {
7470                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7471                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7472                            targetUid);
7473                    if (targetUid > 0) {
7474                        if (needed == null) {
7475                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7476                        }
7477                        needed.add(grantUri);
7478                    }
7479                } else {
7480                    Intent clipIntent = clip.getItemAt(i).getIntent();
7481                    if (clipIntent != null) {
7482                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7483                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7484                        if (newNeeded != null) {
7485                            needed = newNeeded;
7486                        }
7487                    }
7488                }
7489            }
7490        }
7491
7492        return needed;
7493    }
7494
7495    /**
7496     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7497     */
7498    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7499            UriPermissionOwner owner) {
7500        if (needed != null) {
7501            for (int i=0; i<needed.size(); i++) {
7502                GrantUri grantUri = needed.get(i);
7503                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7504                        grantUri, needed.flags, owner);
7505            }
7506        }
7507    }
7508
7509    void grantUriPermissionFromIntentLocked(int callingUid,
7510            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7511        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7512                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7513        if (needed == null) {
7514            return;
7515        }
7516
7517        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7518    }
7519
7520    /**
7521     * @param uri This uri must NOT contain an embedded userId.
7522     * @param userId The userId in which the uri is to be resolved.
7523     */
7524    @Override
7525    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7526            final int modeFlags, int userId) {
7527        enforceNotIsolatedCaller("grantUriPermission");
7528        GrantUri grantUri = new GrantUri(userId, uri, false);
7529        synchronized(this) {
7530            final ProcessRecord r = getRecordForAppLocked(caller);
7531            if (r == null) {
7532                throw new SecurityException("Unable to find app for caller "
7533                        + caller
7534                        + " when granting permission to uri " + grantUri);
7535            }
7536            if (targetPkg == null) {
7537                throw new IllegalArgumentException("null target");
7538            }
7539            if (grantUri == null) {
7540                throw new IllegalArgumentException("null uri");
7541            }
7542
7543            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7544                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7545                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7546                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7547
7548            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7549                    UserHandle.getUserId(r.uid));
7550        }
7551    }
7552
7553    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7554        if (perm.modeFlags == 0) {
7555            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7556                    perm.targetUid);
7557            if (perms != null) {
7558                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7559                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7560
7561                perms.remove(perm.uri);
7562                if (perms.isEmpty()) {
7563                    mGrantedUriPermissions.remove(perm.targetUid);
7564                }
7565            }
7566        }
7567    }
7568
7569    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7570        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7571
7572        final IPackageManager pm = AppGlobals.getPackageManager();
7573        final String authority = grantUri.uri.getAuthority();
7574        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7575        if (pi == null) {
7576            Slog.w(TAG, "No content provider found for permission revoke: "
7577                    + grantUri.toSafeString());
7578            return;
7579        }
7580
7581        // Does the caller have this permission on the URI?
7582        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7583            // If they don't have direct access to the URI, then revoke any
7584            // ownerless URI permissions that have been granted to them.
7585            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7586            if (perms != null) {
7587                boolean persistChanged = false;
7588                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7589                    final UriPermission perm = it.next();
7590                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7591                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7592                        if (DEBUG_URI_PERMISSION)
7593                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7594                                    " permission to " + perm.uri);
7595                        persistChanged |= perm.revokeModes(
7596                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7597                        if (perm.modeFlags == 0) {
7598                            it.remove();
7599                        }
7600                    }
7601                }
7602                if (perms.isEmpty()) {
7603                    mGrantedUriPermissions.remove(callingUid);
7604                }
7605                if (persistChanged) {
7606                    schedulePersistUriGrants();
7607                }
7608            }
7609            return;
7610        }
7611
7612        boolean persistChanged = false;
7613
7614        // Go through all of the permissions and remove any that match.
7615        int N = mGrantedUriPermissions.size();
7616        for (int i = 0; i < N; i++) {
7617            final int targetUid = mGrantedUriPermissions.keyAt(i);
7618            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7619
7620            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7621                final UriPermission perm = it.next();
7622                if (perm.uri.sourceUserId == grantUri.sourceUserId
7623                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7624                    if (DEBUG_URI_PERMISSION)
7625                        Slog.v(TAG,
7626                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7627                    persistChanged |= perm.revokeModes(
7628                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7629                    if (perm.modeFlags == 0) {
7630                        it.remove();
7631                    }
7632                }
7633            }
7634
7635            if (perms.isEmpty()) {
7636                mGrantedUriPermissions.remove(targetUid);
7637                N--;
7638                i--;
7639            }
7640        }
7641
7642        if (persistChanged) {
7643            schedulePersistUriGrants();
7644        }
7645    }
7646
7647    /**
7648     * @param uri This uri must NOT contain an embedded userId.
7649     * @param userId The userId in which the uri is to be resolved.
7650     */
7651    @Override
7652    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7653            int userId) {
7654        enforceNotIsolatedCaller("revokeUriPermission");
7655        synchronized(this) {
7656            final ProcessRecord r = getRecordForAppLocked(caller);
7657            if (r == null) {
7658                throw new SecurityException("Unable to find app for caller "
7659                        + caller
7660                        + " when revoking permission to uri " + uri);
7661            }
7662            if (uri == null) {
7663                Slog.w(TAG, "revokeUriPermission: null uri");
7664                return;
7665            }
7666
7667            if (!Intent.isAccessUriMode(modeFlags)) {
7668                return;
7669            }
7670
7671            final IPackageManager pm = AppGlobals.getPackageManager();
7672            final String authority = uri.getAuthority();
7673            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7674            if (pi == null) {
7675                Slog.w(TAG, "No content provider found for permission revoke: "
7676                        + uri.toSafeString());
7677                return;
7678            }
7679
7680            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7681        }
7682    }
7683
7684    /**
7685     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7686     * given package.
7687     *
7688     * @param packageName Package name to match, or {@code null} to apply to all
7689     *            packages.
7690     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7691     *            to all users.
7692     * @param persistable If persistable grants should be removed.
7693     */
7694    private void removeUriPermissionsForPackageLocked(
7695            String packageName, int userHandle, boolean persistable) {
7696        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7697            throw new IllegalArgumentException("Must narrow by either package or user");
7698        }
7699
7700        boolean persistChanged = false;
7701
7702        int N = mGrantedUriPermissions.size();
7703        for (int i = 0; i < N; i++) {
7704            final int targetUid = mGrantedUriPermissions.keyAt(i);
7705            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7706
7707            // Only inspect grants matching user
7708            if (userHandle == UserHandle.USER_ALL
7709                    || userHandle == UserHandle.getUserId(targetUid)) {
7710                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7711                    final UriPermission perm = it.next();
7712
7713                    // Only inspect grants matching package
7714                    if (packageName == null || perm.sourcePkg.equals(packageName)
7715                            || perm.targetPkg.equals(packageName)) {
7716                        persistChanged |= perm.revokeModes(persistable
7717                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7718
7719                        // Only remove when no modes remain; any persisted grants
7720                        // will keep this alive.
7721                        if (perm.modeFlags == 0) {
7722                            it.remove();
7723                        }
7724                    }
7725                }
7726
7727                if (perms.isEmpty()) {
7728                    mGrantedUriPermissions.remove(targetUid);
7729                    N--;
7730                    i--;
7731                }
7732            }
7733        }
7734
7735        if (persistChanged) {
7736            schedulePersistUriGrants();
7737        }
7738    }
7739
7740    @Override
7741    public IBinder newUriPermissionOwner(String name) {
7742        enforceNotIsolatedCaller("newUriPermissionOwner");
7743        synchronized(this) {
7744            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7745            return owner.getExternalTokenLocked();
7746        }
7747    }
7748
7749    /**
7750     * @param uri This uri must NOT contain an embedded userId.
7751     * @param sourceUserId The userId in which the uri is to be resolved.
7752     * @param targetUserId The userId of the app that receives the grant.
7753     */
7754    @Override
7755    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7756            final int modeFlags, int sourceUserId, int targetUserId) {
7757        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7758                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7759        synchronized(this) {
7760            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7761            if (owner == null) {
7762                throw new IllegalArgumentException("Unknown owner: " + token);
7763            }
7764            if (fromUid != Binder.getCallingUid()) {
7765                if (Binder.getCallingUid() != Process.myUid()) {
7766                    // Only system code can grant URI permissions on behalf
7767                    // of other users.
7768                    throw new SecurityException("nice try");
7769                }
7770            }
7771            if (targetPkg == null) {
7772                throw new IllegalArgumentException("null target");
7773            }
7774            if (uri == null) {
7775                throw new IllegalArgumentException("null uri");
7776            }
7777
7778            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7779                    modeFlags, owner, targetUserId);
7780        }
7781    }
7782
7783    /**
7784     * @param uri This uri must NOT contain an embedded userId.
7785     * @param userId The userId in which the uri is to be resolved.
7786     */
7787    @Override
7788    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7789        synchronized(this) {
7790            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7791            if (owner == null) {
7792                throw new IllegalArgumentException("Unknown owner: " + token);
7793            }
7794
7795            if (uri == null) {
7796                owner.removeUriPermissionsLocked(mode);
7797            } else {
7798                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7799            }
7800        }
7801    }
7802
7803    private void schedulePersistUriGrants() {
7804        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7805            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7806                    10 * DateUtils.SECOND_IN_MILLIS);
7807        }
7808    }
7809
7810    private void writeGrantedUriPermissions() {
7811        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7812
7813        // Snapshot permissions so we can persist without lock
7814        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7815        synchronized (this) {
7816            final int size = mGrantedUriPermissions.size();
7817            for (int i = 0; i < size; i++) {
7818                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7819                for (UriPermission perm : perms.values()) {
7820                    if (perm.persistedModeFlags != 0) {
7821                        persist.add(perm.snapshot());
7822                    }
7823                }
7824            }
7825        }
7826
7827        FileOutputStream fos = null;
7828        try {
7829            fos = mGrantFile.startWrite();
7830
7831            XmlSerializer out = new FastXmlSerializer();
7832            out.setOutput(fos, "utf-8");
7833            out.startDocument(null, true);
7834            out.startTag(null, TAG_URI_GRANTS);
7835            for (UriPermission.Snapshot perm : persist) {
7836                out.startTag(null, TAG_URI_GRANT);
7837                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7838                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7839                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7840                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7841                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7842                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7843                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7844                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7845                out.endTag(null, TAG_URI_GRANT);
7846            }
7847            out.endTag(null, TAG_URI_GRANTS);
7848            out.endDocument();
7849
7850            mGrantFile.finishWrite(fos);
7851        } catch (IOException e) {
7852            if (fos != null) {
7853                mGrantFile.failWrite(fos);
7854            }
7855        }
7856    }
7857
7858    private void readGrantedUriPermissionsLocked() {
7859        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7860
7861        final long now = System.currentTimeMillis();
7862
7863        FileInputStream fis = null;
7864        try {
7865            fis = mGrantFile.openRead();
7866            final XmlPullParser in = Xml.newPullParser();
7867            in.setInput(fis, null);
7868
7869            int type;
7870            while ((type = in.next()) != END_DOCUMENT) {
7871                final String tag = in.getName();
7872                if (type == START_TAG) {
7873                    if (TAG_URI_GRANT.equals(tag)) {
7874                        final int sourceUserId;
7875                        final int targetUserId;
7876                        final int userHandle = readIntAttribute(in,
7877                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7878                        if (userHandle != UserHandle.USER_NULL) {
7879                            // For backwards compatibility.
7880                            sourceUserId = userHandle;
7881                            targetUserId = userHandle;
7882                        } else {
7883                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7884                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7885                        }
7886                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7887                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7888                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7889                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7890                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7891                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7892
7893                        // Sanity check that provider still belongs to source package
7894                        final ProviderInfo pi = getProviderInfoLocked(
7895                                uri.getAuthority(), sourceUserId);
7896                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7897                            int targetUid = -1;
7898                            try {
7899                                targetUid = AppGlobals.getPackageManager()
7900                                        .getPackageUid(targetPkg, targetUserId);
7901                            } catch (RemoteException e) {
7902                            }
7903                            if (targetUid != -1) {
7904                                final UriPermission perm = findOrCreateUriPermissionLocked(
7905                                        sourcePkg, targetPkg, targetUid,
7906                                        new GrantUri(sourceUserId, uri, prefix));
7907                                perm.initPersistedModes(modeFlags, createdTime);
7908                            }
7909                        } else {
7910                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7911                                    + " but instead found " + pi);
7912                        }
7913                    }
7914                }
7915            }
7916        } catch (FileNotFoundException e) {
7917            // Missing grants is okay
7918        } catch (IOException e) {
7919            Log.wtf(TAG, "Failed reading Uri grants", e);
7920        } catch (XmlPullParserException e) {
7921            Log.wtf(TAG, "Failed reading Uri grants", e);
7922        } finally {
7923            IoUtils.closeQuietly(fis);
7924        }
7925    }
7926
7927    /**
7928     * @param uri This uri must NOT contain an embedded userId.
7929     * @param userId The userId in which the uri is to be resolved.
7930     */
7931    @Override
7932    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7933        enforceNotIsolatedCaller("takePersistableUriPermission");
7934
7935        Preconditions.checkFlagsArgument(modeFlags,
7936                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7937
7938        synchronized (this) {
7939            final int callingUid = Binder.getCallingUid();
7940            boolean persistChanged = false;
7941            GrantUri grantUri = new GrantUri(userId, uri, false);
7942
7943            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7944                    new GrantUri(userId, uri, false));
7945            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7946                    new GrantUri(userId, uri, true));
7947
7948            final boolean exactValid = (exactPerm != null)
7949                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7950            final boolean prefixValid = (prefixPerm != null)
7951                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7952
7953            if (!(exactValid || prefixValid)) {
7954                throw new SecurityException("No persistable permission grants found for UID "
7955                        + callingUid + " and Uri " + grantUri.toSafeString());
7956            }
7957
7958            if (exactValid) {
7959                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7960            }
7961            if (prefixValid) {
7962                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7963            }
7964
7965            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7966
7967            if (persistChanged) {
7968                schedulePersistUriGrants();
7969            }
7970        }
7971    }
7972
7973    /**
7974     * @param uri This uri must NOT contain an embedded userId.
7975     * @param userId The userId in which the uri is to be resolved.
7976     */
7977    @Override
7978    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7979        enforceNotIsolatedCaller("releasePersistableUriPermission");
7980
7981        Preconditions.checkFlagsArgument(modeFlags,
7982                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7983
7984        synchronized (this) {
7985            final int callingUid = Binder.getCallingUid();
7986            boolean persistChanged = false;
7987
7988            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7989                    new GrantUri(userId, uri, false));
7990            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7991                    new GrantUri(userId, uri, true));
7992            if (exactPerm == null && prefixPerm == null) {
7993                throw new SecurityException("No permission grants found for UID " + callingUid
7994                        + " and Uri " + uri.toSafeString());
7995            }
7996
7997            if (exactPerm != null) {
7998                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7999                removeUriPermissionIfNeededLocked(exactPerm);
8000            }
8001            if (prefixPerm != null) {
8002                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8003                removeUriPermissionIfNeededLocked(prefixPerm);
8004            }
8005
8006            if (persistChanged) {
8007                schedulePersistUriGrants();
8008            }
8009        }
8010    }
8011
8012    /**
8013     * Prune any older {@link UriPermission} for the given UID until outstanding
8014     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8015     *
8016     * @return if any mutations occured that require persisting.
8017     */
8018    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8019        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8020        if (perms == null) return false;
8021        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8022
8023        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8024        for (UriPermission perm : perms.values()) {
8025            if (perm.persistedModeFlags != 0) {
8026                persisted.add(perm);
8027            }
8028        }
8029
8030        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8031        if (trimCount <= 0) return false;
8032
8033        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8034        for (int i = 0; i < trimCount; i++) {
8035            final UriPermission perm = persisted.get(i);
8036
8037            if (DEBUG_URI_PERMISSION) {
8038                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8039            }
8040
8041            perm.releasePersistableModes(~0);
8042            removeUriPermissionIfNeededLocked(perm);
8043        }
8044
8045        return true;
8046    }
8047
8048    @Override
8049    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8050            String packageName, boolean incoming) {
8051        enforceNotIsolatedCaller("getPersistedUriPermissions");
8052        Preconditions.checkNotNull(packageName, "packageName");
8053
8054        final int callingUid = Binder.getCallingUid();
8055        final IPackageManager pm = AppGlobals.getPackageManager();
8056        try {
8057            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8058            if (packageUid != callingUid) {
8059                throw new SecurityException(
8060                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8061            }
8062        } catch (RemoteException e) {
8063            throw new SecurityException("Failed to verify package name ownership");
8064        }
8065
8066        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8067        synchronized (this) {
8068            if (incoming) {
8069                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8070                        callingUid);
8071                if (perms == null) {
8072                    Slog.w(TAG, "No permission grants found for " + packageName);
8073                } else {
8074                    for (UriPermission perm : perms.values()) {
8075                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8076                            result.add(perm.buildPersistedPublicApiObject());
8077                        }
8078                    }
8079                }
8080            } else {
8081                final int size = mGrantedUriPermissions.size();
8082                for (int i = 0; i < size; i++) {
8083                    final ArrayMap<GrantUri, UriPermission> perms =
8084                            mGrantedUriPermissions.valueAt(i);
8085                    for (UriPermission perm : perms.values()) {
8086                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8087                            result.add(perm.buildPersistedPublicApiObject());
8088                        }
8089                    }
8090                }
8091            }
8092        }
8093        return new ParceledListSlice<android.content.UriPermission>(result);
8094    }
8095
8096    @Override
8097    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8098        synchronized (this) {
8099            ProcessRecord app =
8100                who != null ? getRecordForAppLocked(who) : null;
8101            if (app == null) return;
8102
8103            Message msg = Message.obtain();
8104            msg.what = WAIT_FOR_DEBUGGER_MSG;
8105            msg.obj = app;
8106            msg.arg1 = waiting ? 1 : 0;
8107            mHandler.sendMessage(msg);
8108        }
8109    }
8110
8111    @Override
8112    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8113        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8114        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8115        outInfo.availMem = Process.getFreeMemory();
8116        outInfo.totalMem = Process.getTotalMemory();
8117        outInfo.threshold = homeAppMem;
8118        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8119        outInfo.hiddenAppThreshold = cachedAppMem;
8120        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8121                ProcessList.SERVICE_ADJ);
8122        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8123                ProcessList.VISIBLE_APP_ADJ);
8124        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8125                ProcessList.FOREGROUND_APP_ADJ);
8126    }
8127
8128    // =========================================================
8129    // TASK MANAGEMENT
8130    // =========================================================
8131
8132    @Override
8133    public List<IAppTask> getAppTasks(String callingPackage) {
8134        int callingUid = Binder.getCallingUid();
8135        long ident = Binder.clearCallingIdentity();
8136
8137        synchronized(this) {
8138            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8139            try {
8140                if (localLOGV) Slog.v(TAG, "getAppTasks");
8141
8142                final int N = mRecentTasks.size();
8143                for (int i = 0; i < N; i++) {
8144                    TaskRecord tr = mRecentTasks.get(i);
8145                    // Skip tasks that do not match the caller.  We don't need to verify
8146                    // callingPackage, because we are also limiting to callingUid and know
8147                    // that will limit to the correct security sandbox.
8148                    if (tr.effectiveUid != callingUid) {
8149                        continue;
8150                    }
8151                    Intent intent = tr.getBaseIntent();
8152                    if (intent == null ||
8153                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8154                        continue;
8155                    }
8156                    ActivityManager.RecentTaskInfo taskInfo =
8157                            createRecentTaskInfoFromTaskRecord(tr);
8158                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8159                    list.add(taskImpl);
8160                }
8161            } finally {
8162                Binder.restoreCallingIdentity(ident);
8163            }
8164            return list;
8165        }
8166    }
8167
8168    @Override
8169    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8170        final int callingUid = Binder.getCallingUid();
8171        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8172
8173        synchronized(this) {
8174            if (localLOGV) Slog.v(
8175                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8176
8177            final boolean allowed = checkCallingPermission(
8178                    android.Manifest.permission.GET_TASKS)
8179                    == PackageManager.PERMISSION_GRANTED;
8180            if (!allowed) {
8181                Slog.w(TAG, "getTasks: caller " + callingUid
8182                        + " does not hold GET_TASKS; limiting output");
8183            }
8184
8185            // TODO: Improve with MRU list from all ActivityStacks.
8186            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8187        }
8188
8189        return list;
8190    }
8191
8192    TaskRecord getMostRecentTask() {
8193        return mRecentTasks.get(0);
8194    }
8195
8196    /**
8197     * Creates a new RecentTaskInfo from a TaskRecord.
8198     */
8199    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8200        // Update the task description to reflect any changes in the task stack
8201        tr.updateTaskDescription();
8202
8203        // Compose the recent task info
8204        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8205        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8206        rti.persistentId = tr.taskId;
8207        rti.baseIntent = new Intent(tr.getBaseIntent());
8208        rti.origActivity = tr.origActivity;
8209        rti.description = tr.lastDescription;
8210        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8211        rti.userId = tr.userId;
8212        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8213        rti.firstActiveTime = tr.firstActiveTime;
8214        rti.lastActiveTime = tr.lastActiveTime;
8215        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8216        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8217        return rti;
8218    }
8219
8220    @Override
8221    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8222        final int callingUid = Binder.getCallingUid();
8223        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8224                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8225
8226        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8227        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8228        synchronized (this) {
8229            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8230                    == PackageManager.PERMISSION_GRANTED;
8231            if (!allowed) {
8232                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8233                        + " does not hold GET_TASKS; limiting output");
8234            }
8235            final boolean detailed = checkCallingPermission(
8236                    android.Manifest.permission.GET_DETAILED_TASKS)
8237                    == PackageManager.PERMISSION_GRANTED;
8238
8239            final int N = mRecentTasks.size();
8240            ArrayList<ActivityManager.RecentTaskInfo> res
8241                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8242                            maxNum < N ? maxNum : N);
8243
8244            final Set<Integer> includedUsers;
8245            if (includeProfiles) {
8246                includedUsers = getProfileIdsLocked(userId);
8247            } else {
8248                includedUsers = new HashSet<Integer>();
8249            }
8250            includedUsers.add(Integer.valueOf(userId));
8251
8252            for (int i=0; i<N && maxNum > 0; i++) {
8253                TaskRecord tr = mRecentTasks.get(i);
8254                // Only add calling user or related users recent tasks
8255                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8256                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8257                    continue;
8258                }
8259
8260                // Return the entry if desired by the caller.  We always return
8261                // the first entry, because callers always expect this to be the
8262                // foreground app.  We may filter others if the caller has
8263                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8264                // we should exclude the entry.
8265
8266                if (i == 0
8267                        || withExcluded
8268                        || (tr.intent == null)
8269                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8270                                == 0)) {
8271                    if (!allowed) {
8272                        // If the caller doesn't have the GET_TASKS permission, then only
8273                        // allow them to see a small subset of tasks -- their own and home.
8274                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8275                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8276                            continue;
8277                        }
8278                    }
8279                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8280                        if (tr.stack != null && tr.stack.isHomeStack()) {
8281                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8282                            continue;
8283                        }
8284                    }
8285                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8286                        // Don't include auto remove tasks that are finished or finishing.
8287                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8288                                + tr);
8289                        continue;
8290                    }
8291                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8292                            && !tr.isAvailable) {
8293                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8294                        continue;
8295                    }
8296
8297                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8298                    if (!detailed) {
8299                        rti.baseIntent.replaceExtras((Bundle)null);
8300                    }
8301
8302                    res.add(rti);
8303                    maxNum--;
8304                }
8305            }
8306            return res;
8307        }
8308    }
8309
8310    private TaskRecord recentTaskForIdLocked(int id) {
8311        final int N = mRecentTasks.size();
8312            for (int i=0; i<N; i++) {
8313                TaskRecord tr = mRecentTasks.get(i);
8314                if (tr.taskId == id) {
8315                    return tr;
8316                }
8317            }
8318            return null;
8319    }
8320
8321    @Override
8322    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8323        synchronized (this) {
8324            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8325                    "getTaskThumbnail()");
8326            TaskRecord tr = recentTaskForIdLocked(id);
8327            if (tr != null) {
8328                return tr.getTaskThumbnailLocked();
8329            }
8330        }
8331        return null;
8332    }
8333
8334    @Override
8335    public int addAppTask(IBinder activityToken, Intent intent,
8336            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8337        final int callingUid = Binder.getCallingUid();
8338        final long callingIdent = Binder.clearCallingIdentity();
8339
8340        try {
8341            synchronized (this) {
8342                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8343                if (r == null) {
8344                    throw new IllegalArgumentException("Activity does not exist; token="
8345                            + activityToken);
8346                }
8347                ComponentName comp = intent.getComponent();
8348                if (comp == null) {
8349                    throw new IllegalArgumentException("Intent " + intent
8350                            + " must specify explicit component");
8351                }
8352                if (thumbnail.getWidth() != mThumbnailWidth
8353                        || thumbnail.getHeight() != mThumbnailHeight) {
8354                    throw new IllegalArgumentException("Bad thumbnail size: got "
8355                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8356                            + mThumbnailWidth + "x" + mThumbnailHeight);
8357                }
8358                if (intent.getSelector() != null) {
8359                    intent.setSelector(null);
8360                }
8361                if (intent.getSourceBounds() != null) {
8362                    intent.setSourceBounds(null);
8363                }
8364                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8365                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8366                        // The caller has added this as an auto-remove task...  that makes no
8367                        // sense, so turn off auto-remove.
8368                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8369                    }
8370                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8371                    // Must be a new task.
8372                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8373                }
8374                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8375                    mLastAddedTaskActivity = null;
8376                }
8377                ActivityInfo ainfo = mLastAddedTaskActivity;
8378                if (ainfo == null) {
8379                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8380                            comp, 0, UserHandle.getUserId(callingUid));
8381                    if (ainfo.applicationInfo.uid != callingUid) {
8382                        throw new SecurityException(
8383                                "Can't add task for another application: target uid="
8384                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8385                    }
8386                }
8387
8388                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8389                        intent, description);
8390
8391                int trimIdx = trimRecentsForTask(task, false);
8392                if (trimIdx >= 0) {
8393                    // If this would have caused a trim, then we'll abort because that
8394                    // means it would be added at the end of the list but then just removed.
8395                    return -1;
8396                }
8397
8398                final int N = mRecentTasks.size();
8399                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8400                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8401                    tr.removedFromRecents(mTaskPersister);
8402                }
8403
8404                task.inRecents = true;
8405                mRecentTasks.add(task);
8406                r.task.stack.addTask(task, false, false);
8407
8408                task.setLastThumbnail(thumbnail);
8409                task.freeLastThumbnail();
8410
8411                return task.taskId;
8412            }
8413        } finally {
8414            Binder.restoreCallingIdentity(callingIdent);
8415        }
8416    }
8417
8418    @Override
8419    public Point getAppTaskThumbnailSize() {
8420        synchronized (this) {
8421            return new Point(mThumbnailWidth,  mThumbnailHeight);
8422        }
8423    }
8424
8425    @Override
8426    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8427        synchronized (this) {
8428            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8429            if (r != null) {
8430                r.setTaskDescription(td);
8431                r.task.updateTaskDescription();
8432            }
8433        }
8434    }
8435
8436    @Override
8437    public Bitmap getTaskDescriptionIcon(String filename) {
8438        if (!FileUtils.isValidExtFilename(filename)
8439                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8440            throw new IllegalArgumentException("Bad filename: " + filename);
8441        }
8442        return mTaskPersister.getTaskDescriptionIcon(filename);
8443    }
8444
8445    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8446        mRecentTasks.remove(tr);
8447        tr.removedFromRecents(mTaskPersister);
8448        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8449        Intent baseIntent = new Intent(
8450                tr.intent != null ? tr.intent : tr.affinityIntent);
8451        ComponentName component = baseIntent.getComponent();
8452        if (component == null) {
8453            Slog.w(TAG, "Now component for base intent of task: " + tr);
8454            return;
8455        }
8456
8457        // Find any running services associated with this app.
8458        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8459
8460        if (killProcesses) {
8461            // Find any running processes associated with this app.
8462            final String pkg = component.getPackageName();
8463            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8464            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8465            for (int i=0; i<pmap.size(); i++) {
8466                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8467                for (int j=0; j<uids.size(); j++) {
8468                    ProcessRecord proc = uids.valueAt(j);
8469                    if (proc.userId != tr.userId) {
8470                        continue;
8471                    }
8472                    if (!proc.pkgList.containsKey(pkg)) {
8473                        continue;
8474                    }
8475                    procs.add(proc);
8476                }
8477            }
8478
8479            // Kill the running processes.
8480            for (int i=0; i<procs.size(); i++) {
8481                ProcessRecord pr = procs.get(i);
8482                if (pr == mHomeProcess) {
8483                    // Don't kill the home process along with tasks from the same package.
8484                    continue;
8485                }
8486                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8487                    pr.kill("remove task", true);
8488                } else {
8489                    pr.waitingToKill = "remove task";
8490                }
8491            }
8492        }
8493    }
8494
8495    /**
8496     * Removes the task with the specified task id.
8497     *
8498     * @param taskId Identifier of the task to be removed.
8499     * @param flags Additional operational flags.  May be 0 or
8500     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8501     * @return Returns true if the given task was found and removed.
8502     */
8503    private boolean removeTaskByIdLocked(int taskId, int flags) {
8504        TaskRecord tr = recentTaskForIdLocked(taskId);
8505        if (tr != null) {
8506            tr.removeTaskActivitiesLocked();
8507            cleanUpRemovedTaskLocked(tr, flags);
8508            if (tr.isPersistable) {
8509                notifyTaskPersisterLocked(null, true);
8510            }
8511            return true;
8512        }
8513        return false;
8514    }
8515
8516    @Override
8517    public boolean removeTask(int taskId, int flags) {
8518        synchronized (this) {
8519            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8520                    "removeTask()");
8521            long ident = Binder.clearCallingIdentity();
8522            try {
8523                return removeTaskByIdLocked(taskId, flags);
8524            } finally {
8525                Binder.restoreCallingIdentity(ident);
8526            }
8527        }
8528    }
8529
8530    /**
8531     * TODO: Add mController hook
8532     */
8533    @Override
8534    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8535        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8536                "moveTaskToFront()");
8537
8538        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8539        synchronized(this) {
8540            moveTaskToFrontLocked(taskId, flags, options);
8541        }
8542    }
8543
8544    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8545        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8546                Binder.getCallingUid(), -1, -1, "Task to front")) {
8547            ActivityOptions.abort(options);
8548            return;
8549        }
8550        final long origId = Binder.clearCallingIdentity();
8551        try {
8552            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8553            if (task == null) {
8554                return;
8555            }
8556            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8557                mStackSupervisor.showLockTaskToast();
8558                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8559                return;
8560            }
8561            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8562            if (prev != null && prev.isRecentsActivity()) {
8563                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8564            }
8565            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8566        } finally {
8567            Binder.restoreCallingIdentity(origId);
8568        }
8569        ActivityOptions.abort(options);
8570    }
8571
8572    @Override
8573    public void moveTaskToBack(int taskId) {
8574        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8575                "moveTaskToBack()");
8576
8577        synchronized(this) {
8578            TaskRecord tr = recentTaskForIdLocked(taskId);
8579            if (tr != null) {
8580                if (tr == mStackSupervisor.mLockTaskModeTask) {
8581                    mStackSupervisor.showLockTaskToast();
8582                    return;
8583                }
8584                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8585                ActivityStack stack = tr.stack;
8586                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8587                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8588                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8589                        return;
8590                    }
8591                }
8592                final long origId = Binder.clearCallingIdentity();
8593                try {
8594                    stack.moveTaskToBackLocked(taskId, null);
8595                } finally {
8596                    Binder.restoreCallingIdentity(origId);
8597                }
8598            }
8599        }
8600    }
8601
8602    /**
8603     * Moves an activity, and all of the other activities within the same task, to the bottom
8604     * of the history stack.  The activity's order within the task is unchanged.
8605     *
8606     * @param token A reference to the activity we wish to move
8607     * @param nonRoot If false then this only works if the activity is the root
8608     *                of a task; if true it will work for any activity in a task.
8609     * @return Returns true if the move completed, false if not.
8610     */
8611    @Override
8612    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8613        enforceNotIsolatedCaller("moveActivityTaskToBack");
8614        synchronized(this) {
8615            final long origId = Binder.clearCallingIdentity();
8616            try {
8617                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8618                if (taskId >= 0) {
8619                    if ((mStackSupervisor.mLockTaskModeTask != null)
8620                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8621                        mStackSupervisor.showLockTaskToast();
8622                        return false;
8623                    }
8624                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8625                }
8626            } finally {
8627                Binder.restoreCallingIdentity(origId);
8628            }
8629        }
8630        return false;
8631    }
8632
8633    @Override
8634    public void moveTaskBackwards(int task) {
8635        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8636                "moveTaskBackwards()");
8637
8638        synchronized(this) {
8639            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8640                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8641                return;
8642            }
8643            final long origId = Binder.clearCallingIdentity();
8644            moveTaskBackwardsLocked(task);
8645            Binder.restoreCallingIdentity(origId);
8646        }
8647    }
8648
8649    private final void moveTaskBackwardsLocked(int task) {
8650        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8651    }
8652
8653    @Override
8654    public IBinder getHomeActivityToken() throws RemoteException {
8655        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8656                "getHomeActivityToken()");
8657        synchronized (this) {
8658            return mStackSupervisor.getHomeActivityToken();
8659        }
8660    }
8661
8662    @Override
8663    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8664            IActivityContainerCallback callback) throws RemoteException {
8665        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8666                "createActivityContainer()");
8667        synchronized (this) {
8668            if (parentActivityToken == null) {
8669                throw new IllegalArgumentException("parent token must not be null");
8670            }
8671            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8672            if (r == null) {
8673                return null;
8674            }
8675            if (callback == null) {
8676                throw new IllegalArgumentException("callback must not be null");
8677            }
8678            return mStackSupervisor.createActivityContainer(r, callback);
8679        }
8680    }
8681
8682    @Override
8683    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8684        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8685                "deleteActivityContainer()");
8686        synchronized (this) {
8687            mStackSupervisor.deleteActivityContainer(container);
8688        }
8689    }
8690
8691    @Override
8692    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8693            throws RemoteException {
8694        synchronized (this) {
8695            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8696            if (stack != null) {
8697                return stack.mActivityContainer;
8698            }
8699            return null;
8700        }
8701    }
8702
8703    @Override
8704    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8705        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8706                "moveTaskToStack()");
8707        if (stackId == HOME_STACK_ID) {
8708            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8709                    new RuntimeException("here").fillInStackTrace());
8710        }
8711        synchronized (this) {
8712            long ident = Binder.clearCallingIdentity();
8713            try {
8714                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8715                        + stackId + " toTop=" + toTop);
8716                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8717            } finally {
8718                Binder.restoreCallingIdentity(ident);
8719            }
8720        }
8721    }
8722
8723    @Override
8724    public void resizeStack(int stackBoxId, Rect bounds) {
8725        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8726                "resizeStackBox()");
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            mWindowManager.resizeStack(stackBoxId, bounds);
8730        } finally {
8731            Binder.restoreCallingIdentity(ident);
8732        }
8733    }
8734
8735    @Override
8736    public List<StackInfo> getAllStackInfos() {
8737        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8738                "getAllStackInfos()");
8739        long ident = Binder.clearCallingIdentity();
8740        try {
8741            synchronized (this) {
8742                return mStackSupervisor.getAllStackInfosLocked();
8743            }
8744        } finally {
8745            Binder.restoreCallingIdentity(ident);
8746        }
8747    }
8748
8749    @Override
8750    public StackInfo getStackInfo(int stackId) {
8751        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8752                "getStackInfo()");
8753        long ident = Binder.clearCallingIdentity();
8754        try {
8755            synchronized (this) {
8756                return mStackSupervisor.getStackInfoLocked(stackId);
8757            }
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761    }
8762
8763    @Override
8764    public boolean isInHomeStack(int taskId) {
8765        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8766                "getStackInfo()");
8767        long ident = Binder.clearCallingIdentity();
8768        try {
8769            synchronized (this) {
8770                TaskRecord tr = recentTaskForIdLocked(taskId);
8771                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8772            }
8773        } finally {
8774            Binder.restoreCallingIdentity(ident);
8775        }
8776    }
8777
8778    @Override
8779    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8780        synchronized(this) {
8781            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8782        }
8783    }
8784
8785    private boolean isLockTaskAuthorized(String pkg) {
8786        final DevicePolicyManager dpm = (DevicePolicyManager)
8787                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8788        try {
8789            int uid = mContext.getPackageManager().getPackageUid(pkg,
8790                    Binder.getCallingUserHandle().getIdentifier());
8791            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8792        } catch (NameNotFoundException e) {
8793            return false;
8794        }
8795    }
8796
8797    void startLockTaskMode(TaskRecord task) {
8798        final String pkg;
8799        synchronized (this) {
8800            pkg = task.intent.getComponent().getPackageName();
8801        }
8802        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8803        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8804            final TaskRecord taskRecord = task;
8805            mHandler.post(new Runnable() {
8806                @Override
8807                public void run() {
8808                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8809                }
8810            });
8811            return;
8812        }
8813        long ident = Binder.clearCallingIdentity();
8814        try {
8815            synchronized (this) {
8816                // Since we lost lock on task, make sure it is still there.
8817                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8818                if (task != null) {
8819                    if (!isSystemInitiated
8820                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8821                        throw new IllegalArgumentException("Invalid task, not in foreground");
8822                    }
8823                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8824                }
8825            }
8826        } finally {
8827            Binder.restoreCallingIdentity(ident);
8828        }
8829    }
8830
8831    @Override
8832    public void startLockTaskMode(int taskId) {
8833        final TaskRecord task;
8834        long ident = Binder.clearCallingIdentity();
8835        try {
8836            synchronized (this) {
8837                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8838            }
8839        } finally {
8840            Binder.restoreCallingIdentity(ident);
8841        }
8842        if (task != null) {
8843            startLockTaskMode(task);
8844        }
8845    }
8846
8847    @Override
8848    public void startLockTaskMode(IBinder token) {
8849        final TaskRecord task;
8850        long ident = Binder.clearCallingIdentity();
8851        try {
8852            synchronized (this) {
8853                final ActivityRecord r = ActivityRecord.forToken(token);
8854                if (r == null) {
8855                    return;
8856                }
8857                task = r.task;
8858            }
8859        } finally {
8860            Binder.restoreCallingIdentity(ident);
8861        }
8862        if (task != null) {
8863            startLockTaskMode(task);
8864        }
8865    }
8866
8867    @Override
8868    public void startLockTaskModeOnCurrent() throws RemoteException {
8869        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8870                "startLockTaskModeOnCurrent");
8871        ActivityRecord r = null;
8872        synchronized (this) {
8873            r = mStackSupervisor.topRunningActivityLocked();
8874        }
8875        startLockTaskMode(r.task);
8876    }
8877
8878    @Override
8879    public void stopLockTaskMode() {
8880        // Verify that the user matches the package of the intent for the TaskRecord
8881        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8882        // and stopLockTaskMode.
8883        final int callingUid = Binder.getCallingUid();
8884        if (callingUid != Process.SYSTEM_UID) {
8885            try {
8886                String pkg =
8887                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8888                int uid = mContext.getPackageManager().getPackageUid(pkg,
8889                        Binder.getCallingUserHandle().getIdentifier());
8890                if (uid != callingUid) {
8891                    throw new SecurityException("Invalid uid, expected " + uid);
8892                }
8893            } catch (NameNotFoundException e) {
8894                Log.d(TAG, "stopLockTaskMode " + e);
8895                return;
8896            }
8897        }
8898        long ident = Binder.clearCallingIdentity();
8899        try {
8900            Log.d(TAG, "stopLockTaskMode");
8901            // Stop lock task
8902            synchronized (this) {
8903                mStackSupervisor.setLockTaskModeLocked(null, false);
8904            }
8905        } finally {
8906            Binder.restoreCallingIdentity(ident);
8907        }
8908    }
8909
8910    @Override
8911    public void stopLockTaskModeOnCurrent() throws RemoteException {
8912        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8913                "stopLockTaskModeOnCurrent");
8914        long ident = Binder.clearCallingIdentity();
8915        try {
8916            stopLockTaskMode();
8917        } finally {
8918            Binder.restoreCallingIdentity(ident);
8919        }
8920    }
8921
8922    @Override
8923    public boolean isInLockTaskMode() {
8924        synchronized (this) {
8925            return mStackSupervisor.isInLockTaskMode();
8926        }
8927    }
8928
8929    // =========================================================
8930    // CONTENT PROVIDERS
8931    // =========================================================
8932
8933    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8934        List<ProviderInfo> providers = null;
8935        try {
8936            providers = AppGlobals.getPackageManager().
8937                queryContentProviders(app.processName, app.uid,
8938                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8939        } catch (RemoteException ex) {
8940        }
8941        if (DEBUG_MU)
8942            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8943        int userId = app.userId;
8944        if (providers != null) {
8945            int N = providers.size();
8946            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8947            for (int i=0; i<N; i++) {
8948                ProviderInfo cpi =
8949                    (ProviderInfo)providers.get(i);
8950                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8951                        cpi.name, cpi.flags);
8952                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8953                    // This is a singleton provider, but a user besides the
8954                    // default user is asking to initialize a process it runs
8955                    // in...  well, no, it doesn't actually run in this process,
8956                    // it runs in the process of the default user.  Get rid of it.
8957                    providers.remove(i);
8958                    N--;
8959                    i--;
8960                    continue;
8961                }
8962
8963                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8964                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8965                if (cpr == null) {
8966                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8967                    mProviderMap.putProviderByClass(comp, cpr);
8968                }
8969                if (DEBUG_MU)
8970                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8971                app.pubProviders.put(cpi.name, cpr);
8972                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8973                    // Don't add this if it is a platform component that is marked
8974                    // to run in multiple processes, because this is actually
8975                    // part of the framework so doesn't make sense to track as a
8976                    // separate apk in the process.
8977                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8978                            mProcessStats);
8979                }
8980                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8981            }
8982        }
8983        return providers;
8984    }
8985
8986    /**
8987     * Check if {@link ProcessRecord} has a possible chance at accessing the
8988     * given {@link ProviderInfo}. Final permission checking is always done
8989     * in {@link ContentProvider}.
8990     */
8991    private final String checkContentProviderPermissionLocked(
8992            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8993        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8994        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8995        boolean checkedGrants = false;
8996        if (checkUser) {
8997            // Looking for cross-user grants before enforcing the typical cross-users permissions
8998            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8999            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9000                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9001                    return null;
9002                }
9003                checkedGrants = true;
9004            }
9005            userId = handleIncomingUser(callingPid, callingUid, userId,
9006                    false, ALLOW_NON_FULL,
9007                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9008            if (userId != tmpTargetUserId) {
9009                // When we actually went to determine the final targer user ID, this ended
9010                // up different than our initial check for the authority.  This is because
9011                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9012                // SELF.  So we need to re-check the grants again.
9013                checkedGrants = false;
9014            }
9015        }
9016        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9017                cpi.applicationInfo.uid, cpi.exported)
9018                == PackageManager.PERMISSION_GRANTED) {
9019            return null;
9020        }
9021        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9022                cpi.applicationInfo.uid, cpi.exported)
9023                == PackageManager.PERMISSION_GRANTED) {
9024            return null;
9025        }
9026
9027        PathPermission[] pps = cpi.pathPermissions;
9028        if (pps != null) {
9029            int i = pps.length;
9030            while (i > 0) {
9031                i--;
9032                PathPermission pp = pps[i];
9033                String pprperm = pp.getReadPermission();
9034                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9035                        cpi.applicationInfo.uid, cpi.exported)
9036                        == PackageManager.PERMISSION_GRANTED) {
9037                    return null;
9038                }
9039                String ppwperm = pp.getWritePermission();
9040                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9041                        cpi.applicationInfo.uid, cpi.exported)
9042                        == PackageManager.PERMISSION_GRANTED) {
9043                    return null;
9044                }
9045            }
9046        }
9047        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9048            return null;
9049        }
9050
9051        String msg;
9052        if (!cpi.exported) {
9053            msg = "Permission Denial: opening provider " + cpi.name
9054                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9055                    + ", uid=" + callingUid + ") that is not exported from uid "
9056                    + cpi.applicationInfo.uid;
9057        } else {
9058            msg = "Permission Denial: opening provider " + cpi.name
9059                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9060                    + ", uid=" + callingUid + ") requires "
9061                    + cpi.readPermission + " or " + cpi.writePermission;
9062        }
9063        Slog.w(TAG, msg);
9064        return msg;
9065    }
9066
9067    /**
9068     * Returns if the ContentProvider has granted a uri to callingUid
9069     */
9070    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9071        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9072        if (perms != null) {
9073            for (int i=perms.size()-1; i>=0; i--) {
9074                GrantUri grantUri = perms.keyAt(i);
9075                if (grantUri.sourceUserId == userId || !checkUser) {
9076                    if (matchesProvider(grantUri.uri, cpi)) {
9077                        return true;
9078                    }
9079                }
9080            }
9081        }
9082        return false;
9083    }
9084
9085    /**
9086     * Returns true if the uri authority is one of the authorities specified in the provider.
9087     */
9088    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9089        String uriAuth = uri.getAuthority();
9090        String cpiAuth = cpi.authority;
9091        if (cpiAuth.indexOf(';') == -1) {
9092            return cpiAuth.equals(uriAuth);
9093        }
9094        String[] cpiAuths = cpiAuth.split(";");
9095        int length = cpiAuths.length;
9096        for (int i = 0; i < length; i++) {
9097            if (cpiAuths[i].equals(uriAuth)) return true;
9098        }
9099        return false;
9100    }
9101
9102    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9103            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9104        if (r != null) {
9105            for (int i=0; i<r.conProviders.size(); i++) {
9106                ContentProviderConnection conn = r.conProviders.get(i);
9107                if (conn.provider == cpr) {
9108                    if (DEBUG_PROVIDER) Slog.v(TAG,
9109                            "Adding provider requested by "
9110                            + r.processName + " from process "
9111                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9112                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9113                    if (stable) {
9114                        conn.stableCount++;
9115                        conn.numStableIncs++;
9116                    } else {
9117                        conn.unstableCount++;
9118                        conn.numUnstableIncs++;
9119                    }
9120                    return conn;
9121                }
9122            }
9123            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9124            if (stable) {
9125                conn.stableCount = 1;
9126                conn.numStableIncs = 1;
9127            } else {
9128                conn.unstableCount = 1;
9129                conn.numUnstableIncs = 1;
9130            }
9131            cpr.connections.add(conn);
9132            r.conProviders.add(conn);
9133            return conn;
9134        }
9135        cpr.addExternalProcessHandleLocked(externalProcessToken);
9136        return null;
9137    }
9138
9139    boolean decProviderCountLocked(ContentProviderConnection conn,
9140            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9141        if (conn != null) {
9142            cpr = conn.provider;
9143            if (DEBUG_PROVIDER) Slog.v(TAG,
9144                    "Removing provider requested by "
9145                    + conn.client.processName + " from process "
9146                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9147                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9148            if (stable) {
9149                conn.stableCount--;
9150            } else {
9151                conn.unstableCount--;
9152            }
9153            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9154                cpr.connections.remove(conn);
9155                conn.client.conProviders.remove(conn);
9156                return true;
9157            }
9158            return false;
9159        }
9160        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9161        return false;
9162    }
9163
9164    private void checkTime(long startTime, String where) {
9165        long now = SystemClock.elapsedRealtime();
9166        if ((now-startTime) > 1000) {
9167            // If we are taking more than a second, log about it.
9168            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9169        }
9170    }
9171
9172    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9173            String name, IBinder token, boolean stable, int userId) {
9174        ContentProviderRecord cpr;
9175        ContentProviderConnection conn = null;
9176        ProviderInfo cpi = null;
9177
9178        synchronized(this) {
9179            long startTime = SystemClock.elapsedRealtime();
9180
9181            ProcessRecord r = null;
9182            if (caller != null) {
9183                r = getRecordForAppLocked(caller);
9184                if (r == null) {
9185                    throw new SecurityException(
9186                            "Unable to find app for caller " + caller
9187                          + " (pid=" + Binder.getCallingPid()
9188                          + ") when getting content provider " + name);
9189                }
9190            }
9191
9192            boolean checkCrossUser = true;
9193
9194            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9195
9196            // First check if this content provider has been published...
9197            cpr = mProviderMap.getProviderByName(name, userId);
9198            // If that didn't work, check if it exists for user 0 and then
9199            // verify that it's a singleton provider before using it.
9200            if (cpr == null && userId != UserHandle.USER_OWNER) {
9201                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9202                if (cpr != null) {
9203                    cpi = cpr.info;
9204                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9205                            cpi.name, cpi.flags)
9206                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9207                        userId = UserHandle.USER_OWNER;
9208                        checkCrossUser = false;
9209                    } else {
9210                        cpr = null;
9211                        cpi = null;
9212                    }
9213                }
9214            }
9215
9216            boolean providerRunning = cpr != null;
9217            if (providerRunning) {
9218                cpi = cpr.info;
9219                String msg;
9220                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9221                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9222                        != null) {
9223                    throw new SecurityException(msg);
9224                }
9225                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9226
9227                if (r != null && cpr.canRunHere(r)) {
9228                    // This provider has been published or is in the process
9229                    // of being published...  but it is also allowed to run
9230                    // in the caller's process, so don't make a connection
9231                    // and just let the caller instantiate its own instance.
9232                    ContentProviderHolder holder = cpr.newHolder(null);
9233                    // don't give caller the provider object, it needs
9234                    // to make its own.
9235                    holder.provider = null;
9236                    return holder;
9237                }
9238
9239                final long origId = Binder.clearCallingIdentity();
9240
9241                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9242
9243                // In this case the provider instance already exists, so we can
9244                // return it right away.
9245                conn = incProviderCountLocked(r, cpr, token, stable);
9246                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9247                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9248                        // If this is a perceptible app accessing the provider,
9249                        // make sure to count it as being accessed and thus
9250                        // back up on the LRU list.  This is good because
9251                        // content providers are often expensive to start.
9252                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9253                        updateLruProcessLocked(cpr.proc, false, null);
9254                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9255                    }
9256                }
9257
9258                if (cpr.proc != null) {
9259                    if (false) {
9260                        if (cpr.name.flattenToShortString().equals(
9261                                "com.android.providers.calendar/.CalendarProvider2")) {
9262                            Slog.v(TAG, "****************** KILLING "
9263                                + cpr.name.flattenToShortString());
9264                            Process.killProcess(cpr.proc.pid);
9265                        }
9266                    }
9267                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9268                    boolean success = updateOomAdjLocked(cpr.proc);
9269                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9270                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9271                    // NOTE: there is still a race here where a signal could be
9272                    // pending on the process even though we managed to update its
9273                    // adj level.  Not sure what to do about this, but at least
9274                    // the race is now smaller.
9275                    if (!success) {
9276                        // Uh oh...  it looks like the provider's process
9277                        // has been killed on us.  We need to wait for a new
9278                        // process to be started, and make sure its death
9279                        // doesn't kill our process.
9280                        Slog.i(TAG,
9281                                "Existing provider " + cpr.name.flattenToShortString()
9282                                + " is crashing; detaching " + r);
9283                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9284                        checkTime(startTime, "getContentProviderImpl: before appDied");
9285                        appDiedLocked(cpr.proc);
9286                        checkTime(startTime, "getContentProviderImpl: after appDied");
9287                        if (!lastRef) {
9288                            // This wasn't the last ref our process had on
9289                            // the provider...  we have now been killed, bail.
9290                            return null;
9291                        }
9292                        providerRunning = false;
9293                        conn = null;
9294                    }
9295                }
9296
9297                Binder.restoreCallingIdentity(origId);
9298            }
9299
9300            boolean singleton;
9301            if (!providerRunning) {
9302                try {
9303                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9304                    cpi = AppGlobals.getPackageManager().
9305                        resolveContentProvider(name,
9306                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9307                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9308                } catch (RemoteException ex) {
9309                }
9310                if (cpi == null) {
9311                    return null;
9312                }
9313                // If the provider is a singleton AND
9314                // (it's a call within the same user || the provider is a
9315                // privileged app)
9316                // Then allow connecting to the singleton provider
9317                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9318                        cpi.name, cpi.flags)
9319                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9320                if (singleton) {
9321                    userId = UserHandle.USER_OWNER;
9322                }
9323                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9324                checkTime(startTime, "getContentProviderImpl: got app info for user");
9325
9326                String msg;
9327                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9328                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9329                        != null) {
9330                    throw new SecurityException(msg);
9331                }
9332                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9333
9334                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9335                        && !cpi.processName.equals("system")) {
9336                    // If this content provider does not run in the system
9337                    // process, and the system is not yet ready to run other
9338                    // processes, then fail fast instead of hanging.
9339                    throw new IllegalArgumentException(
9340                            "Attempt to launch content provider before system ready");
9341                }
9342
9343                // Make sure that the user who owns this provider is started.  If not,
9344                // we don't want to allow it to run.
9345                if (mStartedUsers.get(userId) == null) {
9346                    Slog.w(TAG, "Unable to launch app "
9347                            + cpi.applicationInfo.packageName + "/"
9348                            + cpi.applicationInfo.uid + " for provider "
9349                            + name + ": user " + userId + " is stopped");
9350                    return null;
9351                }
9352
9353                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9354                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9355                cpr = mProviderMap.getProviderByClass(comp, userId);
9356                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9357                final boolean firstClass = cpr == null;
9358                if (firstClass) {
9359                    try {
9360                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9361                        ApplicationInfo ai =
9362                            AppGlobals.getPackageManager().
9363                                getApplicationInfo(
9364                                        cpi.applicationInfo.packageName,
9365                                        STOCK_PM_FLAGS, userId);
9366                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9367                        if (ai == null) {
9368                            Slog.w(TAG, "No package info for content provider "
9369                                    + cpi.name);
9370                            return null;
9371                        }
9372                        ai = getAppInfoForUser(ai, userId);
9373                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9374                    } catch (RemoteException ex) {
9375                        // pm is in same process, this will never happen.
9376                    }
9377                }
9378
9379                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9380
9381                if (r != null && cpr.canRunHere(r)) {
9382                    // If this is a multiprocess provider, then just return its
9383                    // info and allow the caller to instantiate it.  Only do
9384                    // this if the provider is the same user as the caller's
9385                    // process, or can run as root (so can be in any process).
9386                    return cpr.newHolder(null);
9387                }
9388
9389                if (DEBUG_PROVIDER) {
9390                    RuntimeException e = new RuntimeException("here");
9391                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9392                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9393                }
9394
9395                // This is single process, and our app is now connecting to it.
9396                // See if we are already in the process of launching this
9397                // provider.
9398                final int N = mLaunchingProviders.size();
9399                int i;
9400                for (i=0; i<N; i++) {
9401                    if (mLaunchingProviders.get(i) == cpr) {
9402                        break;
9403                    }
9404                }
9405
9406                // If the provider is not already being launched, then get it
9407                // started.
9408                if (i >= N) {
9409                    final long origId = Binder.clearCallingIdentity();
9410
9411                    try {
9412                        // Content provider is now in use, its package can't be stopped.
9413                        try {
9414                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9415                            AppGlobals.getPackageManager().setPackageStoppedState(
9416                                    cpr.appInfo.packageName, false, userId);
9417                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9418                        } catch (RemoteException e) {
9419                        } catch (IllegalArgumentException e) {
9420                            Slog.w(TAG, "Failed trying to unstop package "
9421                                    + cpr.appInfo.packageName + ": " + e);
9422                        }
9423
9424                        // Use existing process if already started
9425                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9426                        ProcessRecord proc = getProcessRecordLocked(
9427                                cpi.processName, cpr.appInfo.uid, false);
9428                        if (proc != null && proc.thread != null) {
9429                            if (DEBUG_PROVIDER) {
9430                                Slog.d(TAG, "Installing in existing process " + proc);
9431                            }
9432                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9433                            proc.pubProviders.put(cpi.name, cpr);
9434                            try {
9435                                proc.thread.scheduleInstallProvider(cpi);
9436                            } catch (RemoteException e) {
9437                            }
9438                        } else {
9439                            checkTime(startTime, "getContentProviderImpl: before start process");
9440                            proc = startProcessLocked(cpi.processName,
9441                                    cpr.appInfo, false, 0, "content provider",
9442                                    new ComponentName(cpi.applicationInfo.packageName,
9443                                            cpi.name), false, false, false);
9444                            checkTime(startTime, "getContentProviderImpl: after start process");
9445                            if (proc == null) {
9446                                Slog.w(TAG, "Unable to launch app "
9447                                        + cpi.applicationInfo.packageName + "/"
9448                                        + cpi.applicationInfo.uid + " for provider "
9449                                        + name + ": process is bad");
9450                                return null;
9451                            }
9452                        }
9453                        cpr.launchingApp = proc;
9454                        mLaunchingProviders.add(cpr);
9455                    } finally {
9456                        Binder.restoreCallingIdentity(origId);
9457                    }
9458                }
9459
9460                checkTime(startTime, "getContentProviderImpl: updating data structures");
9461
9462                // Make sure the provider is published (the same provider class
9463                // may be published under multiple names).
9464                if (firstClass) {
9465                    mProviderMap.putProviderByClass(comp, cpr);
9466                }
9467
9468                mProviderMap.putProviderByName(name, cpr);
9469                conn = incProviderCountLocked(r, cpr, token, stable);
9470                if (conn != null) {
9471                    conn.waiting = true;
9472                }
9473            }
9474            checkTime(startTime, "getContentProviderImpl: done!");
9475        }
9476
9477        // Wait for the provider to be published...
9478        synchronized (cpr) {
9479            while (cpr.provider == null) {
9480                if (cpr.launchingApp == null) {
9481                    Slog.w(TAG, "Unable to launch app "
9482                            + cpi.applicationInfo.packageName + "/"
9483                            + cpi.applicationInfo.uid + " for provider "
9484                            + name + ": launching app became null");
9485                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9486                            UserHandle.getUserId(cpi.applicationInfo.uid),
9487                            cpi.applicationInfo.packageName,
9488                            cpi.applicationInfo.uid, name);
9489                    return null;
9490                }
9491                try {
9492                    if (DEBUG_MU) {
9493                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9494                                + cpr.launchingApp);
9495                    }
9496                    if (conn != null) {
9497                        conn.waiting = true;
9498                    }
9499                    cpr.wait();
9500                } catch (InterruptedException ex) {
9501                } finally {
9502                    if (conn != null) {
9503                        conn.waiting = false;
9504                    }
9505                }
9506            }
9507        }
9508        return cpr != null ? cpr.newHolder(conn) : null;
9509    }
9510
9511    @Override
9512    public final ContentProviderHolder getContentProvider(
9513            IApplicationThread caller, String name, int userId, boolean stable) {
9514        enforceNotIsolatedCaller("getContentProvider");
9515        if (caller == null) {
9516            String msg = "null IApplicationThread when getting content provider "
9517                    + name;
9518            Slog.w(TAG, msg);
9519            throw new SecurityException(msg);
9520        }
9521        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9522        // with cross-user grant.
9523        return getContentProviderImpl(caller, name, null, stable, userId);
9524    }
9525
9526    public ContentProviderHolder getContentProviderExternal(
9527            String name, int userId, IBinder token) {
9528        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9529            "Do not have permission in call getContentProviderExternal()");
9530        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9531                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9532        return getContentProviderExternalUnchecked(name, token, userId);
9533    }
9534
9535    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9536            IBinder token, int userId) {
9537        return getContentProviderImpl(null, name, token, true, userId);
9538    }
9539
9540    /**
9541     * Drop a content provider from a ProcessRecord's bookkeeping
9542     */
9543    public void removeContentProvider(IBinder connection, boolean stable) {
9544        enforceNotIsolatedCaller("removeContentProvider");
9545        long ident = Binder.clearCallingIdentity();
9546        try {
9547            synchronized (this) {
9548                ContentProviderConnection conn;
9549                try {
9550                    conn = (ContentProviderConnection)connection;
9551                } catch (ClassCastException e) {
9552                    String msg ="removeContentProvider: " + connection
9553                            + " not a ContentProviderConnection";
9554                    Slog.w(TAG, msg);
9555                    throw new IllegalArgumentException(msg);
9556                }
9557                if (conn == null) {
9558                    throw new NullPointerException("connection is null");
9559                }
9560                if (decProviderCountLocked(conn, null, null, stable)) {
9561                    updateOomAdjLocked();
9562                }
9563            }
9564        } finally {
9565            Binder.restoreCallingIdentity(ident);
9566        }
9567    }
9568
9569    public void removeContentProviderExternal(String name, IBinder token) {
9570        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9571            "Do not have permission in call removeContentProviderExternal()");
9572        int userId = UserHandle.getCallingUserId();
9573        long ident = Binder.clearCallingIdentity();
9574        try {
9575            removeContentProviderExternalUnchecked(name, token, userId);
9576        } finally {
9577            Binder.restoreCallingIdentity(ident);
9578        }
9579    }
9580
9581    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9582        synchronized (this) {
9583            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9584            if(cpr == null) {
9585                //remove from mProvidersByClass
9586                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9587                return;
9588            }
9589
9590            //update content provider record entry info
9591            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9592            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9593            if (localCpr.hasExternalProcessHandles()) {
9594                if (localCpr.removeExternalProcessHandleLocked(token)) {
9595                    updateOomAdjLocked();
9596                } else {
9597                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9598                            + " with no external reference for token: "
9599                            + token + ".");
9600                }
9601            } else {
9602                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9603                        + " with no external references.");
9604            }
9605        }
9606    }
9607
9608    public final void publishContentProviders(IApplicationThread caller,
9609            List<ContentProviderHolder> providers) {
9610        if (providers == null) {
9611            return;
9612        }
9613
9614        enforceNotIsolatedCaller("publishContentProviders");
9615        synchronized (this) {
9616            final ProcessRecord r = getRecordForAppLocked(caller);
9617            if (DEBUG_MU)
9618                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9619            if (r == null) {
9620                throw new SecurityException(
9621                        "Unable to find app for caller " + caller
9622                      + " (pid=" + Binder.getCallingPid()
9623                      + ") when publishing content providers");
9624            }
9625
9626            final long origId = Binder.clearCallingIdentity();
9627
9628            final int N = providers.size();
9629            for (int i=0; i<N; i++) {
9630                ContentProviderHolder src = providers.get(i);
9631                if (src == null || src.info == null || src.provider == null) {
9632                    continue;
9633                }
9634                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9635                if (DEBUG_MU)
9636                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9637                if (dst != null) {
9638                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9639                    mProviderMap.putProviderByClass(comp, dst);
9640                    String names[] = dst.info.authority.split(";");
9641                    for (int j = 0; j < names.length; j++) {
9642                        mProviderMap.putProviderByName(names[j], dst);
9643                    }
9644
9645                    int NL = mLaunchingProviders.size();
9646                    int j;
9647                    for (j=0; j<NL; j++) {
9648                        if (mLaunchingProviders.get(j) == dst) {
9649                            mLaunchingProviders.remove(j);
9650                            j--;
9651                            NL--;
9652                        }
9653                    }
9654                    synchronized (dst) {
9655                        dst.provider = src.provider;
9656                        dst.proc = r;
9657                        dst.notifyAll();
9658                    }
9659                    updateOomAdjLocked(r);
9660                }
9661            }
9662
9663            Binder.restoreCallingIdentity(origId);
9664        }
9665    }
9666
9667    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9668        ContentProviderConnection conn;
9669        try {
9670            conn = (ContentProviderConnection)connection;
9671        } catch (ClassCastException e) {
9672            String msg ="refContentProvider: " + connection
9673                    + " not a ContentProviderConnection";
9674            Slog.w(TAG, msg);
9675            throw new IllegalArgumentException(msg);
9676        }
9677        if (conn == null) {
9678            throw new NullPointerException("connection is null");
9679        }
9680
9681        synchronized (this) {
9682            if (stable > 0) {
9683                conn.numStableIncs += stable;
9684            }
9685            stable = conn.stableCount + stable;
9686            if (stable < 0) {
9687                throw new IllegalStateException("stableCount < 0: " + stable);
9688            }
9689
9690            if (unstable > 0) {
9691                conn.numUnstableIncs += unstable;
9692            }
9693            unstable = conn.unstableCount + unstable;
9694            if (unstable < 0) {
9695                throw new IllegalStateException("unstableCount < 0: " + unstable);
9696            }
9697
9698            if ((stable+unstable) <= 0) {
9699                throw new IllegalStateException("ref counts can't go to zero here: stable="
9700                        + stable + " unstable=" + unstable);
9701            }
9702            conn.stableCount = stable;
9703            conn.unstableCount = unstable;
9704            return !conn.dead;
9705        }
9706    }
9707
9708    public void unstableProviderDied(IBinder connection) {
9709        ContentProviderConnection conn;
9710        try {
9711            conn = (ContentProviderConnection)connection;
9712        } catch (ClassCastException e) {
9713            String msg ="refContentProvider: " + connection
9714                    + " not a ContentProviderConnection";
9715            Slog.w(TAG, msg);
9716            throw new IllegalArgumentException(msg);
9717        }
9718        if (conn == null) {
9719            throw new NullPointerException("connection is null");
9720        }
9721
9722        // Safely retrieve the content provider associated with the connection.
9723        IContentProvider provider;
9724        synchronized (this) {
9725            provider = conn.provider.provider;
9726        }
9727
9728        if (provider == null) {
9729            // Um, yeah, we're way ahead of you.
9730            return;
9731        }
9732
9733        // Make sure the caller is being honest with us.
9734        if (provider.asBinder().pingBinder()) {
9735            // Er, no, still looks good to us.
9736            synchronized (this) {
9737                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9738                        + " says " + conn + " died, but we don't agree");
9739                return;
9740            }
9741        }
9742
9743        // Well look at that!  It's dead!
9744        synchronized (this) {
9745            if (conn.provider.provider != provider) {
9746                // But something changed...  good enough.
9747                return;
9748            }
9749
9750            ProcessRecord proc = conn.provider.proc;
9751            if (proc == null || proc.thread == null) {
9752                // Seems like the process is already cleaned up.
9753                return;
9754            }
9755
9756            // As far as we're concerned, this is just like receiving a
9757            // death notification...  just a bit prematurely.
9758            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9759                    + ") early provider death");
9760            final long ident = Binder.clearCallingIdentity();
9761            try {
9762                appDiedLocked(proc);
9763            } finally {
9764                Binder.restoreCallingIdentity(ident);
9765            }
9766        }
9767    }
9768
9769    @Override
9770    public void appNotRespondingViaProvider(IBinder connection) {
9771        enforceCallingPermission(
9772                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9773
9774        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9775        if (conn == null) {
9776            Slog.w(TAG, "ContentProviderConnection is null");
9777            return;
9778        }
9779
9780        final ProcessRecord host = conn.provider.proc;
9781        if (host == null) {
9782            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9783            return;
9784        }
9785
9786        final long token = Binder.clearCallingIdentity();
9787        try {
9788            appNotResponding(host, null, null, false, "ContentProvider not responding");
9789        } finally {
9790            Binder.restoreCallingIdentity(token);
9791        }
9792    }
9793
9794    public final void installSystemProviders() {
9795        List<ProviderInfo> providers;
9796        synchronized (this) {
9797            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9798            providers = generateApplicationProvidersLocked(app);
9799            if (providers != null) {
9800                for (int i=providers.size()-1; i>=0; i--) {
9801                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9802                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9803                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9804                                + ": not system .apk");
9805                        providers.remove(i);
9806                    }
9807                }
9808            }
9809        }
9810        if (providers != null) {
9811            mSystemThread.installSystemProviders(providers);
9812        }
9813
9814        mCoreSettingsObserver = new CoreSettingsObserver(this);
9815
9816        //mUsageStatsService.monitorPackages();
9817    }
9818
9819    /**
9820     * Allows apps to retrieve the MIME type of a URI.
9821     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9822     * users, then it does not need permission to access the ContentProvider.
9823     * Either, it needs cross-user uri grants.
9824     *
9825     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9826     *
9827     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9828     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9829     */
9830    public String getProviderMimeType(Uri uri, int userId) {
9831        enforceNotIsolatedCaller("getProviderMimeType");
9832        final String name = uri.getAuthority();
9833        int callingUid = Binder.getCallingUid();
9834        int callingPid = Binder.getCallingPid();
9835        long ident = 0;
9836        boolean clearedIdentity = false;
9837        userId = unsafeConvertIncomingUser(userId);
9838        if (canClearIdentity(callingPid, callingUid, userId)) {
9839            clearedIdentity = true;
9840            ident = Binder.clearCallingIdentity();
9841        }
9842        ContentProviderHolder holder = null;
9843        try {
9844            holder = getContentProviderExternalUnchecked(name, null, userId);
9845            if (holder != null) {
9846                return holder.provider.getType(uri);
9847            }
9848        } catch (RemoteException e) {
9849            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9850            return null;
9851        } finally {
9852            // We need to clear the identity to call removeContentProviderExternalUnchecked
9853            if (!clearedIdentity) {
9854                ident = Binder.clearCallingIdentity();
9855            }
9856            try {
9857                if (holder != null) {
9858                    removeContentProviderExternalUnchecked(name, null, userId);
9859                }
9860            } finally {
9861                Binder.restoreCallingIdentity(ident);
9862            }
9863        }
9864
9865        return null;
9866    }
9867
9868    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9869        if (UserHandle.getUserId(callingUid) == userId) {
9870            return true;
9871        }
9872        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9873                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9874                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9875                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9876                return true;
9877        }
9878        return false;
9879    }
9880
9881    // =========================================================
9882    // GLOBAL MANAGEMENT
9883    // =========================================================
9884
9885    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9886            boolean isolated, int isolatedUid) {
9887        String proc = customProcess != null ? customProcess : info.processName;
9888        BatteryStatsImpl.Uid.Proc ps = null;
9889        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9890        int uid = info.uid;
9891        if (isolated) {
9892            if (isolatedUid == 0) {
9893                int userId = UserHandle.getUserId(uid);
9894                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9895                while (true) {
9896                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9897                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9898                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9899                    }
9900                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9901                    mNextIsolatedProcessUid++;
9902                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9903                        // No process for this uid, use it.
9904                        break;
9905                    }
9906                    stepsLeft--;
9907                    if (stepsLeft <= 0) {
9908                        return null;
9909                    }
9910                }
9911            } else {
9912                // Special case for startIsolatedProcess (internal only), where
9913                // the uid of the isolated process is specified by the caller.
9914                uid = isolatedUid;
9915            }
9916        }
9917        return new ProcessRecord(stats, info, proc, uid);
9918    }
9919
9920    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9921            String abiOverride) {
9922        ProcessRecord app;
9923        if (!isolated) {
9924            app = getProcessRecordLocked(info.processName, info.uid, true);
9925        } else {
9926            app = null;
9927        }
9928
9929        if (app == null) {
9930            app = newProcessRecordLocked(info, null, isolated, 0);
9931            mProcessNames.put(info.processName, app.uid, app);
9932            if (isolated) {
9933                mIsolatedProcesses.put(app.uid, app);
9934            }
9935            updateLruProcessLocked(app, false, null);
9936            updateOomAdjLocked();
9937        }
9938
9939        // This package really, really can not be stopped.
9940        try {
9941            AppGlobals.getPackageManager().setPackageStoppedState(
9942                    info.packageName, false, UserHandle.getUserId(app.uid));
9943        } catch (RemoteException e) {
9944        } catch (IllegalArgumentException e) {
9945            Slog.w(TAG, "Failed trying to unstop package "
9946                    + info.packageName + ": " + e);
9947        }
9948
9949        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9950                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9951            app.persistent = true;
9952            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9953        }
9954        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9955            mPersistentStartingProcesses.add(app);
9956            startProcessLocked(app, "added application", app.processName, abiOverride,
9957                    null /* entryPoint */, null /* entryPointArgs */);
9958        }
9959
9960        return app;
9961    }
9962
9963    public void unhandledBack() {
9964        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9965                "unhandledBack()");
9966
9967        synchronized(this) {
9968            final long origId = Binder.clearCallingIdentity();
9969            try {
9970                getFocusedStack().unhandledBackLocked();
9971            } finally {
9972                Binder.restoreCallingIdentity(origId);
9973            }
9974        }
9975    }
9976
9977    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9978        enforceNotIsolatedCaller("openContentUri");
9979        final int userId = UserHandle.getCallingUserId();
9980        String name = uri.getAuthority();
9981        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9982        ParcelFileDescriptor pfd = null;
9983        if (cph != null) {
9984            // We record the binder invoker's uid in thread-local storage before
9985            // going to the content provider to open the file.  Later, in the code
9986            // that handles all permissions checks, we look for this uid and use
9987            // that rather than the Activity Manager's own uid.  The effect is that
9988            // we do the check against the caller's permissions even though it looks
9989            // to the content provider like the Activity Manager itself is making
9990            // the request.
9991            sCallerIdentity.set(new Identity(
9992                    Binder.getCallingPid(), Binder.getCallingUid()));
9993            try {
9994                pfd = cph.provider.openFile(null, uri, "r", null);
9995            } catch (FileNotFoundException e) {
9996                // do nothing; pfd will be returned null
9997            } finally {
9998                // Ensure that whatever happens, we clean up the identity state
9999                sCallerIdentity.remove();
10000            }
10001
10002            // We've got the fd now, so we're done with the provider.
10003            removeContentProviderExternalUnchecked(name, null, userId);
10004        } else {
10005            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10006        }
10007        return pfd;
10008    }
10009
10010    // Actually is sleeping or shutting down or whatever else in the future
10011    // is an inactive state.
10012    public boolean isSleepingOrShuttingDown() {
10013        return isSleeping() || mShuttingDown;
10014    }
10015
10016    public boolean isSleeping() {
10017        return mSleeping;
10018    }
10019
10020    void goingToSleep() {
10021        synchronized(this) {
10022            mWentToSleep = true;
10023            goToSleepIfNeededLocked();
10024        }
10025    }
10026
10027    void finishRunningVoiceLocked() {
10028        if (mRunningVoice) {
10029            mRunningVoice = false;
10030            goToSleepIfNeededLocked();
10031        }
10032    }
10033
10034    void goToSleepIfNeededLocked() {
10035        if (mWentToSleep && !mRunningVoice) {
10036            if (!mSleeping) {
10037                mSleeping = true;
10038                mStackSupervisor.goingToSleepLocked();
10039
10040                // Initialize the wake times of all processes.
10041                checkExcessivePowerUsageLocked(false);
10042                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10043                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10044                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10045            }
10046        }
10047    }
10048
10049    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10050        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10051            // Never persist the home stack.
10052            return;
10053        }
10054        mTaskPersister.wakeup(task, flush);
10055    }
10056
10057    @Override
10058    public boolean shutdown(int timeout) {
10059        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10060                != PackageManager.PERMISSION_GRANTED) {
10061            throw new SecurityException("Requires permission "
10062                    + android.Manifest.permission.SHUTDOWN);
10063        }
10064
10065        boolean timedout = false;
10066
10067        synchronized(this) {
10068            mShuttingDown = true;
10069            updateEventDispatchingLocked();
10070            timedout = mStackSupervisor.shutdownLocked(timeout);
10071        }
10072
10073        mAppOpsService.shutdown();
10074        if (mUsageStatsService != null) {
10075            mUsageStatsService.prepareShutdown();
10076        }
10077        mBatteryStatsService.shutdown();
10078        synchronized (this) {
10079            mProcessStats.shutdownLocked();
10080        }
10081        notifyTaskPersisterLocked(null, true);
10082
10083        return timedout;
10084    }
10085
10086    public final void activitySlept(IBinder token) {
10087        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10088
10089        final long origId = Binder.clearCallingIdentity();
10090
10091        synchronized (this) {
10092            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10093            if (r != null) {
10094                mStackSupervisor.activitySleptLocked(r);
10095            }
10096        }
10097
10098        Binder.restoreCallingIdentity(origId);
10099    }
10100
10101    void logLockScreen(String msg) {
10102        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10103                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10104                mWentToSleep + " mSleeping=" + mSleeping);
10105    }
10106
10107    private void comeOutOfSleepIfNeededLocked() {
10108        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10109            if (mSleeping) {
10110                mSleeping = false;
10111                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10112            }
10113        }
10114    }
10115
10116    void wakingUp() {
10117        synchronized(this) {
10118            mWentToSleep = false;
10119            comeOutOfSleepIfNeededLocked();
10120        }
10121    }
10122
10123    void startRunningVoiceLocked() {
10124        if (!mRunningVoice) {
10125            mRunningVoice = true;
10126            comeOutOfSleepIfNeededLocked();
10127        }
10128    }
10129
10130    private void updateEventDispatchingLocked() {
10131        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10132    }
10133
10134    public void setLockScreenShown(boolean shown) {
10135        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10136                != PackageManager.PERMISSION_GRANTED) {
10137            throw new SecurityException("Requires permission "
10138                    + android.Manifest.permission.DEVICE_POWER);
10139        }
10140
10141        synchronized(this) {
10142            long ident = Binder.clearCallingIdentity();
10143            try {
10144                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10145                mLockScreenShown = shown;
10146                comeOutOfSleepIfNeededLocked();
10147            } finally {
10148                Binder.restoreCallingIdentity(ident);
10149            }
10150        }
10151    }
10152
10153    @Override
10154    public void stopAppSwitches() {
10155        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10156                != PackageManager.PERMISSION_GRANTED) {
10157            throw new SecurityException("Requires permission "
10158                    + android.Manifest.permission.STOP_APP_SWITCHES);
10159        }
10160
10161        synchronized(this) {
10162            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10163                    + APP_SWITCH_DELAY_TIME;
10164            mDidAppSwitch = false;
10165            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10166            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10167            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10168        }
10169    }
10170
10171    public void resumeAppSwitches() {
10172        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10173                != PackageManager.PERMISSION_GRANTED) {
10174            throw new SecurityException("Requires permission "
10175                    + android.Manifest.permission.STOP_APP_SWITCHES);
10176        }
10177
10178        synchronized(this) {
10179            // Note that we don't execute any pending app switches... we will
10180            // let those wait until either the timeout, or the next start
10181            // activity request.
10182            mAppSwitchesAllowedTime = 0;
10183        }
10184    }
10185
10186    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10187            int callingPid, int callingUid, String name) {
10188        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10189            return true;
10190        }
10191
10192        int perm = checkComponentPermission(
10193                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10194                sourceUid, -1, true);
10195        if (perm == PackageManager.PERMISSION_GRANTED) {
10196            return true;
10197        }
10198
10199        // If the actual IPC caller is different from the logical source, then
10200        // also see if they are allowed to control app switches.
10201        if (callingUid != -1 && callingUid != sourceUid) {
10202            perm = checkComponentPermission(
10203                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10204                    callingUid, -1, true);
10205            if (perm == PackageManager.PERMISSION_GRANTED) {
10206                return true;
10207            }
10208        }
10209
10210        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10211        return false;
10212    }
10213
10214    public void setDebugApp(String packageName, boolean waitForDebugger,
10215            boolean persistent) {
10216        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10217                "setDebugApp()");
10218
10219        long ident = Binder.clearCallingIdentity();
10220        try {
10221            // Note that this is not really thread safe if there are multiple
10222            // callers into it at the same time, but that's not a situation we
10223            // care about.
10224            if (persistent) {
10225                final ContentResolver resolver = mContext.getContentResolver();
10226                Settings.Global.putString(
10227                    resolver, Settings.Global.DEBUG_APP,
10228                    packageName);
10229                Settings.Global.putInt(
10230                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10231                    waitForDebugger ? 1 : 0);
10232            }
10233
10234            synchronized (this) {
10235                if (!persistent) {
10236                    mOrigDebugApp = mDebugApp;
10237                    mOrigWaitForDebugger = mWaitForDebugger;
10238                }
10239                mDebugApp = packageName;
10240                mWaitForDebugger = waitForDebugger;
10241                mDebugTransient = !persistent;
10242                if (packageName != null) {
10243                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10244                            false, UserHandle.USER_ALL, "set debug app");
10245                }
10246            }
10247        } finally {
10248            Binder.restoreCallingIdentity(ident);
10249        }
10250    }
10251
10252    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10253        synchronized (this) {
10254            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10255            if (!isDebuggable) {
10256                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10257                    throw new SecurityException("Process not debuggable: " + app.packageName);
10258                }
10259            }
10260
10261            mOpenGlTraceApp = processName;
10262        }
10263    }
10264
10265    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10266        synchronized (this) {
10267            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10268            if (!isDebuggable) {
10269                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10270                    throw new SecurityException("Process not debuggable: " + app.packageName);
10271                }
10272            }
10273            mProfileApp = processName;
10274            mProfileFile = profilerInfo.profileFile;
10275            if (mProfileFd != null) {
10276                try {
10277                    mProfileFd.close();
10278                } catch (IOException e) {
10279                }
10280                mProfileFd = null;
10281            }
10282            mProfileFd = profilerInfo.profileFd;
10283            mSamplingInterval = profilerInfo.samplingInterval;
10284            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10285            mProfileType = 0;
10286        }
10287    }
10288
10289    @Override
10290    public void setAlwaysFinish(boolean enabled) {
10291        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10292                "setAlwaysFinish()");
10293
10294        Settings.Global.putInt(
10295                mContext.getContentResolver(),
10296                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10297
10298        synchronized (this) {
10299            mAlwaysFinishActivities = enabled;
10300        }
10301    }
10302
10303    @Override
10304    public void setActivityController(IActivityController controller) {
10305        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10306                "setActivityController()");
10307        synchronized (this) {
10308            mController = controller;
10309            Watchdog.getInstance().setActivityController(controller);
10310        }
10311    }
10312
10313    @Override
10314    public void setUserIsMonkey(boolean userIsMonkey) {
10315        synchronized (this) {
10316            synchronized (mPidsSelfLocked) {
10317                final int callingPid = Binder.getCallingPid();
10318                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10319                if (precessRecord == null) {
10320                    throw new SecurityException("Unknown process: " + callingPid);
10321                }
10322                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10323                    throw new SecurityException("Only an instrumentation process "
10324                            + "with a UiAutomation can call setUserIsMonkey");
10325                }
10326            }
10327            mUserIsMonkey = userIsMonkey;
10328        }
10329    }
10330
10331    @Override
10332    public boolean isUserAMonkey() {
10333        synchronized (this) {
10334            // If there is a controller also implies the user is a monkey.
10335            return (mUserIsMonkey || mController != null);
10336        }
10337    }
10338
10339    public void requestBugReport() {
10340        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10341        SystemProperties.set("ctl.start", "bugreport");
10342    }
10343
10344    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10345        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10346    }
10347
10348    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10349        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10350            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10351        }
10352        return KEY_DISPATCHING_TIMEOUT;
10353    }
10354
10355    @Override
10356    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10357        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10358                != PackageManager.PERMISSION_GRANTED) {
10359            throw new SecurityException("Requires permission "
10360                    + android.Manifest.permission.FILTER_EVENTS);
10361        }
10362        ProcessRecord proc;
10363        long timeout;
10364        synchronized (this) {
10365            synchronized (mPidsSelfLocked) {
10366                proc = mPidsSelfLocked.get(pid);
10367            }
10368            timeout = getInputDispatchingTimeoutLocked(proc);
10369        }
10370
10371        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10372            return -1;
10373        }
10374
10375        return timeout;
10376    }
10377
10378    /**
10379     * Handle input dispatching timeouts.
10380     * Returns whether input dispatching should be aborted or not.
10381     */
10382    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10383            final ActivityRecord activity, final ActivityRecord parent,
10384            final boolean aboveSystem, String reason) {
10385        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10386                != PackageManager.PERMISSION_GRANTED) {
10387            throw new SecurityException("Requires permission "
10388                    + android.Manifest.permission.FILTER_EVENTS);
10389        }
10390
10391        final String annotation;
10392        if (reason == null) {
10393            annotation = "Input dispatching timed out";
10394        } else {
10395            annotation = "Input dispatching timed out (" + reason + ")";
10396        }
10397
10398        if (proc != null) {
10399            synchronized (this) {
10400                if (proc.debugging) {
10401                    return false;
10402                }
10403
10404                if (mDidDexOpt) {
10405                    // Give more time since we were dexopting.
10406                    mDidDexOpt = false;
10407                    return false;
10408                }
10409
10410                if (proc.instrumentationClass != null) {
10411                    Bundle info = new Bundle();
10412                    info.putString("shortMsg", "keyDispatchingTimedOut");
10413                    info.putString("longMsg", annotation);
10414                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10415                    return true;
10416                }
10417            }
10418            mHandler.post(new Runnable() {
10419                @Override
10420                public void run() {
10421                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10422                }
10423            });
10424        }
10425
10426        return true;
10427    }
10428
10429    public Bundle getAssistContextExtras(int requestType) {
10430        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10431                "getAssistContextExtras()");
10432        PendingAssistExtras pae;
10433        Bundle extras = new Bundle();
10434        synchronized (this) {
10435            ActivityRecord activity = getFocusedStack().mResumedActivity;
10436            if (activity == null) {
10437                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10438                return null;
10439            }
10440            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10441            if (activity.app == null || activity.app.thread == null) {
10442                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10443                return extras;
10444            }
10445            if (activity.app.pid == Binder.getCallingPid()) {
10446                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10447                return extras;
10448            }
10449            pae = new PendingAssistExtras(activity);
10450            try {
10451                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10452                        requestType);
10453                mPendingAssistExtras.add(pae);
10454                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10455            } catch (RemoteException e) {
10456                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10457                return extras;
10458            }
10459        }
10460        synchronized (pae) {
10461            while (!pae.haveResult) {
10462                try {
10463                    pae.wait();
10464                } catch (InterruptedException e) {
10465                }
10466            }
10467            if (pae.result != null) {
10468                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10469            }
10470        }
10471        synchronized (this) {
10472            mPendingAssistExtras.remove(pae);
10473            mHandler.removeCallbacks(pae);
10474        }
10475        return extras;
10476    }
10477
10478    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10479        PendingAssistExtras pae = (PendingAssistExtras)token;
10480        synchronized (pae) {
10481            pae.result = extras;
10482            pae.haveResult = true;
10483            pae.notifyAll();
10484        }
10485    }
10486
10487    public void registerProcessObserver(IProcessObserver observer) {
10488        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10489                "registerProcessObserver()");
10490        synchronized (this) {
10491            mProcessObservers.register(observer);
10492        }
10493    }
10494
10495    @Override
10496    public void unregisterProcessObserver(IProcessObserver observer) {
10497        synchronized (this) {
10498            mProcessObservers.unregister(observer);
10499        }
10500    }
10501
10502    @Override
10503    public boolean convertFromTranslucent(IBinder token) {
10504        final long origId = Binder.clearCallingIdentity();
10505        try {
10506            synchronized (this) {
10507                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10508                if (r == null) {
10509                    return false;
10510                }
10511                final boolean translucentChanged = r.changeWindowTranslucency(true);
10512                if (translucentChanged) {
10513                    r.task.stack.releaseBackgroundResources();
10514                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10515                }
10516                mWindowManager.setAppFullscreen(token, true);
10517                return translucentChanged;
10518            }
10519        } finally {
10520            Binder.restoreCallingIdentity(origId);
10521        }
10522    }
10523
10524    @Override
10525    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10526        final long origId = Binder.clearCallingIdentity();
10527        try {
10528            synchronized (this) {
10529                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10530                if (r == null) {
10531                    return false;
10532                }
10533                int index = r.task.mActivities.lastIndexOf(r);
10534                if (index > 0) {
10535                    ActivityRecord under = r.task.mActivities.get(index - 1);
10536                    under.returningOptions = options;
10537                }
10538                final boolean translucentChanged = r.changeWindowTranslucency(false);
10539                if (translucentChanged) {
10540                    r.task.stack.convertToTranslucent(r);
10541                }
10542                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10543                mWindowManager.setAppFullscreen(token, false);
10544                return translucentChanged;
10545            }
10546        } finally {
10547            Binder.restoreCallingIdentity(origId);
10548        }
10549    }
10550
10551    @Override
10552    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10553        final long origId = Binder.clearCallingIdentity();
10554        try {
10555            synchronized (this) {
10556                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10557                if (r != null) {
10558                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10559                }
10560            }
10561            return false;
10562        } finally {
10563            Binder.restoreCallingIdentity(origId);
10564        }
10565    }
10566
10567    @Override
10568    public boolean isBackgroundVisibleBehind(IBinder token) {
10569        final long origId = Binder.clearCallingIdentity();
10570        try {
10571            synchronized (this) {
10572                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10573                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10574                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10575                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10576                return visible;
10577            }
10578        } finally {
10579            Binder.restoreCallingIdentity(origId);
10580        }
10581    }
10582
10583    @Override
10584    public ActivityOptions getActivityOptions(IBinder token) {
10585        final long origId = Binder.clearCallingIdentity();
10586        try {
10587            synchronized (this) {
10588                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10589                if (r != null) {
10590                    final ActivityOptions activityOptions = r.pendingOptions;
10591                    r.pendingOptions = null;
10592                    return activityOptions;
10593                }
10594                return null;
10595            }
10596        } finally {
10597            Binder.restoreCallingIdentity(origId);
10598        }
10599    }
10600
10601    @Override
10602    public void setImmersive(IBinder token, boolean immersive) {
10603        synchronized(this) {
10604            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10605            if (r == null) {
10606                throw new IllegalArgumentException();
10607            }
10608            r.immersive = immersive;
10609
10610            // update associated state if we're frontmost
10611            if (r == mFocusedActivity) {
10612                if (DEBUG_IMMERSIVE) {
10613                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10614                }
10615                applyUpdateLockStateLocked(r);
10616            }
10617        }
10618    }
10619
10620    @Override
10621    public boolean isImmersive(IBinder token) {
10622        synchronized (this) {
10623            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10624            if (r == null) {
10625                throw new IllegalArgumentException();
10626            }
10627            return r.immersive;
10628        }
10629    }
10630
10631    public boolean isTopActivityImmersive() {
10632        enforceNotIsolatedCaller("startActivity");
10633        synchronized (this) {
10634            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10635            return (r != null) ? r.immersive : false;
10636        }
10637    }
10638
10639    @Override
10640    public boolean isTopOfTask(IBinder token) {
10641        synchronized (this) {
10642            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10643            if (r == null) {
10644                throw new IllegalArgumentException();
10645            }
10646            return r.task.getTopActivity() == r;
10647        }
10648    }
10649
10650    public final void enterSafeMode() {
10651        synchronized(this) {
10652            // It only makes sense to do this before the system is ready
10653            // and started launching other packages.
10654            if (!mSystemReady) {
10655                try {
10656                    AppGlobals.getPackageManager().enterSafeMode();
10657                } catch (RemoteException e) {
10658                }
10659            }
10660
10661            mSafeMode = true;
10662        }
10663    }
10664
10665    public final void showSafeModeOverlay() {
10666        View v = LayoutInflater.from(mContext).inflate(
10667                com.android.internal.R.layout.safe_mode, null);
10668        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10669        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10670        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10671        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10672        lp.gravity = Gravity.BOTTOM | Gravity.START;
10673        lp.format = v.getBackground().getOpacity();
10674        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10675                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10676        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10677        ((WindowManager)mContext.getSystemService(
10678                Context.WINDOW_SERVICE)).addView(v, lp);
10679    }
10680
10681    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10682        if (!(sender instanceof PendingIntentRecord)) {
10683            return;
10684        }
10685        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10686        synchronized (stats) {
10687            if (mBatteryStatsService.isOnBattery()) {
10688                mBatteryStatsService.enforceCallingPermission();
10689                PendingIntentRecord rec = (PendingIntentRecord)sender;
10690                int MY_UID = Binder.getCallingUid();
10691                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10692                BatteryStatsImpl.Uid.Pkg pkg =
10693                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10694                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10695                pkg.incWakeupsLocked();
10696            }
10697        }
10698    }
10699
10700    public boolean killPids(int[] pids, String pReason, boolean secure) {
10701        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10702            throw new SecurityException("killPids only available to the system");
10703        }
10704        String reason = (pReason == null) ? "Unknown" : pReason;
10705        // XXX Note: don't acquire main activity lock here, because the window
10706        // manager calls in with its locks held.
10707
10708        boolean killed = false;
10709        synchronized (mPidsSelfLocked) {
10710            int[] types = new int[pids.length];
10711            int worstType = 0;
10712            for (int i=0; i<pids.length; i++) {
10713                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10714                if (proc != null) {
10715                    int type = proc.setAdj;
10716                    types[i] = type;
10717                    if (type > worstType) {
10718                        worstType = type;
10719                    }
10720                }
10721            }
10722
10723            // If the worst oom_adj is somewhere in the cached proc LRU range,
10724            // then constrain it so we will kill all cached procs.
10725            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10726                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10727                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10728            }
10729
10730            // If this is not a secure call, don't let it kill processes that
10731            // are important.
10732            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10733                worstType = ProcessList.SERVICE_ADJ;
10734            }
10735
10736            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10737            for (int i=0; i<pids.length; i++) {
10738                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10739                if (proc == null) {
10740                    continue;
10741                }
10742                int adj = proc.setAdj;
10743                if (adj >= worstType && !proc.killedByAm) {
10744                    proc.kill(reason, true);
10745                    killed = true;
10746                }
10747            }
10748        }
10749        return killed;
10750    }
10751
10752    @Override
10753    public void killUid(int uid, String reason) {
10754        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10755            throw new SecurityException("killUid only available to the system");
10756        }
10757        synchronized (this) {
10758            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10759                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10760                    reason != null ? reason : "kill uid");
10761        }
10762    }
10763
10764    @Override
10765    public boolean killProcessesBelowForeground(String reason) {
10766        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10767            throw new SecurityException("killProcessesBelowForeground() only available to system");
10768        }
10769
10770        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10771    }
10772
10773    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10774        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10775            throw new SecurityException("killProcessesBelowAdj() only available to system");
10776        }
10777
10778        boolean killed = false;
10779        synchronized (mPidsSelfLocked) {
10780            final int size = mPidsSelfLocked.size();
10781            for (int i = 0; i < size; i++) {
10782                final int pid = mPidsSelfLocked.keyAt(i);
10783                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10784                if (proc == null) continue;
10785
10786                final int adj = proc.setAdj;
10787                if (adj > belowAdj && !proc.killedByAm) {
10788                    proc.kill(reason, true);
10789                    killed = true;
10790                }
10791            }
10792        }
10793        return killed;
10794    }
10795
10796    @Override
10797    public void hang(final IBinder who, boolean allowRestart) {
10798        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10799                != PackageManager.PERMISSION_GRANTED) {
10800            throw new SecurityException("Requires permission "
10801                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10802        }
10803
10804        final IBinder.DeathRecipient death = new DeathRecipient() {
10805            @Override
10806            public void binderDied() {
10807                synchronized (this) {
10808                    notifyAll();
10809                }
10810            }
10811        };
10812
10813        try {
10814            who.linkToDeath(death, 0);
10815        } catch (RemoteException e) {
10816            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10817            return;
10818        }
10819
10820        synchronized (this) {
10821            Watchdog.getInstance().setAllowRestart(allowRestart);
10822            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10823            synchronized (death) {
10824                while (who.isBinderAlive()) {
10825                    try {
10826                        death.wait();
10827                    } catch (InterruptedException e) {
10828                    }
10829                }
10830            }
10831            Watchdog.getInstance().setAllowRestart(true);
10832        }
10833    }
10834
10835    @Override
10836    public void restart() {
10837        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10838                != PackageManager.PERMISSION_GRANTED) {
10839            throw new SecurityException("Requires permission "
10840                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10841        }
10842
10843        Log.i(TAG, "Sending shutdown broadcast...");
10844
10845        BroadcastReceiver br = new BroadcastReceiver() {
10846            @Override public void onReceive(Context context, Intent intent) {
10847                // Now the broadcast is done, finish up the low-level shutdown.
10848                Log.i(TAG, "Shutting down activity manager...");
10849                shutdown(10000);
10850                Log.i(TAG, "Shutdown complete, restarting!");
10851                Process.killProcess(Process.myPid());
10852                System.exit(10);
10853            }
10854        };
10855
10856        // First send the high-level shut down broadcast.
10857        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10858        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10859        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10860        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10861        mContext.sendOrderedBroadcastAsUser(intent,
10862                UserHandle.ALL, null, br, mHandler, 0, null, null);
10863        */
10864        br.onReceive(mContext, intent);
10865    }
10866
10867    private long getLowRamTimeSinceIdle(long now) {
10868        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10869    }
10870
10871    @Override
10872    public void performIdleMaintenance() {
10873        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10874                != PackageManager.PERMISSION_GRANTED) {
10875            throw new SecurityException("Requires permission "
10876                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10877        }
10878
10879        synchronized (this) {
10880            final long now = SystemClock.uptimeMillis();
10881            final long timeSinceLastIdle = now - mLastIdleTime;
10882            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10883            mLastIdleTime = now;
10884            mLowRamTimeSinceLastIdle = 0;
10885            if (mLowRamStartTime != 0) {
10886                mLowRamStartTime = now;
10887            }
10888
10889            StringBuilder sb = new StringBuilder(128);
10890            sb.append("Idle maintenance over ");
10891            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10892            sb.append(" low RAM for ");
10893            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10894            Slog.i(TAG, sb.toString());
10895
10896            // If at least 1/3 of our time since the last idle period has been spent
10897            // with RAM low, then we want to kill processes.
10898            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10899
10900            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10901                ProcessRecord proc = mLruProcesses.get(i);
10902                if (proc.notCachedSinceIdle) {
10903                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10904                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10905                        if (doKilling && proc.initialIdlePss != 0
10906                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10907                            proc.kill("idle maint (pss " + proc.lastPss
10908                                    + " from " + proc.initialIdlePss + ")", true);
10909                        }
10910                    }
10911                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10912                    proc.notCachedSinceIdle = true;
10913                    proc.initialIdlePss = 0;
10914                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10915                            isSleeping(), now);
10916                }
10917            }
10918
10919            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10920            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10921        }
10922    }
10923
10924    private void retrieveSettings() {
10925        final ContentResolver resolver = mContext.getContentResolver();
10926        String debugApp = Settings.Global.getString(
10927            resolver, Settings.Global.DEBUG_APP);
10928        boolean waitForDebugger = Settings.Global.getInt(
10929            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10930        boolean alwaysFinishActivities = Settings.Global.getInt(
10931            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10932        boolean forceRtl = Settings.Global.getInt(
10933                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10934        // Transfer any global setting for forcing RTL layout, into a System Property
10935        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10936
10937        Configuration configuration = new Configuration();
10938        Settings.System.getConfiguration(resolver, configuration);
10939        if (forceRtl) {
10940            // This will take care of setting the correct layout direction flags
10941            configuration.setLayoutDirection(configuration.locale);
10942        }
10943
10944        synchronized (this) {
10945            mDebugApp = mOrigDebugApp = debugApp;
10946            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10947            mAlwaysFinishActivities = alwaysFinishActivities;
10948            // This happens before any activities are started, so we can
10949            // change mConfiguration in-place.
10950            updateConfigurationLocked(configuration, null, false, true);
10951            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10952        }
10953    }
10954
10955    /** Loads resources after the current configuration has been set. */
10956    private void loadResourcesOnSystemReady() {
10957        final Resources res = mContext.getResources();
10958        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10959        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10960        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10961    }
10962
10963    public boolean testIsSystemReady() {
10964        // no need to synchronize(this) just to read & return the value
10965        return mSystemReady;
10966    }
10967
10968    private static File getCalledPreBootReceiversFile() {
10969        File dataDir = Environment.getDataDirectory();
10970        File systemDir = new File(dataDir, "system");
10971        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10972        return fname;
10973    }
10974
10975    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10976        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10977        File file = getCalledPreBootReceiversFile();
10978        FileInputStream fis = null;
10979        try {
10980            fis = new FileInputStream(file);
10981            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10982            int fvers = dis.readInt();
10983            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10984                String vers = dis.readUTF();
10985                String codename = dis.readUTF();
10986                String build = dis.readUTF();
10987                if (android.os.Build.VERSION.RELEASE.equals(vers)
10988                        && android.os.Build.VERSION.CODENAME.equals(codename)
10989                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10990                    int num = dis.readInt();
10991                    while (num > 0) {
10992                        num--;
10993                        String pkg = dis.readUTF();
10994                        String cls = dis.readUTF();
10995                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10996                    }
10997                }
10998            }
10999        } catch (FileNotFoundException e) {
11000        } catch (IOException e) {
11001            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11002        } finally {
11003            if (fis != null) {
11004                try {
11005                    fis.close();
11006                } catch (IOException e) {
11007                }
11008            }
11009        }
11010        return lastDoneReceivers;
11011    }
11012
11013    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11014        File file = getCalledPreBootReceiversFile();
11015        FileOutputStream fos = null;
11016        DataOutputStream dos = null;
11017        try {
11018            fos = new FileOutputStream(file);
11019            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11020            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11021            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11022            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11023            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11024            dos.writeInt(list.size());
11025            for (int i=0; i<list.size(); i++) {
11026                dos.writeUTF(list.get(i).getPackageName());
11027                dos.writeUTF(list.get(i).getClassName());
11028            }
11029        } catch (IOException e) {
11030            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11031            file.delete();
11032        } finally {
11033            FileUtils.sync(fos);
11034            if (dos != null) {
11035                try {
11036                    dos.close();
11037                } catch (IOException e) {
11038                    // TODO Auto-generated catch block
11039                    e.printStackTrace();
11040                }
11041            }
11042        }
11043    }
11044
11045    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11046            ArrayList<ComponentName> doneReceivers, int userId) {
11047        boolean waitingUpdate = false;
11048        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11049        List<ResolveInfo> ris = null;
11050        try {
11051            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11052                    intent, null, 0, userId);
11053        } catch (RemoteException e) {
11054        }
11055        if (ris != null) {
11056            for (int i=ris.size()-1; i>=0; i--) {
11057                if ((ris.get(i).activityInfo.applicationInfo.flags
11058                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11059                    ris.remove(i);
11060                }
11061            }
11062            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11063
11064            // For User 0, load the version number. When delivering to a new user, deliver
11065            // to all receivers.
11066            if (userId == UserHandle.USER_OWNER) {
11067                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11068                for (int i=0; i<ris.size(); i++) {
11069                    ActivityInfo ai = ris.get(i).activityInfo;
11070                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11071                    if (lastDoneReceivers.contains(comp)) {
11072                        // We already did the pre boot receiver for this app with the current
11073                        // platform version, so don't do it again...
11074                        ris.remove(i);
11075                        i--;
11076                        // ...however, do keep it as one that has been done, so we don't
11077                        // forget about it when rewriting the file of last done receivers.
11078                        doneReceivers.add(comp);
11079                    }
11080                }
11081            }
11082
11083            // If primary user, send broadcast to all available users, else just to userId
11084            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11085                    : new int[] { userId };
11086            for (int i = 0; i < ris.size(); i++) {
11087                ActivityInfo ai = ris.get(i).activityInfo;
11088                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11089                doneReceivers.add(comp);
11090                intent.setComponent(comp);
11091                for (int j=0; j<users.length; j++) {
11092                    IIntentReceiver finisher = null;
11093                    // On last receiver and user, set up a completion callback
11094                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11095                        finisher = new IIntentReceiver.Stub() {
11096                            public void performReceive(Intent intent, int resultCode,
11097                                    String data, Bundle extras, boolean ordered,
11098                                    boolean sticky, int sendingUser) {
11099                                // The raw IIntentReceiver interface is called
11100                                // with the AM lock held, so redispatch to
11101                                // execute our code without the lock.
11102                                mHandler.post(onFinishCallback);
11103                            }
11104                        };
11105                    }
11106                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11107                            + " for user " + users[j]);
11108                    broadcastIntentLocked(null, null, intent, null, finisher,
11109                            0, null, null, null, AppOpsManager.OP_NONE,
11110                            true, false, MY_PID, Process.SYSTEM_UID,
11111                            users[j]);
11112                    if (finisher != null) {
11113                        waitingUpdate = true;
11114                    }
11115                }
11116            }
11117        }
11118
11119        return waitingUpdate;
11120    }
11121
11122    public void systemReady(final Runnable goingCallback) {
11123        synchronized(this) {
11124            if (mSystemReady) {
11125                // If we're done calling all the receivers, run the next "boot phase" passed in
11126                // by the SystemServer
11127                if (goingCallback != null) {
11128                    goingCallback.run();
11129                }
11130                return;
11131            }
11132
11133            // Make sure we have the current profile info, since it is needed for
11134            // security checks.
11135            updateCurrentProfileIdsLocked();
11136
11137            if (mRecentTasks == null) {
11138                mRecentTasks = mTaskPersister.restoreTasksLocked();
11139                if (!mRecentTasks.isEmpty()) {
11140                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11141                }
11142                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11143                mTaskPersister.startPersisting();
11144            }
11145
11146            // Check to see if there are any update receivers to run.
11147            if (!mDidUpdate) {
11148                if (mWaitingUpdate) {
11149                    return;
11150                }
11151                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11152                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11153                    public void run() {
11154                        synchronized (ActivityManagerService.this) {
11155                            mDidUpdate = true;
11156                        }
11157                        writeLastDonePreBootReceivers(doneReceivers);
11158                        showBootMessage(mContext.getText(
11159                                R.string.android_upgrading_complete),
11160                                false);
11161                        systemReady(goingCallback);
11162                    }
11163                }, doneReceivers, UserHandle.USER_OWNER);
11164
11165                if (mWaitingUpdate) {
11166                    return;
11167                }
11168                mDidUpdate = true;
11169            }
11170
11171            mAppOpsService.systemReady();
11172            mSystemReady = true;
11173        }
11174
11175        ArrayList<ProcessRecord> procsToKill = null;
11176        synchronized(mPidsSelfLocked) {
11177            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11178                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11179                if (!isAllowedWhileBooting(proc.info)){
11180                    if (procsToKill == null) {
11181                        procsToKill = new ArrayList<ProcessRecord>();
11182                    }
11183                    procsToKill.add(proc);
11184                }
11185            }
11186        }
11187
11188        synchronized(this) {
11189            if (procsToKill != null) {
11190                for (int i=procsToKill.size()-1; i>=0; i--) {
11191                    ProcessRecord proc = procsToKill.get(i);
11192                    Slog.i(TAG, "Removing system update proc: " + proc);
11193                    removeProcessLocked(proc, true, false, "system update done");
11194                }
11195            }
11196
11197            // Now that we have cleaned up any update processes, we
11198            // are ready to start launching real processes and know that
11199            // we won't trample on them any more.
11200            mProcessesReady = true;
11201        }
11202
11203        Slog.i(TAG, "System now ready");
11204        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11205            SystemClock.uptimeMillis());
11206
11207        synchronized(this) {
11208            // Make sure we have no pre-ready processes sitting around.
11209
11210            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11211                ResolveInfo ri = mContext.getPackageManager()
11212                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11213                                STOCK_PM_FLAGS);
11214                CharSequence errorMsg = null;
11215                if (ri != null) {
11216                    ActivityInfo ai = ri.activityInfo;
11217                    ApplicationInfo app = ai.applicationInfo;
11218                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11219                        mTopAction = Intent.ACTION_FACTORY_TEST;
11220                        mTopData = null;
11221                        mTopComponent = new ComponentName(app.packageName,
11222                                ai.name);
11223                    } else {
11224                        errorMsg = mContext.getResources().getText(
11225                                com.android.internal.R.string.factorytest_not_system);
11226                    }
11227                } else {
11228                    errorMsg = mContext.getResources().getText(
11229                            com.android.internal.R.string.factorytest_no_action);
11230                }
11231                if (errorMsg != null) {
11232                    mTopAction = null;
11233                    mTopData = null;
11234                    mTopComponent = null;
11235                    Message msg = Message.obtain();
11236                    msg.what = SHOW_FACTORY_ERROR_MSG;
11237                    msg.getData().putCharSequence("msg", errorMsg);
11238                    mHandler.sendMessage(msg);
11239                }
11240            }
11241        }
11242
11243        retrieveSettings();
11244        loadResourcesOnSystemReady();
11245
11246        synchronized (this) {
11247            readGrantedUriPermissionsLocked();
11248        }
11249
11250        if (goingCallback != null) goingCallback.run();
11251
11252        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11253                Integer.toString(mCurrentUserId), mCurrentUserId);
11254        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11255                Integer.toString(mCurrentUserId), mCurrentUserId);
11256        mSystemServiceManager.startUser(mCurrentUserId);
11257
11258        synchronized (this) {
11259            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11260                try {
11261                    List apps = AppGlobals.getPackageManager().
11262                        getPersistentApplications(STOCK_PM_FLAGS);
11263                    if (apps != null) {
11264                        int N = apps.size();
11265                        int i;
11266                        for (i=0; i<N; i++) {
11267                            ApplicationInfo info
11268                                = (ApplicationInfo)apps.get(i);
11269                            if (info != null &&
11270                                    !info.packageName.equals("android")) {
11271                                addAppLocked(info, false, null /* ABI override */);
11272                            }
11273                        }
11274                    }
11275                } catch (RemoteException ex) {
11276                    // pm is in same process, this will never happen.
11277                }
11278            }
11279
11280            // Start up initial activity.
11281            mBooting = true;
11282            startHomeActivityLocked(mCurrentUserId);
11283
11284            try {
11285                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11286                    Message msg = Message.obtain();
11287                    msg.what = SHOW_UID_ERROR_MSG;
11288                    mHandler.sendMessage(msg);
11289                }
11290            } catch (RemoteException e) {
11291            }
11292
11293            long ident = Binder.clearCallingIdentity();
11294            try {
11295                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11296                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11297                        | Intent.FLAG_RECEIVER_FOREGROUND);
11298                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11299                broadcastIntentLocked(null, null, intent,
11300                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11301                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11302                intent = new Intent(Intent.ACTION_USER_STARTING);
11303                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11304                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11305                broadcastIntentLocked(null, null, intent,
11306                        null, new IIntentReceiver.Stub() {
11307                            @Override
11308                            public void performReceive(Intent intent, int resultCode, String data,
11309                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11310                                    throws RemoteException {
11311                            }
11312                        }, 0, null, null,
11313                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11314                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11315            } catch (Throwable t) {
11316                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11317            } finally {
11318                Binder.restoreCallingIdentity(ident);
11319            }
11320            mStackSupervisor.resumeTopActivitiesLocked();
11321            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11322        }
11323    }
11324
11325    private boolean makeAppCrashingLocked(ProcessRecord app,
11326            String shortMsg, String longMsg, String stackTrace) {
11327        app.crashing = true;
11328        app.crashingReport = generateProcessError(app,
11329                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11330        startAppProblemLocked(app);
11331        app.stopFreezingAllLocked();
11332        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11333    }
11334
11335    private void makeAppNotRespondingLocked(ProcessRecord app,
11336            String activity, String shortMsg, String longMsg) {
11337        app.notResponding = true;
11338        app.notRespondingReport = generateProcessError(app,
11339                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11340                activity, shortMsg, longMsg, null);
11341        startAppProblemLocked(app);
11342        app.stopFreezingAllLocked();
11343    }
11344
11345    /**
11346     * Generate a process error record, suitable for attachment to a ProcessRecord.
11347     *
11348     * @param app The ProcessRecord in which the error occurred.
11349     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11350     *                      ActivityManager.AppErrorStateInfo
11351     * @param activity The activity associated with the crash, if known.
11352     * @param shortMsg Short message describing the crash.
11353     * @param longMsg Long message describing the crash.
11354     * @param stackTrace Full crash stack trace, may be null.
11355     *
11356     * @return Returns a fully-formed AppErrorStateInfo record.
11357     */
11358    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11359            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11360        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11361
11362        report.condition = condition;
11363        report.processName = app.processName;
11364        report.pid = app.pid;
11365        report.uid = app.info.uid;
11366        report.tag = activity;
11367        report.shortMsg = shortMsg;
11368        report.longMsg = longMsg;
11369        report.stackTrace = stackTrace;
11370
11371        return report;
11372    }
11373
11374    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11375        synchronized (this) {
11376            app.crashing = false;
11377            app.crashingReport = null;
11378            app.notResponding = false;
11379            app.notRespondingReport = null;
11380            if (app.anrDialog == fromDialog) {
11381                app.anrDialog = null;
11382            }
11383            if (app.waitDialog == fromDialog) {
11384                app.waitDialog = null;
11385            }
11386            if (app.pid > 0 && app.pid != MY_PID) {
11387                handleAppCrashLocked(app, null, null, null);
11388                app.kill("user request after error", true);
11389            }
11390        }
11391    }
11392
11393    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11394            String stackTrace) {
11395        long now = SystemClock.uptimeMillis();
11396
11397        Long crashTime;
11398        if (!app.isolated) {
11399            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11400        } else {
11401            crashTime = null;
11402        }
11403        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11404            // This process loses!
11405            Slog.w(TAG, "Process " + app.info.processName
11406                    + " has crashed too many times: killing!");
11407            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11408                    app.userId, app.info.processName, app.uid);
11409            mStackSupervisor.handleAppCrashLocked(app);
11410            if (!app.persistent) {
11411                // We don't want to start this process again until the user
11412                // explicitly does so...  but for persistent process, we really
11413                // need to keep it running.  If a persistent process is actually
11414                // repeatedly crashing, then badness for everyone.
11415                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11416                        app.info.processName);
11417                if (!app.isolated) {
11418                    // XXX We don't have a way to mark isolated processes
11419                    // as bad, since they don't have a peristent identity.
11420                    mBadProcesses.put(app.info.processName, app.uid,
11421                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11422                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11423                }
11424                app.bad = true;
11425                app.removed = true;
11426                // Don't let services in this process be restarted and potentially
11427                // annoy the user repeatedly.  Unless it is persistent, since those
11428                // processes run critical code.
11429                removeProcessLocked(app, false, false, "crash");
11430                mStackSupervisor.resumeTopActivitiesLocked();
11431                return false;
11432            }
11433            mStackSupervisor.resumeTopActivitiesLocked();
11434        } else {
11435            mStackSupervisor.finishTopRunningActivityLocked(app);
11436        }
11437
11438        // Bump up the crash count of any services currently running in the proc.
11439        for (int i=app.services.size()-1; i>=0; i--) {
11440            // Any services running in the application need to be placed
11441            // back in the pending list.
11442            ServiceRecord sr = app.services.valueAt(i);
11443            sr.crashCount++;
11444        }
11445
11446        // If the crashing process is what we consider to be the "home process" and it has been
11447        // replaced by a third-party app, clear the package preferred activities from packages
11448        // with a home activity running in the process to prevent a repeatedly crashing app
11449        // from blocking the user to manually clear the list.
11450        final ArrayList<ActivityRecord> activities = app.activities;
11451        if (app == mHomeProcess && activities.size() > 0
11452                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11453            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11454                final ActivityRecord r = activities.get(activityNdx);
11455                if (r.isHomeActivity()) {
11456                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11457                    try {
11458                        ActivityThread.getPackageManager()
11459                                .clearPackagePreferredActivities(r.packageName);
11460                    } catch (RemoteException c) {
11461                        // pm is in same process, this will never happen.
11462                    }
11463                }
11464            }
11465        }
11466
11467        if (!app.isolated) {
11468            // XXX Can't keep track of crash times for isolated processes,
11469            // because they don't have a perisistent identity.
11470            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11471        }
11472
11473        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11474        return true;
11475    }
11476
11477    void startAppProblemLocked(ProcessRecord app) {
11478        // If this app is not running under the current user, then we
11479        // can't give it a report button because that would require
11480        // launching the report UI under a different user.
11481        app.errorReportReceiver = null;
11482
11483        for (int userId : mCurrentProfileIds) {
11484            if (app.userId == userId) {
11485                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11486                        mContext, app.info.packageName, app.info.flags);
11487            }
11488        }
11489        skipCurrentReceiverLocked(app);
11490    }
11491
11492    void skipCurrentReceiverLocked(ProcessRecord app) {
11493        for (BroadcastQueue queue : mBroadcastQueues) {
11494            queue.skipCurrentReceiverLocked(app);
11495        }
11496    }
11497
11498    /**
11499     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11500     * The application process will exit immediately after this call returns.
11501     * @param app object of the crashing app, null for the system server
11502     * @param crashInfo describing the exception
11503     */
11504    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11505        ProcessRecord r = findAppProcess(app, "Crash");
11506        final String processName = app == null ? "system_server"
11507                : (r == null ? "unknown" : r.processName);
11508
11509        handleApplicationCrashInner("crash", r, processName, crashInfo);
11510    }
11511
11512    /* Native crash reporting uses this inner version because it needs to be somewhat
11513     * decoupled from the AM-managed cleanup lifecycle
11514     */
11515    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11516            ApplicationErrorReport.CrashInfo crashInfo) {
11517        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11518                UserHandle.getUserId(Binder.getCallingUid()), processName,
11519                r == null ? -1 : r.info.flags,
11520                crashInfo.exceptionClassName,
11521                crashInfo.exceptionMessage,
11522                crashInfo.throwFileName,
11523                crashInfo.throwLineNumber);
11524
11525        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11526
11527        crashApplication(r, crashInfo);
11528    }
11529
11530    public void handleApplicationStrictModeViolation(
11531            IBinder app,
11532            int violationMask,
11533            StrictMode.ViolationInfo info) {
11534        ProcessRecord r = findAppProcess(app, "StrictMode");
11535        if (r == null) {
11536            return;
11537        }
11538
11539        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11540            Integer stackFingerprint = info.hashCode();
11541            boolean logIt = true;
11542            synchronized (mAlreadyLoggedViolatedStacks) {
11543                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11544                    logIt = false;
11545                    // TODO: sub-sample into EventLog for these, with
11546                    // the info.durationMillis?  Then we'd get
11547                    // the relative pain numbers, without logging all
11548                    // the stack traces repeatedly.  We'd want to do
11549                    // likewise in the client code, which also does
11550                    // dup suppression, before the Binder call.
11551                } else {
11552                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11553                        mAlreadyLoggedViolatedStacks.clear();
11554                    }
11555                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11556                }
11557            }
11558            if (logIt) {
11559                logStrictModeViolationToDropBox(r, info);
11560            }
11561        }
11562
11563        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11564            AppErrorResult result = new AppErrorResult();
11565            synchronized (this) {
11566                final long origId = Binder.clearCallingIdentity();
11567
11568                Message msg = Message.obtain();
11569                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11570                HashMap<String, Object> data = new HashMap<String, Object>();
11571                data.put("result", result);
11572                data.put("app", r);
11573                data.put("violationMask", violationMask);
11574                data.put("info", info);
11575                msg.obj = data;
11576                mHandler.sendMessage(msg);
11577
11578                Binder.restoreCallingIdentity(origId);
11579            }
11580            int res = result.get();
11581            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11582        }
11583    }
11584
11585    // Depending on the policy in effect, there could be a bunch of
11586    // these in quick succession so we try to batch these together to
11587    // minimize disk writes, number of dropbox entries, and maximize
11588    // compression, by having more fewer, larger records.
11589    private void logStrictModeViolationToDropBox(
11590            ProcessRecord process,
11591            StrictMode.ViolationInfo info) {
11592        if (info == null) {
11593            return;
11594        }
11595        final boolean isSystemApp = process == null ||
11596                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11597                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11598        final String processName = process == null ? "unknown" : process.processName;
11599        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11600        final DropBoxManager dbox = (DropBoxManager)
11601                mContext.getSystemService(Context.DROPBOX_SERVICE);
11602
11603        // Exit early if the dropbox isn't configured to accept this report type.
11604        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11605
11606        boolean bufferWasEmpty;
11607        boolean needsFlush;
11608        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11609        synchronized (sb) {
11610            bufferWasEmpty = sb.length() == 0;
11611            appendDropBoxProcessHeaders(process, processName, sb);
11612            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11613            sb.append("System-App: ").append(isSystemApp).append("\n");
11614            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11615            if (info.violationNumThisLoop != 0) {
11616                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11617            }
11618            if (info.numAnimationsRunning != 0) {
11619                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11620            }
11621            if (info.broadcastIntentAction != null) {
11622                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11623            }
11624            if (info.durationMillis != -1) {
11625                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11626            }
11627            if (info.numInstances != -1) {
11628                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11629            }
11630            if (info.tags != null) {
11631                for (String tag : info.tags) {
11632                    sb.append("Span-Tag: ").append(tag).append("\n");
11633                }
11634            }
11635            sb.append("\n");
11636            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11637                sb.append(info.crashInfo.stackTrace);
11638            }
11639            sb.append("\n");
11640
11641            // Only buffer up to ~64k.  Various logging bits truncate
11642            // things at 128k.
11643            needsFlush = (sb.length() > 64 * 1024);
11644        }
11645
11646        // Flush immediately if the buffer's grown too large, or this
11647        // is a non-system app.  Non-system apps are isolated with a
11648        // different tag & policy and not batched.
11649        //
11650        // Batching is useful during internal testing with
11651        // StrictMode settings turned up high.  Without batching,
11652        // thousands of separate files could be created on boot.
11653        if (!isSystemApp || needsFlush) {
11654            new Thread("Error dump: " + dropboxTag) {
11655                @Override
11656                public void run() {
11657                    String report;
11658                    synchronized (sb) {
11659                        report = sb.toString();
11660                        sb.delete(0, sb.length());
11661                        sb.trimToSize();
11662                    }
11663                    if (report.length() != 0) {
11664                        dbox.addText(dropboxTag, report);
11665                    }
11666                }
11667            }.start();
11668            return;
11669        }
11670
11671        // System app batching:
11672        if (!bufferWasEmpty) {
11673            // An existing dropbox-writing thread is outstanding, so
11674            // we don't need to start it up.  The existing thread will
11675            // catch the buffer appends we just did.
11676            return;
11677        }
11678
11679        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11680        // (After this point, we shouldn't access AMS internal data structures.)
11681        new Thread("Error dump: " + dropboxTag) {
11682            @Override
11683            public void run() {
11684                // 5 second sleep to let stacks arrive and be batched together
11685                try {
11686                    Thread.sleep(5000);  // 5 seconds
11687                } catch (InterruptedException e) {}
11688
11689                String errorReport;
11690                synchronized (mStrictModeBuffer) {
11691                    errorReport = mStrictModeBuffer.toString();
11692                    if (errorReport.length() == 0) {
11693                        return;
11694                    }
11695                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11696                    mStrictModeBuffer.trimToSize();
11697                }
11698                dbox.addText(dropboxTag, errorReport);
11699            }
11700        }.start();
11701    }
11702
11703    /**
11704     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11705     * @param app object of the crashing app, null for the system server
11706     * @param tag reported by the caller
11707     * @param system whether this wtf is coming from the system
11708     * @param crashInfo describing the context of the error
11709     * @return true if the process should exit immediately (WTF is fatal)
11710     */
11711    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11712            final ApplicationErrorReport.CrashInfo crashInfo) {
11713        final ProcessRecord r = findAppProcess(app, "WTF");
11714        final String processName = app == null ? "system_server"
11715                : (r == null ? "unknown" : r.processName);
11716
11717        EventLog.writeEvent(EventLogTags.AM_WTF,
11718                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11719                processName,
11720                r == null ? -1 : r.info.flags,
11721                tag, crashInfo.exceptionMessage);
11722
11723        if (system) {
11724            // If this is coming from the system, we could very well have low-level
11725            // system locks held, so we want to do this all asynchronously.  And we
11726            // never want this to become fatal, so there is that too.
11727            mHandler.post(new Runnable() {
11728                @Override public void run() {
11729                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11730                            crashInfo);
11731                }
11732            });
11733            return false;
11734        }
11735
11736        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11737
11738        if (r != null && r.pid != Process.myPid() &&
11739                Settings.Global.getInt(mContext.getContentResolver(),
11740                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11741            crashApplication(r, crashInfo);
11742            return true;
11743        } else {
11744            return false;
11745        }
11746    }
11747
11748    /**
11749     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11750     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11751     */
11752    private ProcessRecord findAppProcess(IBinder app, String reason) {
11753        if (app == null) {
11754            return null;
11755        }
11756
11757        synchronized (this) {
11758            final int NP = mProcessNames.getMap().size();
11759            for (int ip=0; ip<NP; ip++) {
11760                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11761                final int NA = apps.size();
11762                for (int ia=0; ia<NA; ia++) {
11763                    ProcessRecord p = apps.valueAt(ia);
11764                    if (p.thread != null && p.thread.asBinder() == app) {
11765                        return p;
11766                    }
11767                }
11768            }
11769
11770            Slog.w(TAG, "Can't find mystery application for " + reason
11771                    + " from pid=" + Binder.getCallingPid()
11772                    + " uid=" + Binder.getCallingUid() + ": " + app);
11773            return null;
11774        }
11775    }
11776
11777    /**
11778     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11779     * to append various headers to the dropbox log text.
11780     */
11781    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11782            StringBuilder sb) {
11783        // Watchdog thread ends up invoking this function (with
11784        // a null ProcessRecord) to add the stack file to dropbox.
11785        // Do not acquire a lock on this (am) in such cases, as it
11786        // could cause a potential deadlock, if and when watchdog
11787        // is invoked due to unavailability of lock on am and it
11788        // would prevent watchdog from killing system_server.
11789        if (process == null) {
11790            sb.append("Process: ").append(processName).append("\n");
11791            return;
11792        }
11793        // Note: ProcessRecord 'process' is guarded by the service
11794        // instance.  (notably process.pkgList, which could otherwise change
11795        // concurrently during execution of this method)
11796        synchronized (this) {
11797            sb.append("Process: ").append(processName).append("\n");
11798            int flags = process.info.flags;
11799            IPackageManager pm = AppGlobals.getPackageManager();
11800            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11801            for (int ip=0; ip<process.pkgList.size(); ip++) {
11802                String pkg = process.pkgList.keyAt(ip);
11803                sb.append("Package: ").append(pkg);
11804                try {
11805                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11806                    if (pi != null) {
11807                        sb.append(" v").append(pi.versionCode);
11808                        if (pi.versionName != null) {
11809                            sb.append(" (").append(pi.versionName).append(")");
11810                        }
11811                    }
11812                } catch (RemoteException e) {
11813                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11814                }
11815                sb.append("\n");
11816            }
11817        }
11818    }
11819
11820    private static String processClass(ProcessRecord process) {
11821        if (process == null || process.pid == MY_PID) {
11822            return "system_server";
11823        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11824            return "system_app";
11825        } else {
11826            return "data_app";
11827        }
11828    }
11829
11830    /**
11831     * Write a description of an error (crash, WTF, ANR) to the drop box.
11832     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11833     * @param process which caused the error, null means the system server
11834     * @param activity which triggered the error, null if unknown
11835     * @param parent activity related to the error, null if unknown
11836     * @param subject line related to the error, null if absent
11837     * @param report in long form describing the error, null if absent
11838     * @param logFile to include in the report, null if none
11839     * @param crashInfo giving an application stack trace, null if absent
11840     */
11841    public void addErrorToDropBox(String eventType,
11842            ProcessRecord process, String processName, ActivityRecord activity,
11843            ActivityRecord parent, String subject,
11844            final String report, final File logFile,
11845            final ApplicationErrorReport.CrashInfo crashInfo) {
11846        // NOTE -- this must never acquire the ActivityManagerService lock,
11847        // otherwise the watchdog may be prevented from resetting the system.
11848
11849        final String dropboxTag = processClass(process) + "_" + eventType;
11850        final DropBoxManager dbox = (DropBoxManager)
11851                mContext.getSystemService(Context.DROPBOX_SERVICE);
11852
11853        // Exit early if the dropbox isn't configured to accept this report type.
11854        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11855
11856        final StringBuilder sb = new StringBuilder(1024);
11857        appendDropBoxProcessHeaders(process, processName, sb);
11858        if (activity != null) {
11859            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11860        }
11861        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11862            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11863        }
11864        if (parent != null && parent != activity) {
11865            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11866        }
11867        if (subject != null) {
11868            sb.append("Subject: ").append(subject).append("\n");
11869        }
11870        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11871        if (Debug.isDebuggerConnected()) {
11872            sb.append("Debugger: Connected\n");
11873        }
11874        sb.append("\n");
11875
11876        // Do the rest in a worker thread to avoid blocking the caller on I/O
11877        // (After this point, we shouldn't access AMS internal data structures.)
11878        Thread worker = new Thread("Error dump: " + dropboxTag) {
11879            @Override
11880            public void run() {
11881                if (report != null) {
11882                    sb.append(report);
11883                }
11884                if (logFile != null) {
11885                    try {
11886                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11887                                    "\n\n[[TRUNCATED]]"));
11888                    } catch (IOException e) {
11889                        Slog.e(TAG, "Error reading " + logFile, e);
11890                    }
11891                }
11892                if (crashInfo != null && crashInfo.stackTrace != null) {
11893                    sb.append(crashInfo.stackTrace);
11894                }
11895
11896                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11897                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11898                if (lines > 0) {
11899                    sb.append("\n");
11900
11901                    // Merge several logcat streams, and take the last N lines
11902                    InputStreamReader input = null;
11903                    try {
11904                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11905                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11906                                "-b", "crash",
11907                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11908
11909                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11910                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11911                        input = new InputStreamReader(logcat.getInputStream());
11912
11913                        int num;
11914                        char[] buf = new char[8192];
11915                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11916                    } catch (IOException e) {
11917                        Slog.e(TAG, "Error running logcat", e);
11918                    } finally {
11919                        if (input != null) try { input.close(); } catch (IOException e) {}
11920                    }
11921                }
11922
11923                dbox.addText(dropboxTag, sb.toString());
11924            }
11925        };
11926
11927        if (process == null) {
11928            // If process is null, we are being called from some internal code
11929            // and may be about to die -- run this synchronously.
11930            worker.run();
11931        } else {
11932            worker.start();
11933        }
11934    }
11935
11936    /**
11937     * Bring up the "unexpected error" dialog box for a crashing app.
11938     * Deal with edge cases (intercepts from instrumented applications,
11939     * ActivityController, error intent receivers, that sort of thing).
11940     * @param r the application crashing
11941     * @param crashInfo describing the failure
11942     */
11943    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11944        long timeMillis = System.currentTimeMillis();
11945        String shortMsg = crashInfo.exceptionClassName;
11946        String longMsg = crashInfo.exceptionMessage;
11947        String stackTrace = crashInfo.stackTrace;
11948        if (shortMsg != null && longMsg != null) {
11949            longMsg = shortMsg + ": " + longMsg;
11950        } else if (shortMsg != null) {
11951            longMsg = shortMsg;
11952        }
11953
11954        AppErrorResult result = new AppErrorResult();
11955        synchronized (this) {
11956            if (mController != null) {
11957                try {
11958                    String name = r != null ? r.processName : null;
11959                    int pid = r != null ? r.pid : Binder.getCallingPid();
11960                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11961                    if (!mController.appCrashed(name, pid,
11962                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11963                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11964                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11965                            Slog.w(TAG, "Skip killing native crashed app " + name
11966                                    + "(" + pid + ") during testing");
11967                        } else {
11968                            Slog.w(TAG, "Force-killing crashed app " + name
11969                                    + " at watcher's request");
11970                            if (r != null) {
11971                                r.kill("crash", true);
11972                            } else {
11973                                // Huh.
11974                                Process.killProcess(pid);
11975                                Process.killProcessGroup(uid, pid);
11976                            }
11977                        }
11978                        return;
11979                    }
11980                } catch (RemoteException e) {
11981                    mController = null;
11982                    Watchdog.getInstance().setActivityController(null);
11983                }
11984            }
11985
11986            final long origId = Binder.clearCallingIdentity();
11987
11988            // If this process is running instrumentation, finish it.
11989            if (r != null && r.instrumentationClass != null) {
11990                Slog.w(TAG, "Error in app " + r.processName
11991                      + " running instrumentation " + r.instrumentationClass + ":");
11992                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11993                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11994                Bundle info = new Bundle();
11995                info.putString("shortMsg", shortMsg);
11996                info.putString("longMsg", longMsg);
11997                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11998                Binder.restoreCallingIdentity(origId);
11999                return;
12000            }
12001
12002            // If we can't identify the process or it's already exceeded its crash quota,
12003            // quit right away without showing a crash dialog.
12004            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12005                Binder.restoreCallingIdentity(origId);
12006                return;
12007            }
12008
12009            Message msg = Message.obtain();
12010            msg.what = SHOW_ERROR_MSG;
12011            HashMap data = new HashMap();
12012            data.put("result", result);
12013            data.put("app", r);
12014            msg.obj = data;
12015            mHandler.sendMessage(msg);
12016
12017            Binder.restoreCallingIdentity(origId);
12018        }
12019
12020        int res = result.get();
12021
12022        Intent appErrorIntent = null;
12023        synchronized (this) {
12024            if (r != null && !r.isolated) {
12025                // XXX Can't keep track of crash time for isolated processes,
12026                // since they don't have a persistent identity.
12027                mProcessCrashTimes.put(r.info.processName, r.uid,
12028                        SystemClock.uptimeMillis());
12029            }
12030            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12031                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12032            }
12033        }
12034
12035        if (appErrorIntent != null) {
12036            try {
12037                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12038            } catch (ActivityNotFoundException e) {
12039                Slog.w(TAG, "bug report receiver dissappeared", e);
12040            }
12041        }
12042    }
12043
12044    Intent createAppErrorIntentLocked(ProcessRecord r,
12045            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12046        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12047        if (report == null) {
12048            return null;
12049        }
12050        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12051        result.setComponent(r.errorReportReceiver);
12052        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12053        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12054        return result;
12055    }
12056
12057    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12058            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12059        if (r.errorReportReceiver == null) {
12060            return null;
12061        }
12062
12063        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12064            return null;
12065        }
12066
12067        ApplicationErrorReport report = new ApplicationErrorReport();
12068        report.packageName = r.info.packageName;
12069        report.installerPackageName = r.errorReportReceiver.getPackageName();
12070        report.processName = r.processName;
12071        report.time = timeMillis;
12072        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12073
12074        if (r.crashing || r.forceCrashReport) {
12075            report.type = ApplicationErrorReport.TYPE_CRASH;
12076            report.crashInfo = crashInfo;
12077        } else if (r.notResponding) {
12078            report.type = ApplicationErrorReport.TYPE_ANR;
12079            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12080
12081            report.anrInfo.activity = r.notRespondingReport.tag;
12082            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12083            report.anrInfo.info = r.notRespondingReport.longMsg;
12084        }
12085
12086        return report;
12087    }
12088
12089    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12090        enforceNotIsolatedCaller("getProcessesInErrorState");
12091        // assume our apps are happy - lazy create the list
12092        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12093
12094        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12095                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12096        int userId = UserHandle.getUserId(Binder.getCallingUid());
12097
12098        synchronized (this) {
12099
12100            // iterate across all processes
12101            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12102                ProcessRecord app = mLruProcesses.get(i);
12103                if (!allUsers && app.userId != userId) {
12104                    continue;
12105                }
12106                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12107                    // This one's in trouble, so we'll generate a report for it
12108                    // crashes are higher priority (in case there's a crash *and* an anr)
12109                    ActivityManager.ProcessErrorStateInfo report = null;
12110                    if (app.crashing) {
12111                        report = app.crashingReport;
12112                    } else if (app.notResponding) {
12113                        report = app.notRespondingReport;
12114                    }
12115
12116                    if (report != null) {
12117                        if (errList == null) {
12118                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12119                        }
12120                        errList.add(report);
12121                    } else {
12122                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12123                                " crashing = " + app.crashing +
12124                                " notResponding = " + app.notResponding);
12125                    }
12126                }
12127            }
12128        }
12129
12130        return errList;
12131    }
12132
12133    static int procStateToImportance(int procState, int memAdj,
12134            ActivityManager.RunningAppProcessInfo currApp) {
12135        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12136        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12137            currApp.lru = memAdj;
12138        } else {
12139            currApp.lru = 0;
12140        }
12141        return imp;
12142    }
12143
12144    private void fillInProcMemInfo(ProcessRecord app,
12145            ActivityManager.RunningAppProcessInfo outInfo) {
12146        outInfo.pid = app.pid;
12147        outInfo.uid = app.info.uid;
12148        if (mHeavyWeightProcess == app) {
12149            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12150        }
12151        if (app.persistent) {
12152            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12153        }
12154        if (app.activities.size() > 0) {
12155            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12156        }
12157        outInfo.lastTrimLevel = app.trimMemoryLevel;
12158        int adj = app.curAdj;
12159        int procState = app.curProcState;
12160        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12161        outInfo.importanceReasonCode = app.adjTypeCode;
12162        outInfo.processState = app.curProcState;
12163    }
12164
12165    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12166        enforceNotIsolatedCaller("getRunningAppProcesses");
12167        // Lazy instantiation of list
12168        List<ActivityManager.RunningAppProcessInfo> runList = null;
12169        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12170                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12171        int userId = UserHandle.getUserId(Binder.getCallingUid());
12172        synchronized (this) {
12173            // Iterate across all processes
12174            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12175                ProcessRecord app = mLruProcesses.get(i);
12176                if (!allUsers && app.userId != userId) {
12177                    continue;
12178                }
12179                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12180                    // Generate process state info for running application
12181                    ActivityManager.RunningAppProcessInfo currApp =
12182                        new ActivityManager.RunningAppProcessInfo(app.processName,
12183                                app.pid, app.getPackageList());
12184                    fillInProcMemInfo(app, currApp);
12185                    if (app.adjSource instanceof ProcessRecord) {
12186                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12187                        currApp.importanceReasonImportance =
12188                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12189                                        app.adjSourceProcState);
12190                    } else if (app.adjSource instanceof ActivityRecord) {
12191                        ActivityRecord r = (ActivityRecord)app.adjSource;
12192                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12193                    }
12194                    if (app.adjTarget instanceof ComponentName) {
12195                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12196                    }
12197                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12198                    //        + " lru=" + currApp.lru);
12199                    if (runList == null) {
12200                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12201                    }
12202                    runList.add(currApp);
12203                }
12204            }
12205        }
12206        return runList;
12207    }
12208
12209    public List<ApplicationInfo> getRunningExternalApplications() {
12210        enforceNotIsolatedCaller("getRunningExternalApplications");
12211        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12212        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12213        if (runningApps != null && runningApps.size() > 0) {
12214            Set<String> extList = new HashSet<String>();
12215            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12216                if (app.pkgList != null) {
12217                    for (String pkg : app.pkgList) {
12218                        extList.add(pkg);
12219                    }
12220                }
12221            }
12222            IPackageManager pm = AppGlobals.getPackageManager();
12223            for (String pkg : extList) {
12224                try {
12225                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12226                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12227                        retList.add(info);
12228                    }
12229                } catch (RemoteException e) {
12230                }
12231            }
12232        }
12233        return retList;
12234    }
12235
12236    @Override
12237    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12238        enforceNotIsolatedCaller("getMyMemoryState");
12239        synchronized (this) {
12240            ProcessRecord proc;
12241            synchronized (mPidsSelfLocked) {
12242                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12243            }
12244            fillInProcMemInfo(proc, outInfo);
12245        }
12246    }
12247
12248    @Override
12249    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12250        if (checkCallingPermission(android.Manifest.permission.DUMP)
12251                != PackageManager.PERMISSION_GRANTED) {
12252            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12253                    + Binder.getCallingPid()
12254                    + ", uid=" + Binder.getCallingUid()
12255                    + " without permission "
12256                    + android.Manifest.permission.DUMP);
12257            return;
12258        }
12259
12260        boolean dumpAll = false;
12261        boolean dumpClient = false;
12262        String dumpPackage = null;
12263
12264        int opti = 0;
12265        while (opti < args.length) {
12266            String opt = args[opti];
12267            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12268                break;
12269            }
12270            opti++;
12271            if ("-a".equals(opt)) {
12272                dumpAll = true;
12273            } else if ("-c".equals(opt)) {
12274                dumpClient = true;
12275            } else if ("-h".equals(opt)) {
12276                pw.println("Activity manager dump options:");
12277                pw.println("  [-a] [-c] [-h] [cmd] ...");
12278                pw.println("  cmd may be one of:");
12279                pw.println("    a[ctivities]: activity stack state");
12280                pw.println("    r[recents]: recent activities state");
12281                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12282                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12283                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12284                pw.println("    o[om]: out of memory management");
12285                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12286                pw.println("    provider [COMP_SPEC]: provider client-side state");
12287                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12288                pw.println("    service [COMP_SPEC]: service client-side state");
12289                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12290                pw.println("    all: dump all activities");
12291                pw.println("    top: dump the top activity");
12292                pw.println("    write: write all pending state to storage");
12293                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12294                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12295                pw.println("    a partial substring in a component name, a");
12296                pw.println("    hex object identifier.");
12297                pw.println("  -a: include all available server state.");
12298                pw.println("  -c: include client state.");
12299                return;
12300            } else {
12301                pw.println("Unknown argument: " + opt + "; use -h for help");
12302            }
12303        }
12304
12305        long origId = Binder.clearCallingIdentity();
12306        boolean more = false;
12307        // Is the caller requesting to dump a particular piece of data?
12308        if (opti < args.length) {
12309            String cmd = args[opti];
12310            opti++;
12311            if ("activities".equals(cmd) || "a".equals(cmd)) {
12312                synchronized (this) {
12313                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12314                }
12315            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12316                synchronized (this) {
12317                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12318                }
12319            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12320                String[] newArgs;
12321                String name;
12322                if (opti >= args.length) {
12323                    name = null;
12324                    newArgs = EMPTY_STRING_ARRAY;
12325                } else {
12326                    name = args[opti];
12327                    opti++;
12328                    newArgs = new String[args.length - opti];
12329                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12330                            args.length - opti);
12331                }
12332                synchronized (this) {
12333                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12334                }
12335            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12336                String[] newArgs;
12337                String name;
12338                if (opti >= args.length) {
12339                    name = null;
12340                    newArgs = EMPTY_STRING_ARRAY;
12341                } else {
12342                    name = args[opti];
12343                    opti++;
12344                    newArgs = new String[args.length - opti];
12345                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12346                            args.length - opti);
12347                }
12348                synchronized (this) {
12349                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12350                }
12351            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12352                String[] newArgs;
12353                String name;
12354                if (opti >= args.length) {
12355                    name = null;
12356                    newArgs = EMPTY_STRING_ARRAY;
12357                } else {
12358                    name = args[opti];
12359                    opti++;
12360                    newArgs = new String[args.length - opti];
12361                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12362                            args.length - opti);
12363                }
12364                synchronized (this) {
12365                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12366                }
12367            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12368                synchronized (this) {
12369                    dumpOomLocked(fd, pw, args, opti, true);
12370                }
12371            } else if ("provider".equals(cmd)) {
12372                String[] newArgs;
12373                String name;
12374                if (opti >= args.length) {
12375                    name = null;
12376                    newArgs = EMPTY_STRING_ARRAY;
12377                } else {
12378                    name = args[opti];
12379                    opti++;
12380                    newArgs = new String[args.length - opti];
12381                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12382                }
12383                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12384                    pw.println("No providers match: " + name);
12385                    pw.println("Use -h for help.");
12386                }
12387            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12388                synchronized (this) {
12389                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12390                }
12391            } else if ("service".equals(cmd)) {
12392                String[] newArgs;
12393                String name;
12394                if (opti >= args.length) {
12395                    name = null;
12396                    newArgs = EMPTY_STRING_ARRAY;
12397                } else {
12398                    name = args[opti];
12399                    opti++;
12400                    newArgs = new String[args.length - opti];
12401                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12402                            args.length - opti);
12403                }
12404                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12405                    pw.println("No services match: " + name);
12406                    pw.println("Use -h for help.");
12407                }
12408            } else if ("package".equals(cmd)) {
12409                String[] newArgs;
12410                if (opti >= args.length) {
12411                    pw.println("package: no package name specified");
12412                    pw.println("Use -h for help.");
12413                } else {
12414                    dumpPackage = args[opti];
12415                    opti++;
12416                    newArgs = new String[args.length - opti];
12417                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12418                            args.length - opti);
12419                    args = newArgs;
12420                    opti = 0;
12421                    more = true;
12422                }
12423            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12424                synchronized (this) {
12425                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12426                }
12427            } else if ("write".equals(cmd)) {
12428                mTaskPersister.flush();
12429                pw.println("All tasks persisted.");
12430                return;
12431            } else {
12432                // Dumping a single activity?
12433                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12434                    pw.println("Bad activity command, or no activities match: " + cmd);
12435                    pw.println("Use -h for help.");
12436                }
12437            }
12438            if (!more) {
12439                Binder.restoreCallingIdentity(origId);
12440                return;
12441            }
12442        }
12443
12444        // No piece of data specified, dump everything.
12445        synchronized (this) {
12446            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12447            pw.println();
12448            if (dumpAll) {
12449                pw.println("-------------------------------------------------------------------------------");
12450            }
12451            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12452            pw.println();
12453            if (dumpAll) {
12454                pw.println("-------------------------------------------------------------------------------");
12455            }
12456            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12457            pw.println();
12458            if (dumpAll) {
12459                pw.println("-------------------------------------------------------------------------------");
12460            }
12461            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12462            pw.println();
12463            if (dumpAll) {
12464                pw.println("-------------------------------------------------------------------------------");
12465            }
12466            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12467            pw.println();
12468            if (dumpAll) {
12469                pw.println("-------------------------------------------------------------------------------");
12470            }
12471            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12472            pw.println();
12473            if (dumpAll) {
12474                pw.println("-------------------------------------------------------------------------------");
12475            }
12476            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12477        }
12478        Binder.restoreCallingIdentity(origId);
12479    }
12480
12481    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12482            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12483        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12484
12485        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12486                dumpPackage);
12487        boolean needSep = printedAnything;
12488
12489        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12490                dumpPackage, needSep, "  mFocusedActivity: ");
12491        if (printed) {
12492            printedAnything = true;
12493            needSep = false;
12494        }
12495
12496        if (dumpPackage == null) {
12497            if (needSep) {
12498                pw.println();
12499            }
12500            needSep = true;
12501            printedAnything = true;
12502            mStackSupervisor.dump(pw, "  ");
12503        }
12504
12505        if (!printedAnything) {
12506            pw.println("  (nothing)");
12507        }
12508    }
12509
12510    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12511            int opti, boolean dumpAll, String dumpPackage) {
12512        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12513
12514        boolean printedAnything = false;
12515
12516        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12517            boolean printedHeader = false;
12518
12519            final int N = mRecentTasks.size();
12520            for (int i=0; i<N; i++) {
12521                TaskRecord tr = mRecentTasks.get(i);
12522                if (dumpPackage != null) {
12523                    if (tr.realActivity == null ||
12524                            !dumpPackage.equals(tr.realActivity)) {
12525                        continue;
12526                    }
12527                }
12528                if (!printedHeader) {
12529                    pw.println("  Recent tasks:");
12530                    printedHeader = true;
12531                    printedAnything = true;
12532                }
12533                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12534                        pw.println(tr);
12535                if (dumpAll) {
12536                    mRecentTasks.get(i).dump(pw, "    ");
12537                }
12538            }
12539        }
12540
12541        if (!printedAnything) {
12542            pw.println("  (nothing)");
12543        }
12544    }
12545
12546    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12547            int opti, boolean dumpAll, String dumpPackage) {
12548        boolean needSep = false;
12549        boolean printedAnything = false;
12550        int numPers = 0;
12551
12552        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12553
12554        if (dumpAll) {
12555            final int NP = mProcessNames.getMap().size();
12556            for (int ip=0; ip<NP; ip++) {
12557                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12558                final int NA = procs.size();
12559                for (int ia=0; ia<NA; ia++) {
12560                    ProcessRecord r = procs.valueAt(ia);
12561                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12562                        continue;
12563                    }
12564                    if (!needSep) {
12565                        pw.println("  All known processes:");
12566                        needSep = true;
12567                        printedAnything = true;
12568                    }
12569                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12570                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12571                        pw.print(" "); pw.println(r);
12572                    r.dump(pw, "    ");
12573                    if (r.persistent) {
12574                        numPers++;
12575                    }
12576                }
12577            }
12578        }
12579
12580        if (mIsolatedProcesses.size() > 0) {
12581            boolean printed = false;
12582            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12583                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12584                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12585                    continue;
12586                }
12587                if (!printed) {
12588                    if (needSep) {
12589                        pw.println();
12590                    }
12591                    pw.println("  Isolated process list (sorted by uid):");
12592                    printedAnything = true;
12593                    printed = true;
12594                    needSep = true;
12595                }
12596                pw.println(String.format("%sIsolated #%2d: %s",
12597                        "    ", i, r.toString()));
12598            }
12599        }
12600
12601        if (mLruProcesses.size() > 0) {
12602            if (needSep) {
12603                pw.println();
12604            }
12605            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12606                    pw.print(" total, non-act at ");
12607                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12608                    pw.print(", non-svc at ");
12609                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12610                    pw.println("):");
12611            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12612            needSep = true;
12613            printedAnything = true;
12614        }
12615
12616        if (dumpAll || dumpPackage != null) {
12617            synchronized (mPidsSelfLocked) {
12618                boolean printed = false;
12619                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12620                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12621                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12622                        continue;
12623                    }
12624                    if (!printed) {
12625                        if (needSep) pw.println();
12626                        needSep = true;
12627                        pw.println("  PID mappings:");
12628                        printed = true;
12629                        printedAnything = true;
12630                    }
12631                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12632                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12633                }
12634            }
12635        }
12636
12637        if (mForegroundProcesses.size() > 0) {
12638            synchronized (mPidsSelfLocked) {
12639                boolean printed = false;
12640                for (int i=0; i<mForegroundProcesses.size(); i++) {
12641                    ProcessRecord r = mPidsSelfLocked.get(
12642                            mForegroundProcesses.valueAt(i).pid);
12643                    if (dumpPackage != null && (r == null
12644                            || !r.pkgList.containsKey(dumpPackage))) {
12645                        continue;
12646                    }
12647                    if (!printed) {
12648                        if (needSep) pw.println();
12649                        needSep = true;
12650                        pw.println("  Foreground Processes:");
12651                        printed = true;
12652                        printedAnything = true;
12653                    }
12654                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12655                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12656                }
12657            }
12658        }
12659
12660        if (mPersistentStartingProcesses.size() > 0) {
12661            if (needSep) pw.println();
12662            needSep = true;
12663            printedAnything = true;
12664            pw.println("  Persisent processes that are starting:");
12665            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12666                    "Starting Norm", "Restarting PERS", dumpPackage);
12667        }
12668
12669        if (mRemovedProcesses.size() > 0) {
12670            if (needSep) pw.println();
12671            needSep = true;
12672            printedAnything = true;
12673            pw.println("  Processes that are being removed:");
12674            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12675                    "Removed Norm", "Removed PERS", dumpPackage);
12676        }
12677
12678        if (mProcessesOnHold.size() > 0) {
12679            if (needSep) pw.println();
12680            needSep = true;
12681            printedAnything = true;
12682            pw.println("  Processes that are on old until the system is ready:");
12683            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12684                    "OnHold Norm", "OnHold PERS", dumpPackage);
12685        }
12686
12687        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12688
12689        if (mProcessCrashTimes.getMap().size() > 0) {
12690            boolean printed = false;
12691            long now = SystemClock.uptimeMillis();
12692            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12693            final int NP = pmap.size();
12694            for (int ip=0; ip<NP; ip++) {
12695                String pname = pmap.keyAt(ip);
12696                SparseArray<Long> uids = pmap.valueAt(ip);
12697                final int N = uids.size();
12698                for (int i=0; i<N; i++) {
12699                    int puid = uids.keyAt(i);
12700                    ProcessRecord r = mProcessNames.get(pname, puid);
12701                    if (dumpPackage != null && (r == null
12702                            || !r.pkgList.containsKey(dumpPackage))) {
12703                        continue;
12704                    }
12705                    if (!printed) {
12706                        if (needSep) pw.println();
12707                        needSep = true;
12708                        pw.println("  Time since processes crashed:");
12709                        printed = true;
12710                        printedAnything = true;
12711                    }
12712                    pw.print("    Process "); pw.print(pname);
12713                            pw.print(" uid "); pw.print(puid);
12714                            pw.print(": last crashed ");
12715                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12716                            pw.println(" ago");
12717                }
12718            }
12719        }
12720
12721        if (mBadProcesses.getMap().size() > 0) {
12722            boolean printed = false;
12723            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12724            final int NP = pmap.size();
12725            for (int ip=0; ip<NP; ip++) {
12726                String pname = pmap.keyAt(ip);
12727                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12728                final int N = uids.size();
12729                for (int i=0; i<N; i++) {
12730                    int puid = uids.keyAt(i);
12731                    ProcessRecord r = mProcessNames.get(pname, puid);
12732                    if (dumpPackage != null && (r == null
12733                            || !r.pkgList.containsKey(dumpPackage))) {
12734                        continue;
12735                    }
12736                    if (!printed) {
12737                        if (needSep) pw.println();
12738                        needSep = true;
12739                        pw.println("  Bad processes:");
12740                        printedAnything = true;
12741                    }
12742                    BadProcessInfo info = uids.valueAt(i);
12743                    pw.print("    Bad process "); pw.print(pname);
12744                            pw.print(" uid "); pw.print(puid);
12745                            pw.print(": crashed at time "); pw.println(info.time);
12746                    if (info.shortMsg != null) {
12747                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12748                    }
12749                    if (info.longMsg != null) {
12750                        pw.print("      Long msg: "); pw.println(info.longMsg);
12751                    }
12752                    if (info.stack != null) {
12753                        pw.println("      Stack:");
12754                        int lastPos = 0;
12755                        for (int pos=0; pos<info.stack.length(); pos++) {
12756                            if (info.stack.charAt(pos) == '\n') {
12757                                pw.print("        ");
12758                                pw.write(info.stack, lastPos, pos-lastPos);
12759                                pw.println();
12760                                lastPos = pos+1;
12761                            }
12762                        }
12763                        if (lastPos < info.stack.length()) {
12764                            pw.print("        ");
12765                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12766                            pw.println();
12767                        }
12768                    }
12769                }
12770            }
12771        }
12772
12773        if (dumpPackage == null) {
12774            pw.println();
12775            needSep = false;
12776            pw.println("  mStartedUsers:");
12777            for (int i=0; i<mStartedUsers.size(); i++) {
12778                UserStartedState uss = mStartedUsers.valueAt(i);
12779                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12780                        pw.print(": "); uss.dump("", pw);
12781            }
12782            pw.print("  mStartedUserArray: [");
12783            for (int i=0; i<mStartedUserArray.length; i++) {
12784                if (i > 0) pw.print(", ");
12785                pw.print(mStartedUserArray[i]);
12786            }
12787            pw.println("]");
12788            pw.print("  mUserLru: [");
12789            for (int i=0; i<mUserLru.size(); i++) {
12790                if (i > 0) pw.print(", ");
12791                pw.print(mUserLru.get(i));
12792            }
12793            pw.println("]");
12794            if (dumpAll) {
12795                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12796            }
12797            synchronized (mUserProfileGroupIdsSelfLocked) {
12798                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12799                    pw.println("  mUserProfileGroupIds:");
12800                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12801                        pw.print("    User #");
12802                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12803                        pw.print(" -> profile #");
12804                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12805                    }
12806                }
12807            }
12808        }
12809        if (mHomeProcess != null && (dumpPackage == null
12810                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12811            if (needSep) {
12812                pw.println();
12813                needSep = false;
12814            }
12815            pw.println("  mHomeProcess: " + mHomeProcess);
12816        }
12817        if (mPreviousProcess != null && (dumpPackage == null
12818                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12819            if (needSep) {
12820                pw.println();
12821                needSep = false;
12822            }
12823            pw.println("  mPreviousProcess: " + mPreviousProcess);
12824        }
12825        if (dumpAll) {
12826            StringBuilder sb = new StringBuilder(128);
12827            sb.append("  mPreviousProcessVisibleTime: ");
12828            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12829            pw.println(sb);
12830        }
12831        if (mHeavyWeightProcess != null && (dumpPackage == null
12832                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12833            if (needSep) {
12834                pw.println();
12835                needSep = false;
12836            }
12837            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12838        }
12839        if (dumpPackage == null) {
12840            pw.println("  mConfiguration: " + mConfiguration);
12841        }
12842        if (dumpAll) {
12843            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12844            if (mCompatModePackages.getPackages().size() > 0) {
12845                boolean printed = false;
12846                for (Map.Entry<String, Integer> entry
12847                        : mCompatModePackages.getPackages().entrySet()) {
12848                    String pkg = entry.getKey();
12849                    int mode = entry.getValue();
12850                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12851                        continue;
12852                    }
12853                    if (!printed) {
12854                        pw.println("  mScreenCompatPackages:");
12855                        printed = true;
12856                    }
12857                    pw.print("    "); pw.print(pkg); pw.print(": ");
12858                            pw.print(mode); pw.println();
12859                }
12860            }
12861        }
12862        if (dumpPackage == null) {
12863            if (mSleeping || mWentToSleep || mLockScreenShown) {
12864                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12865                        + " mLockScreenShown " + mLockScreenShown);
12866            }
12867            if (mShuttingDown || mRunningVoice) {
12868                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12869            }
12870        }
12871        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12872                || mOrigWaitForDebugger) {
12873            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12874                    || dumpPackage.equals(mOrigDebugApp)) {
12875                if (needSep) {
12876                    pw.println();
12877                    needSep = false;
12878                }
12879                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12880                        + " mDebugTransient=" + mDebugTransient
12881                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12882            }
12883        }
12884        if (mOpenGlTraceApp != null) {
12885            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12886                if (needSep) {
12887                    pw.println();
12888                    needSep = false;
12889                }
12890                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12891            }
12892        }
12893        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12894                || mProfileFd != null) {
12895            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12896                if (needSep) {
12897                    pw.println();
12898                    needSep = false;
12899                }
12900                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12901                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12902                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12903                        + mAutoStopProfiler);
12904                pw.println("  mProfileType=" + mProfileType);
12905            }
12906        }
12907        if (dumpPackage == null) {
12908            if (mAlwaysFinishActivities || mController != null) {
12909                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12910                        + " mController=" + mController);
12911            }
12912            if (dumpAll) {
12913                pw.println("  Total persistent processes: " + numPers);
12914                pw.println("  mProcessesReady=" + mProcessesReady
12915                        + " mSystemReady=" + mSystemReady
12916                        + " mBooted=" + mBooted
12917                        + " mFactoryTest=" + mFactoryTest);
12918                pw.println("  mBooting=" + mBooting
12919                        + " mCallFinishBooting=" + mCallFinishBooting
12920                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12921                pw.print("  mLastPowerCheckRealtime=");
12922                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12923                        pw.println("");
12924                pw.print("  mLastPowerCheckUptime=");
12925                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12926                        pw.println("");
12927                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12928                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12929                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12930                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12931                        + " (" + mLruProcesses.size() + " total)"
12932                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12933                        + " mNumServiceProcs=" + mNumServiceProcs
12934                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12935                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12936                        + " mLastMemoryLevel" + mLastMemoryLevel
12937                        + " mLastNumProcesses" + mLastNumProcesses);
12938                long now = SystemClock.uptimeMillis();
12939                pw.print("  mLastIdleTime=");
12940                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12941                        pw.print(" mLowRamSinceLastIdle=");
12942                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12943                        pw.println();
12944            }
12945        }
12946
12947        if (!printedAnything) {
12948            pw.println("  (nothing)");
12949        }
12950    }
12951
12952    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12953            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12954        if (mProcessesToGc.size() > 0) {
12955            boolean printed = false;
12956            long now = SystemClock.uptimeMillis();
12957            for (int i=0; i<mProcessesToGc.size(); i++) {
12958                ProcessRecord proc = mProcessesToGc.get(i);
12959                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12960                    continue;
12961                }
12962                if (!printed) {
12963                    if (needSep) pw.println();
12964                    needSep = true;
12965                    pw.println("  Processes that are waiting to GC:");
12966                    printed = true;
12967                }
12968                pw.print("    Process "); pw.println(proc);
12969                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12970                        pw.print(", last gced=");
12971                        pw.print(now-proc.lastRequestedGc);
12972                        pw.print(" ms ago, last lowMem=");
12973                        pw.print(now-proc.lastLowMemory);
12974                        pw.println(" ms ago");
12975
12976            }
12977        }
12978        return needSep;
12979    }
12980
12981    void printOomLevel(PrintWriter pw, String name, int adj) {
12982        pw.print("    ");
12983        if (adj >= 0) {
12984            pw.print(' ');
12985            if (adj < 10) pw.print(' ');
12986        } else {
12987            if (adj > -10) pw.print(' ');
12988        }
12989        pw.print(adj);
12990        pw.print(": ");
12991        pw.print(name);
12992        pw.print(" (");
12993        pw.print(mProcessList.getMemLevel(adj)/1024);
12994        pw.println(" kB)");
12995    }
12996
12997    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12998            int opti, boolean dumpAll) {
12999        boolean needSep = false;
13000
13001        if (mLruProcesses.size() > 0) {
13002            if (needSep) pw.println();
13003            needSep = true;
13004            pw.println("  OOM levels:");
13005            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13006            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13007            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13008            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13009            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13010            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13011            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13012            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13013            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13014            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13015            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13016            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13017            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13018
13019            if (needSep) pw.println();
13020            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13021                    pw.print(" total, non-act at ");
13022                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13023                    pw.print(", non-svc at ");
13024                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13025                    pw.println("):");
13026            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13027            needSep = true;
13028        }
13029
13030        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13031
13032        pw.println();
13033        pw.println("  mHomeProcess: " + mHomeProcess);
13034        pw.println("  mPreviousProcess: " + mPreviousProcess);
13035        if (mHeavyWeightProcess != null) {
13036            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13037        }
13038
13039        return true;
13040    }
13041
13042    /**
13043     * There are three ways to call this:
13044     *  - no provider specified: dump all the providers
13045     *  - a flattened component name that matched an existing provider was specified as the
13046     *    first arg: dump that one provider
13047     *  - the first arg isn't the flattened component name of an existing provider:
13048     *    dump all providers whose component contains the first arg as a substring
13049     */
13050    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13051            int opti, boolean dumpAll) {
13052        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13053    }
13054
13055    static class ItemMatcher {
13056        ArrayList<ComponentName> components;
13057        ArrayList<String> strings;
13058        ArrayList<Integer> objects;
13059        boolean all;
13060
13061        ItemMatcher() {
13062            all = true;
13063        }
13064
13065        void build(String name) {
13066            ComponentName componentName = ComponentName.unflattenFromString(name);
13067            if (componentName != null) {
13068                if (components == null) {
13069                    components = new ArrayList<ComponentName>();
13070                }
13071                components.add(componentName);
13072                all = false;
13073            } else {
13074                int objectId = 0;
13075                // Not a '/' separated full component name; maybe an object ID?
13076                try {
13077                    objectId = Integer.parseInt(name, 16);
13078                    if (objects == null) {
13079                        objects = new ArrayList<Integer>();
13080                    }
13081                    objects.add(objectId);
13082                    all = false;
13083                } catch (RuntimeException e) {
13084                    // Not an integer; just do string match.
13085                    if (strings == null) {
13086                        strings = new ArrayList<String>();
13087                    }
13088                    strings.add(name);
13089                    all = false;
13090                }
13091            }
13092        }
13093
13094        int build(String[] args, int opti) {
13095            for (; opti<args.length; opti++) {
13096                String name = args[opti];
13097                if ("--".equals(name)) {
13098                    return opti+1;
13099                }
13100                build(name);
13101            }
13102            return opti;
13103        }
13104
13105        boolean match(Object object, ComponentName comp) {
13106            if (all) {
13107                return true;
13108            }
13109            if (components != null) {
13110                for (int i=0; i<components.size(); i++) {
13111                    if (components.get(i).equals(comp)) {
13112                        return true;
13113                    }
13114                }
13115            }
13116            if (objects != null) {
13117                for (int i=0; i<objects.size(); i++) {
13118                    if (System.identityHashCode(object) == objects.get(i)) {
13119                        return true;
13120                    }
13121                }
13122            }
13123            if (strings != null) {
13124                String flat = comp.flattenToString();
13125                for (int i=0; i<strings.size(); i++) {
13126                    if (flat.contains(strings.get(i))) {
13127                        return true;
13128                    }
13129                }
13130            }
13131            return false;
13132        }
13133    }
13134
13135    /**
13136     * There are three things that cmd can be:
13137     *  - a flattened component name that matches an existing activity
13138     *  - the cmd arg isn't the flattened component name of an existing activity:
13139     *    dump all activity whose component contains the cmd as a substring
13140     *  - A hex number of the ActivityRecord object instance.
13141     */
13142    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13143            int opti, boolean dumpAll) {
13144        ArrayList<ActivityRecord> activities;
13145
13146        synchronized (this) {
13147            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13148        }
13149
13150        if (activities.size() <= 0) {
13151            return false;
13152        }
13153
13154        String[] newArgs = new String[args.length - opti];
13155        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13156
13157        TaskRecord lastTask = null;
13158        boolean needSep = false;
13159        for (int i=activities.size()-1; i>=0; i--) {
13160            ActivityRecord r = activities.get(i);
13161            if (needSep) {
13162                pw.println();
13163            }
13164            needSep = true;
13165            synchronized (this) {
13166                if (lastTask != r.task) {
13167                    lastTask = r.task;
13168                    pw.print("TASK "); pw.print(lastTask.affinity);
13169                            pw.print(" id="); pw.println(lastTask.taskId);
13170                    if (dumpAll) {
13171                        lastTask.dump(pw, "  ");
13172                    }
13173                }
13174            }
13175            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13176        }
13177        return true;
13178    }
13179
13180    /**
13181     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13182     * there is a thread associated with the activity.
13183     */
13184    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13185            final ActivityRecord r, String[] args, boolean dumpAll) {
13186        String innerPrefix = prefix + "  ";
13187        synchronized (this) {
13188            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13189                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13190                    pw.print(" pid=");
13191                    if (r.app != null) pw.println(r.app.pid);
13192                    else pw.println("(not running)");
13193            if (dumpAll) {
13194                r.dump(pw, innerPrefix);
13195            }
13196        }
13197        if (r.app != null && r.app.thread != null) {
13198            // flush anything that is already in the PrintWriter since the thread is going
13199            // to write to the file descriptor directly
13200            pw.flush();
13201            try {
13202                TransferPipe tp = new TransferPipe();
13203                try {
13204                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13205                            r.appToken, innerPrefix, args);
13206                    tp.go(fd);
13207                } finally {
13208                    tp.kill();
13209                }
13210            } catch (IOException e) {
13211                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13212            } catch (RemoteException e) {
13213                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13214            }
13215        }
13216    }
13217
13218    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13219            int opti, boolean dumpAll, String dumpPackage) {
13220        boolean needSep = false;
13221        boolean onlyHistory = false;
13222        boolean printedAnything = false;
13223
13224        if ("history".equals(dumpPackage)) {
13225            if (opti < args.length && "-s".equals(args[opti])) {
13226                dumpAll = false;
13227            }
13228            onlyHistory = true;
13229            dumpPackage = null;
13230        }
13231
13232        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13233        if (!onlyHistory && dumpAll) {
13234            if (mRegisteredReceivers.size() > 0) {
13235                boolean printed = false;
13236                Iterator it = mRegisteredReceivers.values().iterator();
13237                while (it.hasNext()) {
13238                    ReceiverList r = (ReceiverList)it.next();
13239                    if (dumpPackage != null && (r.app == null ||
13240                            !dumpPackage.equals(r.app.info.packageName))) {
13241                        continue;
13242                    }
13243                    if (!printed) {
13244                        pw.println("  Registered Receivers:");
13245                        needSep = true;
13246                        printed = true;
13247                        printedAnything = true;
13248                    }
13249                    pw.print("  * "); pw.println(r);
13250                    r.dump(pw, "    ");
13251                }
13252            }
13253
13254            if (mReceiverResolver.dump(pw, needSep ?
13255                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13256                    "    ", dumpPackage, false)) {
13257                needSep = true;
13258                printedAnything = true;
13259            }
13260        }
13261
13262        for (BroadcastQueue q : mBroadcastQueues) {
13263            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13264            printedAnything |= needSep;
13265        }
13266
13267        needSep = true;
13268
13269        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13270            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13271                if (needSep) {
13272                    pw.println();
13273                }
13274                needSep = true;
13275                printedAnything = true;
13276                pw.print("  Sticky broadcasts for user ");
13277                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13278                StringBuilder sb = new StringBuilder(128);
13279                for (Map.Entry<String, ArrayList<Intent>> ent
13280                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13281                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13282                    if (dumpAll) {
13283                        pw.println(":");
13284                        ArrayList<Intent> intents = ent.getValue();
13285                        final int N = intents.size();
13286                        for (int i=0; i<N; i++) {
13287                            sb.setLength(0);
13288                            sb.append("    Intent: ");
13289                            intents.get(i).toShortString(sb, false, true, false, false);
13290                            pw.println(sb.toString());
13291                            Bundle bundle = intents.get(i).getExtras();
13292                            if (bundle != null) {
13293                                pw.print("      ");
13294                                pw.println(bundle.toString());
13295                            }
13296                        }
13297                    } else {
13298                        pw.println("");
13299                    }
13300                }
13301            }
13302        }
13303
13304        if (!onlyHistory && dumpAll) {
13305            pw.println();
13306            for (BroadcastQueue queue : mBroadcastQueues) {
13307                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13308                        + queue.mBroadcastsScheduled);
13309            }
13310            pw.println("  mHandler:");
13311            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13312            needSep = true;
13313            printedAnything = true;
13314        }
13315
13316        if (!printedAnything) {
13317            pw.println("  (nothing)");
13318        }
13319    }
13320
13321    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13322            int opti, boolean dumpAll, String dumpPackage) {
13323        boolean needSep;
13324        boolean printedAnything = false;
13325
13326        ItemMatcher matcher = new ItemMatcher();
13327        matcher.build(args, opti);
13328
13329        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13330
13331        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13332        printedAnything |= needSep;
13333
13334        if (mLaunchingProviders.size() > 0) {
13335            boolean printed = false;
13336            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13337                ContentProviderRecord r = mLaunchingProviders.get(i);
13338                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13339                    continue;
13340                }
13341                if (!printed) {
13342                    if (needSep) pw.println();
13343                    needSep = true;
13344                    pw.println("  Launching content providers:");
13345                    printed = true;
13346                    printedAnything = true;
13347                }
13348                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13349                        pw.println(r);
13350            }
13351        }
13352
13353        if (mGrantedUriPermissions.size() > 0) {
13354            boolean printed = false;
13355            int dumpUid = -2;
13356            if (dumpPackage != null) {
13357                try {
13358                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13359                } catch (NameNotFoundException e) {
13360                    dumpUid = -1;
13361                }
13362            }
13363            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13364                int uid = mGrantedUriPermissions.keyAt(i);
13365                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13366                    continue;
13367                }
13368                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13369                if (!printed) {
13370                    if (needSep) pw.println();
13371                    needSep = true;
13372                    pw.println("  Granted Uri Permissions:");
13373                    printed = true;
13374                    printedAnything = true;
13375                }
13376                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13377                for (UriPermission perm : perms.values()) {
13378                    pw.print("    "); pw.println(perm);
13379                    if (dumpAll) {
13380                        perm.dump(pw, "      ");
13381                    }
13382                }
13383            }
13384        }
13385
13386        if (!printedAnything) {
13387            pw.println("  (nothing)");
13388        }
13389    }
13390
13391    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13392            int opti, boolean dumpAll, String dumpPackage) {
13393        boolean printed = false;
13394
13395        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13396
13397        if (mIntentSenderRecords.size() > 0) {
13398            Iterator<WeakReference<PendingIntentRecord>> it
13399                    = mIntentSenderRecords.values().iterator();
13400            while (it.hasNext()) {
13401                WeakReference<PendingIntentRecord> ref = it.next();
13402                PendingIntentRecord rec = ref != null ? ref.get(): null;
13403                if (dumpPackage != null && (rec == null
13404                        || !dumpPackage.equals(rec.key.packageName))) {
13405                    continue;
13406                }
13407                printed = true;
13408                if (rec != null) {
13409                    pw.print("  * "); pw.println(rec);
13410                    if (dumpAll) {
13411                        rec.dump(pw, "    ");
13412                    }
13413                } else {
13414                    pw.print("  * "); pw.println(ref);
13415                }
13416            }
13417        }
13418
13419        if (!printed) {
13420            pw.println("  (nothing)");
13421        }
13422    }
13423
13424    private static final int dumpProcessList(PrintWriter pw,
13425            ActivityManagerService service, List list,
13426            String prefix, String normalLabel, String persistentLabel,
13427            String dumpPackage) {
13428        int numPers = 0;
13429        final int N = list.size()-1;
13430        for (int i=N; i>=0; i--) {
13431            ProcessRecord r = (ProcessRecord)list.get(i);
13432            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13433                continue;
13434            }
13435            pw.println(String.format("%s%s #%2d: %s",
13436                    prefix, (r.persistent ? persistentLabel : normalLabel),
13437                    i, r.toString()));
13438            if (r.persistent) {
13439                numPers++;
13440            }
13441        }
13442        return numPers;
13443    }
13444
13445    private static final boolean dumpProcessOomList(PrintWriter pw,
13446            ActivityManagerService service, List<ProcessRecord> origList,
13447            String prefix, String normalLabel, String persistentLabel,
13448            boolean inclDetails, String dumpPackage) {
13449
13450        ArrayList<Pair<ProcessRecord, Integer>> list
13451                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13452        for (int i=0; i<origList.size(); i++) {
13453            ProcessRecord r = origList.get(i);
13454            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13455                continue;
13456            }
13457            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13458        }
13459
13460        if (list.size() <= 0) {
13461            return false;
13462        }
13463
13464        Comparator<Pair<ProcessRecord, Integer>> comparator
13465                = new Comparator<Pair<ProcessRecord, Integer>>() {
13466            @Override
13467            public int compare(Pair<ProcessRecord, Integer> object1,
13468                    Pair<ProcessRecord, Integer> object2) {
13469                if (object1.first.setAdj != object2.first.setAdj) {
13470                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13471                }
13472                if (object1.second.intValue() != object2.second.intValue()) {
13473                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13474                }
13475                return 0;
13476            }
13477        };
13478
13479        Collections.sort(list, comparator);
13480
13481        final long curRealtime = SystemClock.elapsedRealtime();
13482        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13483        final long curUptime = SystemClock.uptimeMillis();
13484        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13485
13486        for (int i=list.size()-1; i>=0; i--) {
13487            ProcessRecord r = list.get(i).first;
13488            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13489            char schedGroup;
13490            switch (r.setSchedGroup) {
13491                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13492                    schedGroup = 'B';
13493                    break;
13494                case Process.THREAD_GROUP_DEFAULT:
13495                    schedGroup = 'F';
13496                    break;
13497                default:
13498                    schedGroup = '?';
13499                    break;
13500            }
13501            char foreground;
13502            if (r.foregroundActivities) {
13503                foreground = 'A';
13504            } else if (r.foregroundServices) {
13505                foreground = 'S';
13506            } else {
13507                foreground = ' ';
13508            }
13509            String procState = ProcessList.makeProcStateString(r.curProcState);
13510            pw.print(prefix);
13511            pw.print(r.persistent ? persistentLabel : normalLabel);
13512            pw.print(" #");
13513            int num = (origList.size()-1)-list.get(i).second;
13514            if (num < 10) pw.print(' ');
13515            pw.print(num);
13516            pw.print(": ");
13517            pw.print(oomAdj);
13518            pw.print(' ');
13519            pw.print(schedGroup);
13520            pw.print('/');
13521            pw.print(foreground);
13522            pw.print('/');
13523            pw.print(procState);
13524            pw.print(" trm:");
13525            if (r.trimMemoryLevel < 10) pw.print(' ');
13526            pw.print(r.trimMemoryLevel);
13527            pw.print(' ');
13528            pw.print(r.toShortString());
13529            pw.print(" (");
13530            pw.print(r.adjType);
13531            pw.println(')');
13532            if (r.adjSource != null || r.adjTarget != null) {
13533                pw.print(prefix);
13534                pw.print("    ");
13535                if (r.adjTarget instanceof ComponentName) {
13536                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13537                } else if (r.adjTarget != null) {
13538                    pw.print(r.adjTarget.toString());
13539                } else {
13540                    pw.print("{null}");
13541                }
13542                pw.print("<=");
13543                if (r.adjSource instanceof ProcessRecord) {
13544                    pw.print("Proc{");
13545                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13546                    pw.println("}");
13547                } else if (r.adjSource != null) {
13548                    pw.println(r.adjSource.toString());
13549                } else {
13550                    pw.println("{null}");
13551                }
13552            }
13553            if (inclDetails) {
13554                pw.print(prefix);
13555                pw.print("    ");
13556                pw.print("oom: max="); pw.print(r.maxAdj);
13557                pw.print(" curRaw="); pw.print(r.curRawAdj);
13558                pw.print(" setRaw="); pw.print(r.setRawAdj);
13559                pw.print(" cur="); pw.print(r.curAdj);
13560                pw.print(" set="); pw.println(r.setAdj);
13561                pw.print(prefix);
13562                pw.print("    ");
13563                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13564                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13565                pw.print(" lastPss="); pw.print(r.lastPss);
13566                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13567                pw.print(prefix);
13568                pw.print("    ");
13569                pw.print("cached="); pw.print(r.cached);
13570                pw.print(" empty="); pw.print(r.empty);
13571                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13572
13573                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13574                    if (r.lastWakeTime != 0) {
13575                        long wtime;
13576                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13577                        synchronized (stats) {
13578                            wtime = stats.getProcessWakeTime(r.info.uid,
13579                                    r.pid, curRealtime);
13580                        }
13581                        long timeUsed = wtime - r.lastWakeTime;
13582                        pw.print(prefix);
13583                        pw.print("    ");
13584                        pw.print("keep awake over ");
13585                        TimeUtils.formatDuration(realtimeSince, pw);
13586                        pw.print(" used ");
13587                        TimeUtils.formatDuration(timeUsed, pw);
13588                        pw.print(" (");
13589                        pw.print((timeUsed*100)/realtimeSince);
13590                        pw.println("%)");
13591                    }
13592                    if (r.lastCpuTime != 0) {
13593                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13594                        pw.print(prefix);
13595                        pw.print("    ");
13596                        pw.print("run cpu over ");
13597                        TimeUtils.formatDuration(uptimeSince, pw);
13598                        pw.print(" used ");
13599                        TimeUtils.formatDuration(timeUsed, pw);
13600                        pw.print(" (");
13601                        pw.print((timeUsed*100)/uptimeSince);
13602                        pw.println("%)");
13603                    }
13604                }
13605            }
13606        }
13607        return true;
13608    }
13609
13610    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13611        ArrayList<ProcessRecord> procs;
13612        synchronized (this) {
13613            if (args != null && args.length > start
13614                    && args[start].charAt(0) != '-') {
13615                procs = new ArrayList<ProcessRecord>();
13616                int pid = -1;
13617                try {
13618                    pid = Integer.parseInt(args[start]);
13619                } catch (NumberFormatException e) {
13620                }
13621                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13622                    ProcessRecord proc = mLruProcesses.get(i);
13623                    if (proc.pid == pid) {
13624                        procs.add(proc);
13625                    } else if (proc.processName.equals(args[start])) {
13626                        procs.add(proc);
13627                    }
13628                }
13629                if (procs.size() <= 0) {
13630                    return null;
13631                }
13632            } else {
13633                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13634            }
13635        }
13636        return procs;
13637    }
13638
13639    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13640            PrintWriter pw, String[] args) {
13641        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13642        if (procs == null) {
13643            pw.println("No process found for: " + args[0]);
13644            return;
13645        }
13646
13647        long uptime = SystemClock.uptimeMillis();
13648        long realtime = SystemClock.elapsedRealtime();
13649        pw.println("Applications Graphics Acceleration Info:");
13650        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13651
13652        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13653            ProcessRecord r = procs.get(i);
13654            if (r.thread != null) {
13655                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13656                pw.flush();
13657                try {
13658                    TransferPipe tp = new TransferPipe();
13659                    try {
13660                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13661                        tp.go(fd);
13662                    } finally {
13663                        tp.kill();
13664                    }
13665                } catch (IOException e) {
13666                    pw.println("Failure while dumping the app: " + r);
13667                    pw.flush();
13668                } catch (RemoteException e) {
13669                    pw.println("Got a RemoteException while dumping the app " + r);
13670                    pw.flush();
13671                }
13672            }
13673        }
13674    }
13675
13676    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13677        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13678        if (procs == null) {
13679            pw.println("No process found for: " + args[0]);
13680            return;
13681        }
13682
13683        pw.println("Applications Database Info:");
13684
13685        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13686            ProcessRecord r = procs.get(i);
13687            if (r.thread != null) {
13688                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13689                pw.flush();
13690                try {
13691                    TransferPipe tp = new TransferPipe();
13692                    try {
13693                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13694                        tp.go(fd);
13695                    } finally {
13696                        tp.kill();
13697                    }
13698                } catch (IOException e) {
13699                    pw.println("Failure while dumping the app: " + r);
13700                    pw.flush();
13701                } catch (RemoteException e) {
13702                    pw.println("Got a RemoteException while dumping the app " + r);
13703                    pw.flush();
13704                }
13705            }
13706        }
13707    }
13708
13709    final static class MemItem {
13710        final boolean isProc;
13711        final String label;
13712        final String shortLabel;
13713        final long pss;
13714        final int id;
13715        final boolean hasActivities;
13716        ArrayList<MemItem> subitems;
13717
13718        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13719                boolean _hasActivities) {
13720            isProc = true;
13721            label = _label;
13722            shortLabel = _shortLabel;
13723            pss = _pss;
13724            id = _id;
13725            hasActivities = _hasActivities;
13726        }
13727
13728        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13729            isProc = false;
13730            label = _label;
13731            shortLabel = _shortLabel;
13732            pss = _pss;
13733            id = _id;
13734            hasActivities = false;
13735        }
13736    }
13737
13738    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13739            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13740        if (sort && !isCompact) {
13741            Collections.sort(items, new Comparator<MemItem>() {
13742                @Override
13743                public int compare(MemItem lhs, MemItem rhs) {
13744                    if (lhs.pss < rhs.pss) {
13745                        return 1;
13746                    } else if (lhs.pss > rhs.pss) {
13747                        return -1;
13748                    }
13749                    return 0;
13750                }
13751            });
13752        }
13753
13754        for (int i=0; i<items.size(); i++) {
13755            MemItem mi = items.get(i);
13756            if (!isCompact) {
13757                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13758            } else if (mi.isProc) {
13759                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13760                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13761                pw.println(mi.hasActivities ? ",a" : ",e");
13762            } else {
13763                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13764                pw.println(mi.pss);
13765            }
13766            if (mi.subitems != null) {
13767                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13768                        true, isCompact);
13769            }
13770        }
13771    }
13772
13773    // These are in KB.
13774    static final long[] DUMP_MEM_BUCKETS = new long[] {
13775        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13776        120*1024, 160*1024, 200*1024,
13777        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13778        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13779    };
13780
13781    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13782            boolean stackLike) {
13783        int start = label.lastIndexOf('.');
13784        if (start >= 0) start++;
13785        else start = 0;
13786        int end = label.length();
13787        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13788            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13789                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13790                out.append(bucket);
13791                out.append(stackLike ? "MB." : "MB ");
13792                out.append(label, start, end);
13793                return;
13794            }
13795        }
13796        out.append(memKB/1024);
13797        out.append(stackLike ? "MB." : "MB ");
13798        out.append(label, start, end);
13799    }
13800
13801    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13802            ProcessList.NATIVE_ADJ,
13803            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13804            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13805            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13806            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13807            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13808    };
13809    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13810            "Native",
13811            "System", "Persistent", "Foreground",
13812            "Visible", "Perceptible",
13813            "Heavy Weight", "Backup",
13814            "A Services", "Home",
13815            "Previous", "B Services", "Cached"
13816    };
13817    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13818            "native",
13819            "sys", "pers", "fore",
13820            "vis", "percept",
13821            "heavy", "backup",
13822            "servicea", "home",
13823            "prev", "serviceb", "cached"
13824    };
13825
13826    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13827            long realtime, boolean isCheckinRequest, boolean isCompact) {
13828        if (isCheckinRequest || isCompact) {
13829            // short checkin version
13830            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13831        } else {
13832            pw.println("Applications Memory Usage (kB):");
13833            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13834        }
13835    }
13836
13837    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13838            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13839        boolean dumpDetails = false;
13840        boolean dumpFullDetails = false;
13841        boolean dumpDalvik = false;
13842        boolean oomOnly = false;
13843        boolean isCompact = false;
13844        boolean localOnly = false;
13845
13846        int opti = 0;
13847        while (opti < args.length) {
13848            String opt = args[opti];
13849            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13850                break;
13851            }
13852            opti++;
13853            if ("-a".equals(opt)) {
13854                dumpDetails = true;
13855                dumpFullDetails = true;
13856                dumpDalvik = true;
13857            } else if ("-d".equals(opt)) {
13858                dumpDalvik = true;
13859            } else if ("-c".equals(opt)) {
13860                isCompact = true;
13861            } else if ("--oom".equals(opt)) {
13862                oomOnly = true;
13863            } else if ("--local".equals(opt)) {
13864                localOnly = true;
13865            } else if ("-h".equals(opt)) {
13866                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13867                pw.println("  -a: include all available information for each process.");
13868                pw.println("  -d: include dalvik details when dumping process details.");
13869                pw.println("  -c: dump in a compact machine-parseable representation.");
13870                pw.println("  --oom: only show processes organized by oom adj.");
13871                pw.println("  --local: only collect details locally, don't call process.");
13872                pw.println("If [process] is specified it can be the name or ");
13873                pw.println("pid of a specific process to dump.");
13874                return;
13875            } else {
13876                pw.println("Unknown argument: " + opt + "; use -h for help");
13877            }
13878        }
13879
13880        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13881        long uptime = SystemClock.uptimeMillis();
13882        long realtime = SystemClock.elapsedRealtime();
13883        final long[] tmpLong = new long[1];
13884
13885        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13886        if (procs == null) {
13887            // No Java processes.  Maybe they want to print a native process.
13888            if (args != null && args.length > opti
13889                    && args[opti].charAt(0) != '-') {
13890                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13891                        = new ArrayList<ProcessCpuTracker.Stats>();
13892                updateCpuStatsNow();
13893                int findPid = -1;
13894                try {
13895                    findPid = Integer.parseInt(args[opti]);
13896                } catch (NumberFormatException e) {
13897                }
13898                synchronized (mProcessCpuTracker) {
13899                    final int N = mProcessCpuTracker.countStats();
13900                    for (int i=0; i<N; i++) {
13901                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13902                        if (st.pid == findPid || (st.baseName != null
13903                                && st.baseName.equals(args[opti]))) {
13904                            nativeProcs.add(st);
13905                        }
13906                    }
13907                }
13908                if (nativeProcs.size() > 0) {
13909                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13910                            isCompact);
13911                    Debug.MemoryInfo mi = null;
13912                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13913                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13914                        final int pid = r.pid;
13915                        if (!isCheckinRequest && dumpDetails) {
13916                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13917                        }
13918                        if (mi == null) {
13919                            mi = new Debug.MemoryInfo();
13920                        }
13921                        if (dumpDetails || (!brief && !oomOnly)) {
13922                            Debug.getMemoryInfo(pid, mi);
13923                        } else {
13924                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13925                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13926                        }
13927                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13928                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13929                        if (isCheckinRequest) {
13930                            pw.println();
13931                        }
13932                    }
13933                    return;
13934                }
13935            }
13936            pw.println("No process found for: " + args[opti]);
13937            return;
13938        }
13939
13940        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13941            dumpDetails = true;
13942        }
13943
13944        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13945
13946        String[] innerArgs = new String[args.length-opti];
13947        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13948
13949        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13950        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13951        long nativePss=0, dalvikPss=0, otherPss=0;
13952        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13953
13954        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13955        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13956                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13957
13958        long totalPss = 0;
13959        long cachedPss = 0;
13960
13961        Debug.MemoryInfo mi = null;
13962        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13963            final ProcessRecord r = procs.get(i);
13964            final IApplicationThread thread;
13965            final int pid;
13966            final int oomAdj;
13967            final boolean hasActivities;
13968            synchronized (this) {
13969                thread = r.thread;
13970                pid = r.pid;
13971                oomAdj = r.getSetAdjWithServices();
13972                hasActivities = r.activities.size() > 0;
13973            }
13974            if (thread != null) {
13975                if (!isCheckinRequest && dumpDetails) {
13976                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13977                }
13978                if (mi == null) {
13979                    mi = new Debug.MemoryInfo();
13980                }
13981                if (dumpDetails || (!brief && !oomOnly)) {
13982                    Debug.getMemoryInfo(pid, mi);
13983                } else {
13984                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13985                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13986                }
13987                if (dumpDetails) {
13988                    if (localOnly) {
13989                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13990                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13991                        if (isCheckinRequest) {
13992                            pw.println();
13993                        }
13994                    } else {
13995                        try {
13996                            pw.flush();
13997                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13998                                    dumpDalvik, innerArgs);
13999                        } catch (RemoteException e) {
14000                            if (!isCheckinRequest) {
14001                                pw.println("Got RemoteException!");
14002                                pw.flush();
14003                            }
14004                        }
14005                    }
14006                }
14007
14008                final long myTotalPss = mi.getTotalPss();
14009                final long myTotalUss = mi.getTotalUss();
14010
14011                synchronized (this) {
14012                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14013                        // Record this for posterity if the process has been stable.
14014                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14015                    }
14016                }
14017
14018                if (!isCheckinRequest && mi != null) {
14019                    totalPss += myTotalPss;
14020                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14021                            (hasActivities ? " / activities)" : ")"),
14022                            r.processName, myTotalPss, pid, hasActivities);
14023                    procMems.add(pssItem);
14024                    procMemsMap.put(pid, pssItem);
14025
14026                    nativePss += mi.nativePss;
14027                    dalvikPss += mi.dalvikPss;
14028                    otherPss += mi.otherPss;
14029                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14030                        long mem = mi.getOtherPss(j);
14031                        miscPss[j] += mem;
14032                        otherPss -= mem;
14033                    }
14034
14035                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14036                        cachedPss += myTotalPss;
14037                    }
14038
14039                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14040                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14041                                || oomIndex == (oomPss.length-1)) {
14042                            oomPss[oomIndex] += myTotalPss;
14043                            if (oomProcs[oomIndex] == null) {
14044                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14045                            }
14046                            oomProcs[oomIndex].add(pssItem);
14047                            break;
14048                        }
14049                    }
14050                }
14051            }
14052        }
14053
14054        long nativeProcTotalPss = 0;
14055
14056        if (!isCheckinRequest && procs.size() > 1) {
14057            // If we are showing aggregations, also look for native processes to
14058            // include so that our aggregations are more accurate.
14059            updateCpuStatsNow();
14060            synchronized (mProcessCpuTracker) {
14061                final int N = mProcessCpuTracker.countStats();
14062                for (int i=0; i<N; i++) {
14063                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14064                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14065                        if (mi == null) {
14066                            mi = new Debug.MemoryInfo();
14067                        }
14068                        if (!brief && !oomOnly) {
14069                            Debug.getMemoryInfo(st.pid, mi);
14070                        } else {
14071                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14072                            mi.nativePrivateDirty = (int)tmpLong[0];
14073                        }
14074
14075                        final long myTotalPss = mi.getTotalPss();
14076                        totalPss += myTotalPss;
14077                        nativeProcTotalPss += myTotalPss;
14078
14079                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14080                                st.name, myTotalPss, st.pid, false);
14081                        procMems.add(pssItem);
14082
14083                        nativePss += mi.nativePss;
14084                        dalvikPss += mi.dalvikPss;
14085                        otherPss += mi.otherPss;
14086                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14087                            long mem = mi.getOtherPss(j);
14088                            miscPss[j] += mem;
14089                            otherPss -= mem;
14090                        }
14091                        oomPss[0] += myTotalPss;
14092                        if (oomProcs[0] == null) {
14093                            oomProcs[0] = new ArrayList<MemItem>();
14094                        }
14095                        oomProcs[0].add(pssItem);
14096                    }
14097                }
14098            }
14099
14100            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14101
14102            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14103            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14104            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14105            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14106                String label = Debug.MemoryInfo.getOtherLabel(j);
14107                catMems.add(new MemItem(label, label, miscPss[j], j));
14108            }
14109
14110            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14111            for (int j=0; j<oomPss.length; j++) {
14112                if (oomPss[j] != 0) {
14113                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14114                            : DUMP_MEM_OOM_LABEL[j];
14115                    MemItem item = new MemItem(label, label, oomPss[j],
14116                            DUMP_MEM_OOM_ADJ[j]);
14117                    item.subitems = oomProcs[j];
14118                    oomMems.add(item);
14119                }
14120            }
14121
14122            if (!brief && !oomOnly && !isCompact) {
14123                pw.println();
14124                pw.println("Total PSS by process:");
14125                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14126                pw.println();
14127            }
14128            if (!isCompact) {
14129                pw.println("Total PSS by OOM adjustment:");
14130            }
14131            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14132            if (!brief && !oomOnly) {
14133                PrintWriter out = categoryPw != null ? categoryPw : pw;
14134                if (!isCompact) {
14135                    out.println();
14136                    out.println("Total PSS by category:");
14137                }
14138                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14139            }
14140            if (!isCompact) {
14141                pw.println();
14142            }
14143            MemInfoReader memInfo = new MemInfoReader();
14144            memInfo.readMemInfo();
14145            if (nativeProcTotalPss > 0) {
14146                synchronized (this) {
14147                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14148                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14149                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14150                            nativeProcTotalPss);
14151                }
14152            }
14153            if (!brief) {
14154                if (!isCompact) {
14155                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14156                    pw.print(" kB (status ");
14157                    switch (mLastMemoryLevel) {
14158                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14159                            pw.println("normal)");
14160                            break;
14161                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14162                            pw.println("moderate)");
14163                            break;
14164                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14165                            pw.println("low)");
14166                            break;
14167                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14168                            pw.println("critical)");
14169                            break;
14170                        default:
14171                            pw.print(mLastMemoryLevel);
14172                            pw.println(")");
14173                            break;
14174                    }
14175                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14176                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14177                            pw.print(cachedPss); pw.print(" cached pss + ");
14178                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14179                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14180                } else {
14181                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14182                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14183                            + memInfo.getFreeSizeKb()); pw.print(",");
14184                    pw.println(totalPss - cachedPss);
14185                }
14186            }
14187            if (!isCompact) {
14188                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14189                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14190                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14191                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14192                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14193                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14194                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14195                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14196                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14197                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14198                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14199            }
14200            if (!brief) {
14201                if (memInfo.getZramTotalSizeKb() != 0) {
14202                    if (!isCompact) {
14203                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14204                                pw.print(" kB physical used for ");
14205                                pw.print(memInfo.getSwapTotalSizeKb()
14206                                        - memInfo.getSwapFreeSizeKb());
14207                                pw.print(" kB in swap (");
14208                                pw.print(memInfo.getSwapTotalSizeKb());
14209                                pw.println(" kB total swap)");
14210                    } else {
14211                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14212                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14213                                pw.println(memInfo.getSwapFreeSizeKb());
14214                    }
14215                }
14216                final int[] SINGLE_LONG_FORMAT = new int[] {
14217                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14218                };
14219                long[] longOut = new long[1];
14220                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14221                        SINGLE_LONG_FORMAT, null, longOut, null);
14222                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14223                longOut[0] = 0;
14224                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14225                        SINGLE_LONG_FORMAT, null, longOut, null);
14226                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14227                longOut[0] = 0;
14228                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14229                        SINGLE_LONG_FORMAT, null, longOut, null);
14230                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14231                longOut[0] = 0;
14232                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14233                        SINGLE_LONG_FORMAT, null, longOut, null);
14234                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14235                if (!isCompact) {
14236                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14237                        pw.print("      KSM: "); pw.print(sharing);
14238                                pw.print(" kB saved from shared ");
14239                                pw.print(shared); pw.println(" kB");
14240                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14241                                pw.print(voltile); pw.println(" kB volatile");
14242                    }
14243                    pw.print("   Tuning: ");
14244                    pw.print(ActivityManager.staticGetMemoryClass());
14245                    pw.print(" (large ");
14246                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14247                    pw.print("), oom ");
14248                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14249                    pw.print(" kB");
14250                    pw.print(", restore limit ");
14251                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14252                    pw.print(" kB");
14253                    if (ActivityManager.isLowRamDeviceStatic()) {
14254                        pw.print(" (low-ram)");
14255                    }
14256                    if (ActivityManager.isHighEndGfx()) {
14257                        pw.print(" (high-end-gfx)");
14258                    }
14259                    pw.println();
14260                } else {
14261                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14262                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14263                    pw.println(voltile);
14264                    pw.print("tuning,");
14265                    pw.print(ActivityManager.staticGetMemoryClass());
14266                    pw.print(',');
14267                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14268                    pw.print(',');
14269                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14270                    if (ActivityManager.isLowRamDeviceStatic()) {
14271                        pw.print(",low-ram");
14272                    }
14273                    if (ActivityManager.isHighEndGfx()) {
14274                        pw.print(",high-end-gfx");
14275                    }
14276                    pw.println();
14277                }
14278            }
14279        }
14280    }
14281
14282    /**
14283     * Searches array of arguments for the specified string
14284     * @param args array of argument strings
14285     * @param value value to search for
14286     * @return true if the value is contained in the array
14287     */
14288    private static boolean scanArgs(String[] args, String value) {
14289        if (args != null) {
14290            for (String arg : args) {
14291                if (value.equals(arg)) {
14292                    return true;
14293                }
14294            }
14295        }
14296        return false;
14297    }
14298
14299    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14300            ContentProviderRecord cpr, boolean always) {
14301        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14302
14303        if (!inLaunching || always) {
14304            synchronized (cpr) {
14305                cpr.launchingApp = null;
14306                cpr.notifyAll();
14307            }
14308            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14309            String names[] = cpr.info.authority.split(";");
14310            for (int j = 0; j < names.length; j++) {
14311                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14312            }
14313        }
14314
14315        for (int i=0; i<cpr.connections.size(); i++) {
14316            ContentProviderConnection conn = cpr.connections.get(i);
14317            if (conn.waiting) {
14318                // If this connection is waiting for the provider, then we don't
14319                // need to mess with its process unless we are always removing
14320                // or for some reason the provider is not currently launching.
14321                if (inLaunching && !always) {
14322                    continue;
14323                }
14324            }
14325            ProcessRecord capp = conn.client;
14326            conn.dead = true;
14327            if (conn.stableCount > 0) {
14328                if (!capp.persistent && capp.thread != null
14329                        && capp.pid != 0
14330                        && capp.pid != MY_PID) {
14331                    capp.kill("depends on provider "
14332                            + cpr.name.flattenToShortString()
14333                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14334                }
14335            } else if (capp.thread != null && conn.provider.provider != null) {
14336                try {
14337                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14338                } catch (RemoteException e) {
14339                }
14340                // In the protocol here, we don't expect the client to correctly
14341                // clean up this connection, we'll just remove it.
14342                cpr.connections.remove(i);
14343                conn.client.conProviders.remove(conn);
14344            }
14345        }
14346
14347        if (inLaunching && always) {
14348            mLaunchingProviders.remove(cpr);
14349        }
14350        return inLaunching;
14351    }
14352
14353    /**
14354     * Main code for cleaning up a process when it has gone away.  This is
14355     * called both as a result of the process dying, or directly when stopping
14356     * a process when running in single process mode.
14357     *
14358     * @return Returns true if the given process has been restarted, so the
14359     * app that was passed in must remain on the process lists.
14360     */
14361    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14362            boolean restarting, boolean allowRestart, int index) {
14363        if (index >= 0) {
14364            removeLruProcessLocked(app);
14365            ProcessList.remove(app.pid);
14366        }
14367
14368        mProcessesToGc.remove(app);
14369        mPendingPssProcesses.remove(app);
14370
14371        // Dismiss any open dialogs.
14372        if (app.crashDialog != null && !app.forceCrashReport) {
14373            app.crashDialog.dismiss();
14374            app.crashDialog = null;
14375        }
14376        if (app.anrDialog != null) {
14377            app.anrDialog.dismiss();
14378            app.anrDialog = null;
14379        }
14380        if (app.waitDialog != null) {
14381            app.waitDialog.dismiss();
14382            app.waitDialog = null;
14383        }
14384
14385        app.crashing = false;
14386        app.notResponding = false;
14387
14388        app.resetPackageList(mProcessStats);
14389        app.unlinkDeathRecipient();
14390        app.makeInactive(mProcessStats);
14391        app.waitingToKill = null;
14392        app.forcingToForeground = null;
14393        updateProcessForegroundLocked(app, false, false);
14394        app.foregroundActivities = false;
14395        app.hasShownUi = false;
14396        app.treatLikeActivity = false;
14397        app.hasAboveClient = false;
14398        app.hasClientActivities = false;
14399
14400        mServices.killServicesLocked(app, allowRestart);
14401
14402        boolean restart = false;
14403
14404        // Remove published content providers.
14405        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14406            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14407            final boolean always = app.bad || !allowRestart;
14408            if (removeDyingProviderLocked(app, cpr, always) || always) {
14409                // We left the provider in the launching list, need to
14410                // restart it.
14411                restart = true;
14412            }
14413
14414            cpr.provider = null;
14415            cpr.proc = null;
14416        }
14417        app.pubProviders.clear();
14418
14419        // Take care of any launching providers waiting for this process.
14420        if (checkAppInLaunchingProvidersLocked(app, false)) {
14421            restart = true;
14422        }
14423
14424        // Unregister from connected content providers.
14425        if (!app.conProviders.isEmpty()) {
14426            for (int i=0; i<app.conProviders.size(); i++) {
14427                ContentProviderConnection conn = app.conProviders.get(i);
14428                conn.provider.connections.remove(conn);
14429            }
14430            app.conProviders.clear();
14431        }
14432
14433        // At this point there may be remaining entries in mLaunchingProviders
14434        // where we were the only one waiting, so they are no longer of use.
14435        // Look for these and clean up if found.
14436        // XXX Commented out for now.  Trying to figure out a way to reproduce
14437        // the actual situation to identify what is actually going on.
14438        if (false) {
14439            for (int i=0; i<mLaunchingProviders.size(); i++) {
14440                ContentProviderRecord cpr = (ContentProviderRecord)
14441                        mLaunchingProviders.get(i);
14442                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14443                    synchronized (cpr) {
14444                        cpr.launchingApp = null;
14445                        cpr.notifyAll();
14446                    }
14447                }
14448            }
14449        }
14450
14451        skipCurrentReceiverLocked(app);
14452
14453        // Unregister any receivers.
14454        for (int i=app.receivers.size()-1; i>=0; i--) {
14455            removeReceiverLocked(app.receivers.valueAt(i));
14456        }
14457        app.receivers.clear();
14458
14459        // If the app is undergoing backup, tell the backup manager about it
14460        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14461            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14462                    + mBackupTarget.appInfo + " died during backup");
14463            try {
14464                IBackupManager bm = IBackupManager.Stub.asInterface(
14465                        ServiceManager.getService(Context.BACKUP_SERVICE));
14466                bm.agentDisconnected(app.info.packageName);
14467            } catch (RemoteException e) {
14468                // can't happen; backup manager is local
14469            }
14470        }
14471
14472        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14473            ProcessChangeItem item = mPendingProcessChanges.get(i);
14474            if (item.pid == app.pid) {
14475                mPendingProcessChanges.remove(i);
14476                mAvailProcessChanges.add(item);
14477            }
14478        }
14479        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14480
14481        // If the caller is restarting this app, then leave it in its
14482        // current lists and let the caller take care of it.
14483        if (restarting) {
14484            return false;
14485        }
14486
14487        if (!app.persistent || app.isolated) {
14488            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14489                    "Removing non-persistent process during cleanup: " + app);
14490            mProcessNames.remove(app.processName, app.uid);
14491            mIsolatedProcesses.remove(app.uid);
14492            if (mHeavyWeightProcess == app) {
14493                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14494                        mHeavyWeightProcess.userId, 0));
14495                mHeavyWeightProcess = null;
14496            }
14497        } else if (!app.removed) {
14498            // This app is persistent, so we need to keep its record around.
14499            // If it is not already on the pending app list, add it there
14500            // and start a new process for it.
14501            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14502                mPersistentStartingProcesses.add(app);
14503                restart = true;
14504            }
14505        }
14506        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14507                "Clean-up removing on hold: " + app);
14508        mProcessesOnHold.remove(app);
14509
14510        if (app == mHomeProcess) {
14511            mHomeProcess = null;
14512        }
14513        if (app == mPreviousProcess) {
14514            mPreviousProcess = null;
14515        }
14516
14517        if (restart && !app.isolated) {
14518            // We have components that still need to be running in the
14519            // process, so re-launch it.
14520            if (index < 0) {
14521                ProcessList.remove(app.pid);
14522            }
14523            mProcessNames.put(app.processName, app.uid, app);
14524            startProcessLocked(app, "restart", app.processName);
14525            return true;
14526        } else if (app.pid > 0 && app.pid != MY_PID) {
14527            // Goodbye!
14528            boolean removed;
14529            synchronized (mPidsSelfLocked) {
14530                mPidsSelfLocked.remove(app.pid);
14531                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14532            }
14533            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14534            if (app.isolated) {
14535                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14536            }
14537            app.setPid(0);
14538        }
14539        return false;
14540    }
14541
14542    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14543        // Look through the content providers we are waiting to have launched,
14544        // and if any run in this process then either schedule a restart of
14545        // the process or kill the client waiting for it if this process has
14546        // gone bad.
14547        int NL = mLaunchingProviders.size();
14548        boolean restart = false;
14549        for (int i=0; i<NL; i++) {
14550            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14551            if (cpr.launchingApp == app) {
14552                if (!alwaysBad && !app.bad) {
14553                    restart = true;
14554                } else {
14555                    removeDyingProviderLocked(app, cpr, true);
14556                    // cpr should have been removed from mLaunchingProviders
14557                    NL = mLaunchingProviders.size();
14558                    i--;
14559                }
14560            }
14561        }
14562        return restart;
14563    }
14564
14565    // =========================================================
14566    // SERVICES
14567    // =========================================================
14568
14569    @Override
14570    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14571            int flags) {
14572        enforceNotIsolatedCaller("getServices");
14573        synchronized (this) {
14574            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14575        }
14576    }
14577
14578    @Override
14579    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14580        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14581        synchronized (this) {
14582            return mServices.getRunningServiceControlPanelLocked(name);
14583        }
14584    }
14585
14586    @Override
14587    public ComponentName startService(IApplicationThread caller, Intent service,
14588            String resolvedType, int userId) {
14589        enforceNotIsolatedCaller("startService");
14590        // Refuse possible leaked file descriptors
14591        if (service != null && service.hasFileDescriptors() == true) {
14592            throw new IllegalArgumentException("File descriptors passed in Intent");
14593        }
14594
14595        if (DEBUG_SERVICE)
14596            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14597        synchronized(this) {
14598            final int callingPid = Binder.getCallingPid();
14599            final int callingUid = Binder.getCallingUid();
14600            final long origId = Binder.clearCallingIdentity();
14601            ComponentName res = mServices.startServiceLocked(caller, service,
14602                    resolvedType, callingPid, callingUid, userId);
14603            Binder.restoreCallingIdentity(origId);
14604            return res;
14605        }
14606    }
14607
14608    ComponentName startServiceInPackage(int uid,
14609            Intent service, String resolvedType, int userId) {
14610        synchronized(this) {
14611            if (DEBUG_SERVICE)
14612                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14613            final long origId = Binder.clearCallingIdentity();
14614            ComponentName res = mServices.startServiceLocked(null, service,
14615                    resolvedType, -1, uid, userId);
14616            Binder.restoreCallingIdentity(origId);
14617            return res;
14618        }
14619    }
14620
14621    @Override
14622    public int stopService(IApplicationThread caller, Intent service,
14623            String resolvedType, int userId) {
14624        enforceNotIsolatedCaller("stopService");
14625        // Refuse possible leaked file descriptors
14626        if (service != null && service.hasFileDescriptors() == true) {
14627            throw new IllegalArgumentException("File descriptors passed in Intent");
14628        }
14629
14630        synchronized(this) {
14631            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14632        }
14633    }
14634
14635    @Override
14636    public IBinder peekService(Intent service, String resolvedType) {
14637        enforceNotIsolatedCaller("peekService");
14638        // Refuse possible leaked file descriptors
14639        if (service != null && service.hasFileDescriptors() == true) {
14640            throw new IllegalArgumentException("File descriptors passed in Intent");
14641        }
14642        synchronized(this) {
14643            return mServices.peekServiceLocked(service, resolvedType);
14644        }
14645    }
14646
14647    @Override
14648    public boolean stopServiceToken(ComponentName className, IBinder token,
14649            int startId) {
14650        synchronized(this) {
14651            return mServices.stopServiceTokenLocked(className, token, startId);
14652        }
14653    }
14654
14655    @Override
14656    public void setServiceForeground(ComponentName className, IBinder token,
14657            int id, Notification notification, boolean removeNotification) {
14658        synchronized(this) {
14659            mServices.setServiceForegroundLocked(className, token, id, notification,
14660                    removeNotification);
14661        }
14662    }
14663
14664    @Override
14665    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14666            boolean requireFull, String name, String callerPackage) {
14667        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14668                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14669    }
14670
14671    int unsafeConvertIncomingUser(int userId) {
14672        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14673                ? mCurrentUserId : userId;
14674    }
14675
14676    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14677            int allowMode, String name, String callerPackage) {
14678        final int callingUserId = UserHandle.getUserId(callingUid);
14679        if (callingUserId == userId) {
14680            return userId;
14681        }
14682
14683        // Note that we may be accessing mCurrentUserId outside of a lock...
14684        // shouldn't be a big deal, if this is being called outside
14685        // of a locked context there is intrinsically a race with
14686        // the value the caller will receive and someone else changing it.
14687        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14688        // we will switch to the calling user if access to the current user fails.
14689        int targetUserId = unsafeConvertIncomingUser(userId);
14690
14691        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14692            final boolean allow;
14693            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14694                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14695                // If the caller has this permission, they always pass go.  And collect $200.
14696                allow = true;
14697            } else if (allowMode == ALLOW_FULL_ONLY) {
14698                // We require full access, sucks to be you.
14699                allow = false;
14700            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14701                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14702                // If the caller does not have either permission, they are always doomed.
14703                allow = false;
14704            } else if (allowMode == ALLOW_NON_FULL) {
14705                // We are blanket allowing non-full access, you lucky caller!
14706                allow = true;
14707            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14708                // We may or may not allow this depending on whether the two users are
14709                // in the same profile.
14710                synchronized (mUserProfileGroupIdsSelfLocked) {
14711                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14712                            UserInfo.NO_PROFILE_GROUP_ID);
14713                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14714                            UserInfo.NO_PROFILE_GROUP_ID);
14715                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14716                            && callingProfile == targetProfile;
14717                }
14718            } else {
14719                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14720            }
14721            if (!allow) {
14722                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14723                    // In this case, they would like to just execute as their
14724                    // owner user instead of failing.
14725                    targetUserId = callingUserId;
14726                } else {
14727                    StringBuilder builder = new StringBuilder(128);
14728                    builder.append("Permission Denial: ");
14729                    builder.append(name);
14730                    if (callerPackage != null) {
14731                        builder.append(" from ");
14732                        builder.append(callerPackage);
14733                    }
14734                    builder.append(" asks to run as user ");
14735                    builder.append(userId);
14736                    builder.append(" but is calling from user ");
14737                    builder.append(UserHandle.getUserId(callingUid));
14738                    builder.append("; this requires ");
14739                    builder.append(INTERACT_ACROSS_USERS_FULL);
14740                    if (allowMode != ALLOW_FULL_ONLY) {
14741                        builder.append(" or ");
14742                        builder.append(INTERACT_ACROSS_USERS);
14743                    }
14744                    String msg = builder.toString();
14745                    Slog.w(TAG, msg);
14746                    throw new SecurityException(msg);
14747                }
14748            }
14749        }
14750        if (!allowAll && targetUserId < 0) {
14751            throw new IllegalArgumentException(
14752                    "Call does not support special user #" + targetUserId);
14753        }
14754        // Check shell permission
14755        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14756            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14757                    targetUserId)) {
14758                throw new SecurityException("Shell does not have permission to access user "
14759                        + targetUserId + "\n " + Debug.getCallers(3));
14760            }
14761        }
14762        return targetUserId;
14763    }
14764
14765    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14766            String className, int flags) {
14767        boolean result = false;
14768        // For apps that don't have pre-defined UIDs, check for permission
14769        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14770            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14771                if (ActivityManager.checkUidPermission(
14772                        INTERACT_ACROSS_USERS,
14773                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14774                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14775                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14776                            + " requests FLAG_SINGLE_USER, but app does not hold "
14777                            + INTERACT_ACROSS_USERS;
14778                    Slog.w(TAG, msg);
14779                    throw new SecurityException(msg);
14780                }
14781                // Permission passed
14782                result = true;
14783            }
14784        } else if ("system".equals(componentProcessName)) {
14785            result = true;
14786        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14787            // Phone app and persistent apps are allowed to export singleuser providers.
14788            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14789                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14790        }
14791        if (DEBUG_MU) {
14792            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14793                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14794        }
14795        return result;
14796    }
14797
14798    /**
14799     * Checks to see if the caller is in the same app as the singleton
14800     * component, or the component is in a special app. It allows special apps
14801     * to export singleton components but prevents exporting singleton
14802     * components for regular apps.
14803     */
14804    boolean isValidSingletonCall(int callingUid, int componentUid) {
14805        int componentAppId = UserHandle.getAppId(componentUid);
14806        return UserHandle.isSameApp(callingUid, componentUid)
14807                || componentAppId == Process.SYSTEM_UID
14808                || componentAppId == Process.PHONE_UID
14809                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14810                        == PackageManager.PERMISSION_GRANTED;
14811    }
14812
14813    public int bindService(IApplicationThread caller, IBinder token,
14814            Intent service, String resolvedType,
14815            IServiceConnection connection, int flags, int userId) {
14816        enforceNotIsolatedCaller("bindService");
14817
14818        // Refuse possible leaked file descriptors
14819        if (service != null && service.hasFileDescriptors() == true) {
14820            throw new IllegalArgumentException("File descriptors passed in Intent");
14821        }
14822
14823        synchronized(this) {
14824            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14825                    connection, flags, userId);
14826        }
14827    }
14828
14829    public boolean unbindService(IServiceConnection connection) {
14830        synchronized (this) {
14831            return mServices.unbindServiceLocked(connection);
14832        }
14833    }
14834
14835    public void publishService(IBinder token, Intent intent, IBinder service) {
14836        // Refuse possible leaked file descriptors
14837        if (intent != null && intent.hasFileDescriptors() == true) {
14838            throw new IllegalArgumentException("File descriptors passed in Intent");
14839        }
14840
14841        synchronized(this) {
14842            if (!(token instanceof ServiceRecord)) {
14843                throw new IllegalArgumentException("Invalid service token");
14844            }
14845            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14846        }
14847    }
14848
14849    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14850        // Refuse possible leaked file descriptors
14851        if (intent != null && intent.hasFileDescriptors() == true) {
14852            throw new IllegalArgumentException("File descriptors passed in Intent");
14853        }
14854
14855        synchronized(this) {
14856            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14857        }
14858    }
14859
14860    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14861        synchronized(this) {
14862            if (!(token instanceof ServiceRecord)) {
14863                throw new IllegalArgumentException("Invalid service token");
14864            }
14865            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14866        }
14867    }
14868
14869    // =========================================================
14870    // BACKUP AND RESTORE
14871    // =========================================================
14872
14873    // Cause the target app to be launched if necessary and its backup agent
14874    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14875    // activity manager to announce its creation.
14876    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14877        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14878        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14879
14880        synchronized(this) {
14881            // !!! TODO: currently no check here that we're already bound
14882            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14883            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14884            synchronized (stats) {
14885                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14886            }
14887
14888            // Backup agent is now in use, its package can't be stopped.
14889            try {
14890                AppGlobals.getPackageManager().setPackageStoppedState(
14891                        app.packageName, false, UserHandle.getUserId(app.uid));
14892            } catch (RemoteException e) {
14893            } catch (IllegalArgumentException e) {
14894                Slog.w(TAG, "Failed trying to unstop package "
14895                        + app.packageName + ": " + e);
14896            }
14897
14898            BackupRecord r = new BackupRecord(ss, app, backupMode);
14899            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14900                    ? new ComponentName(app.packageName, app.backupAgentName)
14901                    : new ComponentName("android", "FullBackupAgent");
14902            // startProcessLocked() returns existing proc's record if it's already running
14903            ProcessRecord proc = startProcessLocked(app.processName, app,
14904                    false, 0, "backup", hostingName, false, false, false);
14905            if (proc == null) {
14906                Slog.e(TAG, "Unable to start backup agent process " + r);
14907                return false;
14908            }
14909
14910            r.app = proc;
14911            mBackupTarget = r;
14912            mBackupAppName = app.packageName;
14913
14914            // Try not to kill the process during backup
14915            updateOomAdjLocked(proc);
14916
14917            // If the process is already attached, schedule the creation of the backup agent now.
14918            // If it is not yet live, this will be done when it attaches to the framework.
14919            if (proc.thread != null) {
14920                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14921                try {
14922                    proc.thread.scheduleCreateBackupAgent(app,
14923                            compatibilityInfoForPackageLocked(app), backupMode);
14924                } catch (RemoteException e) {
14925                    // Will time out on the backup manager side
14926                }
14927            } else {
14928                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14929            }
14930            // Invariants: at this point, the target app process exists and the application
14931            // is either already running or in the process of coming up.  mBackupTarget and
14932            // mBackupAppName describe the app, so that when it binds back to the AM we
14933            // know that it's scheduled for a backup-agent operation.
14934        }
14935
14936        return true;
14937    }
14938
14939    @Override
14940    public void clearPendingBackup() {
14941        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14942        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14943
14944        synchronized (this) {
14945            mBackupTarget = null;
14946            mBackupAppName = null;
14947        }
14948    }
14949
14950    // A backup agent has just come up
14951    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14952        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14953                + " = " + agent);
14954
14955        synchronized(this) {
14956            if (!agentPackageName.equals(mBackupAppName)) {
14957                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14958                return;
14959            }
14960        }
14961
14962        long oldIdent = Binder.clearCallingIdentity();
14963        try {
14964            IBackupManager bm = IBackupManager.Stub.asInterface(
14965                    ServiceManager.getService(Context.BACKUP_SERVICE));
14966            bm.agentConnected(agentPackageName, agent);
14967        } catch (RemoteException e) {
14968            // can't happen; the backup manager service is local
14969        } catch (Exception e) {
14970            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14971            e.printStackTrace();
14972        } finally {
14973            Binder.restoreCallingIdentity(oldIdent);
14974        }
14975    }
14976
14977    // done with this agent
14978    public void unbindBackupAgent(ApplicationInfo appInfo) {
14979        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14980        if (appInfo == null) {
14981            Slog.w(TAG, "unbind backup agent for null app");
14982            return;
14983        }
14984
14985        synchronized(this) {
14986            try {
14987                if (mBackupAppName == null) {
14988                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14989                    return;
14990                }
14991
14992                if (!mBackupAppName.equals(appInfo.packageName)) {
14993                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14994                    return;
14995                }
14996
14997                // Not backing this app up any more; reset its OOM adjustment
14998                final ProcessRecord proc = mBackupTarget.app;
14999                updateOomAdjLocked(proc);
15000
15001                // If the app crashed during backup, 'thread' will be null here
15002                if (proc.thread != null) {
15003                    try {
15004                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15005                                compatibilityInfoForPackageLocked(appInfo));
15006                    } catch (Exception e) {
15007                        Slog.e(TAG, "Exception when unbinding backup agent:");
15008                        e.printStackTrace();
15009                    }
15010                }
15011            } finally {
15012                mBackupTarget = null;
15013                mBackupAppName = null;
15014            }
15015        }
15016    }
15017    // =========================================================
15018    // BROADCASTS
15019    // =========================================================
15020
15021    private final List getStickiesLocked(String action, IntentFilter filter,
15022            List cur, int userId) {
15023        final ContentResolver resolver = mContext.getContentResolver();
15024        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15025        if (stickies == null) {
15026            return cur;
15027        }
15028        final ArrayList<Intent> list = stickies.get(action);
15029        if (list == null) {
15030            return cur;
15031        }
15032        int N = list.size();
15033        for (int i=0; i<N; i++) {
15034            Intent intent = list.get(i);
15035            if (filter.match(resolver, intent, true, TAG) >= 0) {
15036                if (cur == null) {
15037                    cur = new ArrayList<Intent>();
15038                }
15039                cur.add(intent);
15040            }
15041        }
15042        return cur;
15043    }
15044
15045    boolean isPendingBroadcastProcessLocked(int pid) {
15046        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15047                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15048    }
15049
15050    void skipPendingBroadcastLocked(int pid) {
15051            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15052            for (BroadcastQueue queue : mBroadcastQueues) {
15053                queue.skipPendingBroadcastLocked(pid);
15054            }
15055    }
15056
15057    // The app just attached; send any pending broadcasts that it should receive
15058    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15059        boolean didSomething = false;
15060        for (BroadcastQueue queue : mBroadcastQueues) {
15061            didSomething |= queue.sendPendingBroadcastsLocked(app);
15062        }
15063        return didSomething;
15064    }
15065
15066    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15067            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15068        enforceNotIsolatedCaller("registerReceiver");
15069        int callingUid;
15070        int callingPid;
15071        synchronized(this) {
15072            ProcessRecord callerApp = null;
15073            if (caller != null) {
15074                callerApp = getRecordForAppLocked(caller);
15075                if (callerApp == null) {
15076                    throw new SecurityException(
15077                            "Unable to find app for caller " + caller
15078                            + " (pid=" + Binder.getCallingPid()
15079                            + ") when registering receiver " + receiver);
15080                }
15081                if (callerApp.info.uid != Process.SYSTEM_UID &&
15082                        !callerApp.pkgList.containsKey(callerPackage) &&
15083                        !"android".equals(callerPackage)) {
15084                    throw new SecurityException("Given caller package " + callerPackage
15085                            + " is not running in process " + callerApp);
15086                }
15087                callingUid = callerApp.info.uid;
15088                callingPid = callerApp.pid;
15089            } else {
15090                callerPackage = null;
15091                callingUid = Binder.getCallingUid();
15092                callingPid = Binder.getCallingPid();
15093            }
15094
15095            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15096                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15097
15098            List allSticky = null;
15099
15100            // Look for any matching sticky broadcasts...
15101            Iterator actions = filter.actionsIterator();
15102            if (actions != null) {
15103                while (actions.hasNext()) {
15104                    String action = (String)actions.next();
15105                    allSticky = getStickiesLocked(action, filter, allSticky,
15106                            UserHandle.USER_ALL);
15107                    allSticky = getStickiesLocked(action, filter, allSticky,
15108                            UserHandle.getUserId(callingUid));
15109                }
15110            } else {
15111                allSticky = getStickiesLocked(null, filter, allSticky,
15112                        UserHandle.USER_ALL);
15113                allSticky = getStickiesLocked(null, filter, allSticky,
15114                        UserHandle.getUserId(callingUid));
15115            }
15116
15117            // The first sticky in the list is returned directly back to
15118            // the client.
15119            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15120
15121            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15122                    + ": " + sticky);
15123
15124            if (receiver == null) {
15125                return sticky;
15126            }
15127
15128            ReceiverList rl
15129                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15130            if (rl == null) {
15131                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15132                        userId, receiver);
15133                if (rl.app != null) {
15134                    rl.app.receivers.add(rl);
15135                } else {
15136                    try {
15137                        receiver.asBinder().linkToDeath(rl, 0);
15138                    } catch (RemoteException e) {
15139                        return sticky;
15140                    }
15141                    rl.linkedToDeath = true;
15142                }
15143                mRegisteredReceivers.put(receiver.asBinder(), rl);
15144            } else if (rl.uid != callingUid) {
15145                throw new IllegalArgumentException(
15146                        "Receiver requested to register for uid " + callingUid
15147                        + " was previously registered for uid " + rl.uid);
15148            } else if (rl.pid != callingPid) {
15149                throw new IllegalArgumentException(
15150                        "Receiver requested to register for pid " + callingPid
15151                        + " was previously registered for pid " + rl.pid);
15152            } else if (rl.userId != userId) {
15153                throw new IllegalArgumentException(
15154                        "Receiver requested to register for user " + userId
15155                        + " was previously registered for user " + rl.userId);
15156            }
15157            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15158                    permission, callingUid, userId);
15159            rl.add(bf);
15160            if (!bf.debugCheck()) {
15161                Slog.w(TAG, "==> For Dynamic broadast");
15162            }
15163            mReceiverResolver.addFilter(bf);
15164
15165            // Enqueue broadcasts for all existing stickies that match
15166            // this filter.
15167            if (allSticky != null) {
15168                ArrayList receivers = new ArrayList();
15169                receivers.add(bf);
15170
15171                int N = allSticky.size();
15172                for (int i=0; i<N; i++) {
15173                    Intent intent = (Intent)allSticky.get(i);
15174                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15175                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15176                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15177                            null, null, false, true, true, -1);
15178                    queue.enqueueParallelBroadcastLocked(r);
15179                    queue.scheduleBroadcastsLocked();
15180                }
15181            }
15182
15183            return sticky;
15184        }
15185    }
15186
15187    public void unregisterReceiver(IIntentReceiver receiver) {
15188        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15189
15190        final long origId = Binder.clearCallingIdentity();
15191        try {
15192            boolean doTrim = false;
15193
15194            synchronized(this) {
15195                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15196                if (rl != null) {
15197                    if (rl.curBroadcast != null) {
15198                        BroadcastRecord r = rl.curBroadcast;
15199                        final boolean doNext = finishReceiverLocked(
15200                                receiver.asBinder(), r.resultCode, r.resultData,
15201                                r.resultExtras, r.resultAbort);
15202                        if (doNext) {
15203                            doTrim = true;
15204                            r.queue.processNextBroadcast(false);
15205                        }
15206                    }
15207
15208                    if (rl.app != null) {
15209                        rl.app.receivers.remove(rl);
15210                    }
15211                    removeReceiverLocked(rl);
15212                    if (rl.linkedToDeath) {
15213                        rl.linkedToDeath = false;
15214                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15215                    }
15216                }
15217            }
15218
15219            // If we actually concluded any broadcasts, we might now be able
15220            // to trim the recipients' apps from our working set
15221            if (doTrim) {
15222                trimApplications();
15223                return;
15224            }
15225
15226        } finally {
15227            Binder.restoreCallingIdentity(origId);
15228        }
15229    }
15230
15231    void removeReceiverLocked(ReceiverList rl) {
15232        mRegisteredReceivers.remove(rl.receiver.asBinder());
15233        int N = rl.size();
15234        for (int i=0; i<N; i++) {
15235            mReceiverResolver.removeFilter(rl.get(i));
15236        }
15237    }
15238
15239    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15240        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15241            ProcessRecord r = mLruProcesses.get(i);
15242            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15243                try {
15244                    r.thread.dispatchPackageBroadcast(cmd, packages);
15245                } catch (RemoteException ex) {
15246                }
15247            }
15248        }
15249    }
15250
15251    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15252            int callingUid, int[] users) {
15253        List<ResolveInfo> receivers = null;
15254        try {
15255            HashSet<ComponentName> singleUserReceivers = null;
15256            boolean scannedFirstReceivers = false;
15257            for (int user : users) {
15258                // Skip users that have Shell restrictions
15259                if (callingUid == Process.SHELL_UID
15260                        && getUserManagerLocked().hasUserRestriction(
15261                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15262                    continue;
15263                }
15264                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15265                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15266                if (user != 0 && newReceivers != null) {
15267                    // If this is not the primary user, we need to check for
15268                    // any receivers that should be filtered out.
15269                    for (int i=0; i<newReceivers.size(); i++) {
15270                        ResolveInfo ri = newReceivers.get(i);
15271                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15272                            newReceivers.remove(i);
15273                            i--;
15274                        }
15275                    }
15276                }
15277                if (newReceivers != null && newReceivers.size() == 0) {
15278                    newReceivers = null;
15279                }
15280                if (receivers == null) {
15281                    receivers = newReceivers;
15282                } else if (newReceivers != null) {
15283                    // We need to concatenate the additional receivers
15284                    // found with what we have do far.  This would be easy,
15285                    // but we also need to de-dup any receivers that are
15286                    // singleUser.
15287                    if (!scannedFirstReceivers) {
15288                        // Collect any single user receivers we had already retrieved.
15289                        scannedFirstReceivers = true;
15290                        for (int i=0; i<receivers.size(); i++) {
15291                            ResolveInfo ri = receivers.get(i);
15292                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15293                                ComponentName cn = new ComponentName(
15294                                        ri.activityInfo.packageName, ri.activityInfo.name);
15295                                if (singleUserReceivers == null) {
15296                                    singleUserReceivers = new HashSet<ComponentName>();
15297                                }
15298                                singleUserReceivers.add(cn);
15299                            }
15300                        }
15301                    }
15302                    // Add the new results to the existing results, tracking
15303                    // and de-dupping single user receivers.
15304                    for (int i=0; i<newReceivers.size(); i++) {
15305                        ResolveInfo ri = newReceivers.get(i);
15306                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15307                            ComponentName cn = new ComponentName(
15308                                    ri.activityInfo.packageName, ri.activityInfo.name);
15309                            if (singleUserReceivers == null) {
15310                                singleUserReceivers = new HashSet<ComponentName>();
15311                            }
15312                            if (!singleUserReceivers.contains(cn)) {
15313                                singleUserReceivers.add(cn);
15314                                receivers.add(ri);
15315                            }
15316                        } else {
15317                            receivers.add(ri);
15318                        }
15319                    }
15320                }
15321            }
15322        } catch (RemoteException ex) {
15323            // pm is in same process, this will never happen.
15324        }
15325        return receivers;
15326    }
15327
15328    private final int broadcastIntentLocked(ProcessRecord callerApp,
15329            String callerPackage, Intent intent, String resolvedType,
15330            IIntentReceiver resultTo, int resultCode, String resultData,
15331            Bundle map, String requiredPermission, int appOp,
15332            boolean ordered, boolean sticky, int callingPid, int callingUid,
15333            int userId) {
15334        intent = new Intent(intent);
15335
15336        // By default broadcasts do not go to stopped apps.
15337        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15338
15339        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15340            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15341            + " ordered=" + ordered + " userid=" + userId);
15342        if ((resultTo != null) && !ordered) {
15343            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15344        }
15345
15346        userId = handleIncomingUser(callingPid, callingUid, userId,
15347                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15348
15349        // Make sure that the user who is receiving this broadcast is started.
15350        // If not, we will just skip it.
15351
15352        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15353            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15354                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15355                Slog.w(TAG, "Skipping broadcast of " + intent
15356                        + ": user " + userId + " is stopped");
15357                return ActivityManager.BROADCAST_SUCCESS;
15358            }
15359        }
15360
15361        /*
15362         * Prevent non-system code (defined here to be non-persistent
15363         * processes) from sending protected broadcasts.
15364         */
15365        int callingAppId = UserHandle.getAppId(callingUid);
15366        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15367            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15368            || callingAppId == Process.NFC_UID || callingUid == 0) {
15369            // Always okay.
15370        } else if (callerApp == null || !callerApp.persistent) {
15371            try {
15372                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15373                        intent.getAction())) {
15374                    String msg = "Permission Denial: not allowed to send broadcast "
15375                            + intent.getAction() + " from pid="
15376                            + callingPid + ", uid=" + callingUid;
15377                    Slog.w(TAG, msg);
15378                    throw new SecurityException(msg);
15379                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15380                    // Special case for compatibility: we don't want apps to send this,
15381                    // but historically it has not been protected and apps may be using it
15382                    // to poke their own app widget.  So, instead of making it protected,
15383                    // just limit it to the caller.
15384                    if (callerApp == null) {
15385                        String msg = "Permission Denial: not allowed to send broadcast "
15386                                + intent.getAction() + " from unknown caller.";
15387                        Slog.w(TAG, msg);
15388                        throw new SecurityException(msg);
15389                    } else if (intent.getComponent() != null) {
15390                        // They are good enough to send to an explicit component...  verify
15391                        // it is being sent to the calling app.
15392                        if (!intent.getComponent().getPackageName().equals(
15393                                callerApp.info.packageName)) {
15394                            String msg = "Permission Denial: not allowed to send broadcast "
15395                                    + intent.getAction() + " to "
15396                                    + intent.getComponent().getPackageName() + " from "
15397                                    + callerApp.info.packageName;
15398                            Slog.w(TAG, msg);
15399                            throw new SecurityException(msg);
15400                        }
15401                    } else {
15402                        // Limit broadcast to their own package.
15403                        intent.setPackage(callerApp.info.packageName);
15404                    }
15405                }
15406            } catch (RemoteException e) {
15407                Slog.w(TAG, "Remote exception", e);
15408                return ActivityManager.BROADCAST_SUCCESS;
15409            }
15410        }
15411
15412        // Handle special intents: if this broadcast is from the package
15413        // manager about a package being removed, we need to remove all of
15414        // its activities from the history stack.
15415        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15416                intent.getAction());
15417        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15418                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15419                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15420                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15421                || uidRemoved) {
15422            if (checkComponentPermission(
15423                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15424                    callingPid, callingUid, -1, true)
15425                    == PackageManager.PERMISSION_GRANTED) {
15426                if (uidRemoved) {
15427                    final Bundle intentExtras = intent.getExtras();
15428                    final int uid = intentExtras != null
15429                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15430                    if (uid >= 0) {
15431                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15432                        synchronized (bs) {
15433                            bs.removeUidStatsLocked(uid);
15434                        }
15435                        mAppOpsService.uidRemoved(uid);
15436                    }
15437                } else {
15438                    // If resources are unavailable just force stop all
15439                    // those packages and flush the attribute cache as well.
15440                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15441                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15442                        if (list != null && (list.length > 0)) {
15443                            for (String pkg : list) {
15444                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15445                                        "storage unmount");
15446                            }
15447                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15448                            sendPackageBroadcastLocked(
15449                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15450                        }
15451                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15452                            intent.getAction())) {
15453                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15454                    } else {
15455                        Uri data = intent.getData();
15456                        String ssp;
15457                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15458                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15459                                    intent.getAction());
15460                            boolean fullUninstall = removed &&
15461                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15462                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15463                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15464                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15465                                        false, fullUninstall, userId,
15466                                        removed ? "pkg removed" : "pkg changed");
15467                            }
15468                            if (removed) {
15469                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15470                                        new String[] {ssp}, userId);
15471                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15472                                    mAppOpsService.packageRemoved(
15473                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15474
15475                                    // Remove all permissions granted from/to this package
15476                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15477                                }
15478                            }
15479                        }
15480                    }
15481                }
15482            } else {
15483                String msg = "Permission Denial: " + intent.getAction()
15484                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15485                        + ", uid=" + callingUid + ")"
15486                        + " requires "
15487                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15488                Slog.w(TAG, msg);
15489                throw new SecurityException(msg);
15490            }
15491
15492        // Special case for adding a package: by default turn on compatibility
15493        // mode.
15494        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15495            Uri data = intent.getData();
15496            String ssp;
15497            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15498                mCompatModePackages.handlePackageAddedLocked(ssp,
15499                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15500            }
15501        }
15502
15503        /*
15504         * If this is the time zone changed action, queue up a message that will reset the timezone
15505         * of all currently running processes. This message will get queued up before the broadcast
15506         * happens.
15507         */
15508        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15509            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15510        }
15511
15512        /*
15513         * If the user set the time, let all running processes know.
15514         */
15515        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15516            final int is24Hour = intent.getBooleanExtra(
15517                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15518            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15519            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15520            synchronized (stats) {
15521                stats.noteCurrentTimeChangedLocked();
15522            }
15523        }
15524
15525        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15526            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15527        }
15528
15529        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15530            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15531            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15532        }
15533
15534        // Add to the sticky list if requested.
15535        if (sticky) {
15536            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15537                    callingPid, callingUid)
15538                    != PackageManager.PERMISSION_GRANTED) {
15539                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15540                        + callingPid + ", uid=" + callingUid
15541                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15542                Slog.w(TAG, msg);
15543                throw new SecurityException(msg);
15544            }
15545            if (requiredPermission != null) {
15546                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15547                        + " and enforce permission " + requiredPermission);
15548                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15549            }
15550            if (intent.getComponent() != null) {
15551                throw new SecurityException(
15552                        "Sticky broadcasts can't target a specific component");
15553            }
15554            // We use userId directly here, since the "all" target is maintained
15555            // as a separate set of sticky broadcasts.
15556            if (userId != UserHandle.USER_ALL) {
15557                // But first, if this is not a broadcast to all users, then
15558                // make sure it doesn't conflict with an existing broadcast to
15559                // all users.
15560                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15561                        UserHandle.USER_ALL);
15562                if (stickies != null) {
15563                    ArrayList<Intent> list = stickies.get(intent.getAction());
15564                    if (list != null) {
15565                        int N = list.size();
15566                        int i;
15567                        for (i=0; i<N; i++) {
15568                            if (intent.filterEquals(list.get(i))) {
15569                                throw new IllegalArgumentException(
15570                                        "Sticky broadcast " + intent + " for user "
15571                                        + userId + " conflicts with existing global broadcast");
15572                            }
15573                        }
15574                    }
15575                }
15576            }
15577            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15578            if (stickies == null) {
15579                stickies = new ArrayMap<String, ArrayList<Intent>>();
15580                mStickyBroadcasts.put(userId, stickies);
15581            }
15582            ArrayList<Intent> list = stickies.get(intent.getAction());
15583            if (list == null) {
15584                list = new ArrayList<Intent>();
15585                stickies.put(intent.getAction(), list);
15586            }
15587            int N = list.size();
15588            int i;
15589            for (i=0; i<N; i++) {
15590                if (intent.filterEquals(list.get(i))) {
15591                    // This sticky already exists, replace it.
15592                    list.set(i, new Intent(intent));
15593                    break;
15594                }
15595            }
15596            if (i >= N) {
15597                list.add(new Intent(intent));
15598            }
15599        }
15600
15601        int[] users;
15602        if (userId == UserHandle.USER_ALL) {
15603            // Caller wants broadcast to go to all started users.
15604            users = mStartedUserArray;
15605        } else {
15606            // Caller wants broadcast to go to one specific user.
15607            users = new int[] {userId};
15608        }
15609
15610        // Figure out who all will receive this broadcast.
15611        List receivers = null;
15612        List<BroadcastFilter> registeredReceivers = null;
15613        // Need to resolve the intent to interested receivers...
15614        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15615                 == 0) {
15616            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15617        }
15618        if (intent.getComponent() == null) {
15619            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15620                // Query one target user at a time, excluding shell-restricted users
15621                UserManagerService ums = getUserManagerLocked();
15622                for (int i = 0; i < users.length; i++) {
15623                    if (ums.hasUserRestriction(
15624                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15625                        continue;
15626                    }
15627                    List<BroadcastFilter> registeredReceiversForUser =
15628                            mReceiverResolver.queryIntent(intent,
15629                                    resolvedType, false, users[i]);
15630                    if (registeredReceivers == null) {
15631                        registeredReceivers = registeredReceiversForUser;
15632                    } else if (registeredReceiversForUser != null) {
15633                        registeredReceivers.addAll(registeredReceiversForUser);
15634                    }
15635                }
15636            } else {
15637                registeredReceivers = mReceiverResolver.queryIntent(intent,
15638                        resolvedType, false, userId);
15639            }
15640        }
15641
15642        final boolean replacePending =
15643                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15644
15645        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15646                + " replacePending=" + replacePending);
15647
15648        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15649        if (!ordered && NR > 0) {
15650            // If we are not serializing this broadcast, then send the
15651            // registered receivers separately so they don't wait for the
15652            // components to be launched.
15653            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15654            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15655                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15656                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15657                    ordered, sticky, false, userId);
15658            if (DEBUG_BROADCAST) Slog.v(
15659                    TAG, "Enqueueing parallel broadcast " + r);
15660            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15661            if (!replaced) {
15662                queue.enqueueParallelBroadcastLocked(r);
15663                queue.scheduleBroadcastsLocked();
15664            }
15665            registeredReceivers = null;
15666            NR = 0;
15667        }
15668
15669        // Merge into one list.
15670        int ir = 0;
15671        if (receivers != null) {
15672            // A special case for PACKAGE_ADDED: do not allow the package
15673            // being added to see this broadcast.  This prevents them from
15674            // using this as a back door to get run as soon as they are
15675            // installed.  Maybe in the future we want to have a special install
15676            // broadcast or such for apps, but we'd like to deliberately make
15677            // this decision.
15678            String skipPackages[] = null;
15679            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15680                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15681                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15682                Uri data = intent.getData();
15683                if (data != null) {
15684                    String pkgName = data.getSchemeSpecificPart();
15685                    if (pkgName != null) {
15686                        skipPackages = new String[] { pkgName };
15687                    }
15688                }
15689            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15690                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15691            }
15692            if (skipPackages != null && (skipPackages.length > 0)) {
15693                for (String skipPackage : skipPackages) {
15694                    if (skipPackage != null) {
15695                        int NT = receivers.size();
15696                        for (int it=0; it<NT; it++) {
15697                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15698                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15699                                receivers.remove(it);
15700                                it--;
15701                                NT--;
15702                            }
15703                        }
15704                    }
15705                }
15706            }
15707
15708            int NT = receivers != null ? receivers.size() : 0;
15709            int it = 0;
15710            ResolveInfo curt = null;
15711            BroadcastFilter curr = null;
15712            while (it < NT && ir < NR) {
15713                if (curt == null) {
15714                    curt = (ResolveInfo)receivers.get(it);
15715                }
15716                if (curr == null) {
15717                    curr = registeredReceivers.get(ir);
15718                }
15719                if (curr.getPriority() >= curt.priority) {
15720                    // Insert this broadcast record into the final list.
15721                    receivers.add(it, curr);
15722                    ir++;
15723                    curr = null;
15724                    it++;
15725                    NT++;
15726                } else {
15727                    // Skip to the next ResolveInfo in the final list.
15728                    it++;
15729                    curt = null;
15730                }
15731            }
15732        }
15733        while (ir < NR) {
15734            if (receivers == null) {
15735                receivers = new ArrayList();
15736            }
15737            receivers.add(registeredReceivers.get(ir));
15738            ir++;
15739        }
15740
15741        if ((receivers != null && receivers.size() > 0)
15742                || resultTo != null) {
15743            BroadcastQueue queue = broadcastQueueForIntent(intent);
15744            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15745                    callerPackage, callingPid, callingUid, resolvedType,
15746                    requiredPermission, appOp, receivers, resultTo, resultCode,
15747                    resultData, map, ordered, sticky, false, userId);
15748            if (DEBUG_BROADCAST) Slog.v(
15749                    TAG, "Enqueueing ordered broadcast " + r
15750                    + ": prev had " + queue.mOrderedBroadcasts.size());
15751            if (DEBUG_BROADCAST) {
15752                int seq = r.intent.getIntExtra("seq", -1);
15753                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15754            }
15755            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15756            if (!replaced) {
15757                queue.enqueueOrderedBroadcastLocked(r);
15758                queue.scheduleBroadcastsLocked();
15759            }
15760        }
15761
15762        return ActivityManager.BROADCAST_SUCCESS;
15763    }
15764
15765    final Intent verifyBroadcastLocked(Intent intent) {
15766        // Refuse possible leaked file descriptors
15767        if (intent != null && intent.hasFileDescriptors() == true) {
15768            throw new IllegalArgumentException("File descriptors passed in Intent");
15769        }
15770
15771        int flags = intent.getFlags();
15772
15773        if (!mProcessesReady) {
15774            // if the caller really truly claims to know what they're doing, go
15775            // ahead and allow the broadcast without launching any receivers
15776            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15777                intent = new Intent(intent);
15778                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15779            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15780                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15781                        + " before boot completion");
15782                throw new IllegalStateException("Cannot broadcast before boot completed");
15783            }
15784        }
15785
15786        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15787            throw new IllegalArgumentException(
15788                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15789        }
15790
15791        return intent;
15792    }
15793
15794    public final int broadcastIntent(IApplicationThread caller,
15795            Intent intent, String resolvedType, IIntentReceiver resultTo,
15796            int resultCode, String resultData, Bundle map,
15797            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15798        enforceNotIsolatedCaller("broadcastIntent");
15799        synchronized(this) {
15800            intent = verifyBroadcastLocked(intent);
15801
15802            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15803            final int callingPid = Binder.getCallingPid();
15804            final int callingUid = Binder.getCallingUid();
15805            final long origId = Binder.clearCallingIdentity();
15806            int res = broadcastIntentLocked(callerApp,
15807                    callerApp != null ? callerApp.info.packageName : null,
15808                    intent, resolvedType, resultTo,
15809                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15810                    callingPid, callingUid, userId);
15811            Binder.restoreCallingIdentity(origId);
15812            return res;
15813        }
15814    }
15815
15816    int broadcastIntentInPackage(String packageName, int uid,
15817            Intent intent, String resolvedType, IIntentReceiver resultTo,
15818            int resultCode, String resultData, Bundle map,
15819            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15820        synchronized(this) {
15821            intent = verifyBroadcastLocked(intent);
15822
15823            final long origId = Binder.clearCallingIdentity();
15824            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15825                    resultTo, resultCode, resultData, map, requiredPermission,
15826                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15827            Binder.restoreCallingIdentity(origId);
15828            return res;
15829        }
15830    }
15831
15832    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15833        // Refuse possible leaked file descriptors
15834        if (intent != null && intent.hasFileDescriptors() == true) {
15835            throw new IllegalArgumentException("File descriptors passed in Intent");
15836        }
15837
15838        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15839                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15840
15841        synchronized(this) {
15842            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15843                    != PackageManager.PERMISSION_GRANTED) {
15844                String msg = "Permission Denial: unbroadcastIntent() from pid="
15845                        + Binder.getCallingPid()
15846                        + ", uid=" + Binder.getCallingUid()
15847                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15848                Slog.w(TAG, msg);
15849                throw new SecurityException(msg);
15850            }
15851            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15852            if (stickies != null) {
15853                ArrayList<Intent> list = stickies.get(intent.getAction());
15854                if (list != null) {
15855                    int N = list.size();
15856                    int i;
15857                    for (i=0; i<N; i++) {
15858                        if (intent.filterEquals(list.get(i))) {
15859                            list.remove(i);
15860                            break;
15861                        }
15862                    }
15863                    if (list.size() <= 0) {
15864                        stickies.remove(intent.getAction());
15865                    }
15866                }
15867                if (stickies.size() <= 0) {
15868                    mStickyBroadcasts.remove(userId);
15869                }
15870            }
15871        }
15872    }
15873
15874    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15875            String resultData, Bundle resultExtras, boolean resultAbort) {
15876        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15877        if (r == null) {
15878            Slog.w(TAG, "finishReceiver called but not found on queue");
15879            return false;
15880        }
15881
15882        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15883    }
15884
15885    void backgroundServicesFinishedLocked(int userId) {
15886        for (BroadcastQueue queue : mBroadcastQueues) {
15887            queue.backgroundServicesFinishedLocked(userId);
15888        }
15889    }
15890
15891    public void finishReceiver(IBinder who, int resultCode, String resultData,
15892            Bundle resultExtras, boolean resultAbort) {
15893        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15894
15895        // Refuse possible leaked file descriptors
15896        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15897            throw new IllegalArgumentException("File descriptors passed in Bundle");
15898        }
15899
15900        final long origId = Binder.clearCallingIdentity();
15901        try {
15902            boolean doNext = false;
15903            BroadcastRecord r;
15904
15905            synchronized(this) {
15906                r = broadcastRecordForReceiverLocked(who);
15907                if (r != null) {
15908                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15909                        resultData, resultExtras, resultAbort, true);
15910                }
15911            }
15912
15913            if (doNext) {
15914                r.queue.processNextBroadcast(false);
15915            }
15916            trimApplications();
15917        } finally {
15918            Binder.restoreCallingIdentity(origId);
15919        }
15920    }
15921
15922    // =========================================================
15923    // INSTRUMENTATION
15924    // =========================================================
15925
15926    public boolean startInstrumentation(ComponentName className,
15927            String profileFile, int flags, Bundle arguments,
15928            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15929            int userId, String abiOverride) {
15930        enforceNotIsolatedCaller("startInstrumentation");
15931        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15932                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15933        // Refuse possible leaked file descriptors
15934        if (arguments != null && arguments.hasFileDescriptors()) {
15935            throw new IllegalArgumentException("File descriptors passed in Bundle");
15936        }
15937
15938        synchronized(this) {
15939            InstrumentationInfo ii = null;
15940            ApplicationInfo ai = null;
15941            try {
15942                ii = mContext.getPackageManager().getInstrumentationInfo(
15943                    className, STOCK_PM_FLAGS);
15944                ai = AppGlobals.getPackageManager().getApplicationInfo(
15945                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15946            } catch (PackageManager.NameNotFoundException e) {
15947            } catch (RemoteException e) {
15948            }
15949            if (ii == null) {
15950                reportStartInstrumentationFailure(watcher, className,
15951                        "Unable to find instrumentation info for: " + className);
15952                return false;
15953            }
15954            if (ai == null) {
15955                reportStartInstrumentationFailure(watcher, className,
15956                        "Unable to find instrumentation target package: " + ii.targetPackage);
15957                return false;
15958            }
15959
15960            int match = mContext.getPackageManager().checkSignatures(
15961                    ii.targetPackage, ii.packageName);
15962            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15963                String msg = "Permission Denial: starting instrumentation "
15964                        + className + " from pid="
15965                        + Binder.getCallingPid()
15966                        + ", uid=" + Binder.getCallingPid()
15967                        + " not allowed because package " + ii.packageName
15968                        + " does not have a signature matching the target "
15969                        + ii.targetPackage;
15970                reportStartInstrumentationFailure(watcher, className, msg);
15971                throw new SecurityException(msg);
15972            }
15973
15974            final long origId = Binder.clearCallingIdentity();
15975            // Instrumentation can kill and relaunch even persistent processes
15976            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15977                    "start instr");
15978            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15979            app.instrumentationClass = className;
15980            app.instrumentationInfo = ai;
15981            app.instrumentationProfileFile = profileFile;
15982            app.instrumentationArguments = arguments;
15983            app.instrumentationWatcher = watcher;
15984            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15985            app.instrumentationResultClass = className;
15986            Binder.restoreCallingIdentity(origId);
15987        }
15988
15989        return true;
15990    }
15991
15992    /**
15993     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15994     * error to the logs, but if somebody is watching, send the report there too.  This enables
15995     * the "am" command to report errors with more information.
15996     *
15997     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15998     * @param cn The component name of the instrumentation.
15999     * @param report The error report.
16000     */
16001    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16002            ComponentName cn, String report) {
16003        Slog.w(TAG, report);
16004        try {
16005            if (watcher != null) {
16006                Bundle results = new Bundle();
16007                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16008                results.putString("Error", report);
16009                watcher.instrumentationStatus(cn, -1, results);
16010            }
16011        } catch (RemoteException e) {
16012            Slog.w(TAG, e);
16013        }
16014    }
16015
16016    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16017        if (app.instrumentationWatcher != null) {
16018            try {
16019                // NOTE:  IInstrumentationWatcher *must* be oneway here
16020                app.instrumentationWatcher.instrumentationFinished(
16021                    app.instrumentationClass,
16022                    resultCode,
16023                    results);
16024            } catch (RemoteException e) {
16025            }
16026        }
16027        if (app.instrumentationUiAutomationConnection != null) {
16028            try {
16029                app.instrumentationUiAutomationConnection.shutdown();
16030            } catch (RemoteException re) {
16031                /* ignore */
16032            }
16033            // Only a UiAutomation can set this flag and now that
16034            // it is finished we make sure it is reset to its default.
16035            mUserIsMonkey = false;
16036        }
16037        app.instrumentationWatcher = null;
16038        app.instrumentationUiAutomationConnection = null;
16039        app.instrumentationClass = null;
16040        app.instrumentationInfo = null;
16041        app.instrumentationProfileFile = null;
16042        app.instrumentationArguments = null;
16043
16044        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16045                "finished inst");
16046    }
16047
16048    public void finishInstrumentation(IApplicationThread target,
16049            int resultCode, Bundle results) {
16050        int userId = UserHandle.getCallingUserId();
16051        // Refuse possible leaked file descriptors
16052        if (results != null && results.hasFileDescriptors()) {
16053            throw new IllegalArgumentException("File descriptors passed in Intent");
16054        }
16055
16056        synchronized(this) {
16057            ProcessRecord app = getRecordForAppLocked(target);
16058            if (app == null) {
16059                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16060                return;
16061            }
16062            final long origId = Binder.clearCallingIdentity();
16063            finishInstrumentationLocked(app, resultCode, results);
16064            Binder.restoreCallingIdentity(origId);
16065        }
16066    }
16067
16068    // =========================================================
16069    // CONFIGURATION
16070    // =========================================================
16071
16072    public ConfigurationInfo getDeviceConfigurationInfo() {
16073        ConfigurationInfo config = new ConfigurationInfo();
16074        synchronized (this) {
16075            config.reqTouchScreen = mConfiguration.touchscreen;
16076            config.reqKeyboardType = mConfiguration.keyboard;
16077            config.reqNavigation = mConfiguration.navigation;
16078            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16079                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16080                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16081            }
16082            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16083                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16084                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16085            }
16086            config.reqGlEsVersion = GL_ES_VERSION;
16087        }
16088        return config;
16089    }
16090
16091    ActivityStack getFocusedStack() {
16092        return mStackSupervisor.getFocusedStack();
16093    }
16094
16095    public Configuration getConfiguration() {
16096        Configuration ci;
16097        synchronized(this) {
16098            ci = new Configuration(mConfiguration);
16099        }
16100        return ci;
16101    }
16102
16103    public void updatePersistentConfiguration(Configuration values) {
16104        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16105                "updateConfiguration()");
16106        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16107                "updateConfiguration()");
16108        if (values == null) {
16109            throw new NullPointerException("Configuration must not be null");
16110        }
16111
16112        synchronized(this) {
16113            final long origId = Binder.clearCallingIdentity();
16114            updateConfigurationLocked(values, null, true, false);
16115            Binder.restoreCallingIdentity(origId);
16116        }
16117    }
16118
16119    public void updateConfiguration(Configuration values) {
16120        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16121                "updateConfiguration()");
16122
16123        synchronized(this) {
16124            if (values == null && mWindowManager != null) {
16125                // sentinel: fetch the current configuration from the window manager
16126                values = mWindowManager.computeNewConfiguration();
16127            }
16128
16129            if (mWindowManager != null) {
16130                mProcessList.applyDisplaySize(mWindowManager);
16131            }
16132
16133            final long origId = Binder.clearCallingIdentity();
16134            if (values != null) {
16135                Settings.System.clearConfiguration(values);
16136            }
16137            updateConfigurationLocked(values, null, false, false);
16138            Binder.restoreCallingIdentity(origId);
16139        }
16140    }
16141
16142    /**
16143     * Do either or both things: (1) change the current configuration, and (2)
16144     * make sure the given activity is running with the (now) current
16145     * configuration.  Returns true if the activity has been left running, or
16146     * false if <var>starting</var> is being destroyed to match the new
16147     * configuration.
16148     * @param persistent TODO
16149     */
16150    boolean updateConfigurationLocked(Configuration values,
16151            ActivityRecord starting, boolean persistent, boolean initLocale) {
16152        int changes = 0;
16153
16154        if (values != null) {
16155            Configuration newConfig = new Configuration(mConfiguration);
16156            changes = newConfig.updateFrom(values);
16157            if (changes != 0) {
16158                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16159                    Slog.i(TAG, "Updating configuration to: " + values);
16160                }
16161
16162                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16163
16164                if (values.locale != null && !initLocale) {
16165                    saveLocaleLocked(values.locale,
16166                                     !values.locale.equals(mConfiguration.locale),
16167                                     values.userSetLocale);
16168                }
16169
16170                mConfigurationSeq++;
16171                if (mConfigurationSeq <= 0) {
16172                    mConfigurationSeq = 1;
16173                }
16174                newConfig.seq = mConfigurationSeq;
16175                mConfiguration = newConfig;
16176                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16177                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16178                //mUsageStatsService.noteStartConfig(newConfig);
16179
16180                final Configuration configCopy = new Configuration(mConfiguration);
16181
16182                // TODO: If our config changes, should we auto dismiss any currently
16183                // showing dialogs?
16184                mShowDialogs = shouldShowDialogs(newConfig);
16185
16186                AttributeCache ac = AttributeCache.instance();
16187                if (ac != null) {
16188                    ac.updateConfiguration(configCopy);
16189                }
16190
16191                // Make sure all resources in our process are updated
16192                // right now, so that anyone who is going to retrieve
16193                // resource values after we return will be sure to get
16194                // the new ones.  This is especially important during
16195                // boot, where the first config change needs to guarantee
16196                // all resources have that config before following boot
16197                // code is executed.
16198                mSystemThread.applyConfigurationToResources(configCopy);
16199
16200                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16201                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16202                    msg.obj = new Configuration(configCopy);
16203                    mHandler.sendMessage(msg);
16204                }
16205
16206                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16207                    ProcessRecord app = mLruProcesses.get(i);
16208                    try {
16209                        if (app.thread != null) {
16210                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16211                                    + app.processName + " new config " + mConfiguration);
16212                            app.thread.scheduleConfigurationChanged(configCopy);
16213                        }
16214                    } catch (Exception e) {
16215                    }
16216                }
16217                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16218                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16219                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16220                        | Intent.FLAG_RECEIVER_FOREGROUND);
16221                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16222                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16223                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16224                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16225                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16226                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16227                    broadcastIntentLocked(null, null, intent,
16228                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16229                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16230                }
16231            }
16232        }
16233
16234        boolean kept = true;
16235        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16236        // mainStack is null during startup.
16237        if (mainStack != null) {
16238            if (changes != 0 && starting == null) {
16239                // If the configuration changed, and the caller is not already
16240                // in the process of starting an activity, then find the top
16241                // activity to check if its configuration needs to change.
16242                starting = mainStack.topRunningActivityLocked(null);
16243            }
16244
16245            if (starting != null) {
16246                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16247                // And we need to make sure at this point that all other activities
16248                // are made visible with the correct configuration.
16249                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16250            }
16251        }
16252
16253        if (values != null && mWindowManager != null) {
16254            mWindowManager.setNewConfiguration(mConfiguration);
16255        }
16256
16257        return kept;
16258    }
16259
16260    /**
16261     * Decide based on the configuration whether we should shouw the ANR,
16262     * crash, etc dialogs.  The idea is that if there is no affordnace to
16263     * press the on-screen buttons, we shouldn't show the dialog.
16264     *
16265     * A thought: SystemUI might also want to get told about this, the Power
16266     * dialog / global actions also might want different behaviors.
16267     */
16268    private static final boolean shouldShowDialogs(Configuration config) {
16269        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16270                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16271    }
16272
16273    /**
16274     * Save the locale.  You must be inside a synchronized (this) block.
16275     */
16276    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16277        if(isDiff) {
16278            SystemProperties.set("user.language", l.getLanguage());
16279            SystemProperties.set("user.region", l.getCountry());
16280        }
16281
16282        if(isPersist) {
16283            SystemProperties.set("persist.sys.language", l.getLanguage());
16284            SystemProperties.set("persist.sys.country", l.getCountry());
16285            SystemProperties.set("persist.sys.localevar", l.getVariant());
16286
16287            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16288        }
16289    }
16290
16291    @Override
16292    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16293        synchronized (this) {
16294            ActivityRecord srec = ActivityRecord.forToken(token);
16295            if (srec.task != null && srec.task.stack != null) {
16296                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16297            }
16298        }
16299        return false;
16300    }
16301
16302    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16303            Intent resultData) {
16304
16305        synchronized (this) {
16306            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16307            if (stack != null) {
16308                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16309            }
16310            return false;
16311        }
16312    }
16313
16314    public int getLaunchedFromUid(IBinder activityToken) {
16315        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16316        if (srec == null) {
16317            return -1;
16318        }
16319        return srec.launchedFromUid;
16320    }
16321
16322    public String getLaunchedFromPackage(IBinder activityToken) {
16323        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16324        if (srec == null) {
16325            return null;
16326        }
16327        return srec.launchedFromPackage;
16328    }
16329
16330    // =========================================================
16331    // LIFETIME MANAGEMENT
16332    // =========================================================
16333
16334    // Returns which broadcast queue the app is the current [or imminent] receiver
16335    // on, or 'null' if the app is not an active broadcast recipient.
16336    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16337        BroadcastRecord r = app.curReceiver;
16338        if (r != null) {
16339            return r.queue;
16340        }
16341
16342        // It's not the current receiver, but it might be starting up to become one
16343        synchronized (this) {
16344            for (BroadcastQueue queue : mBroadcastQueues) {
16345                r = queue.mPendingBroadcast;
16346                if (r != null && r.curApp == app) {
16347                    // found it; report which queue it's in
16348                    return queue;
16349                }
16350            }
16351        }
16352
16353        return null;
16354    }
16355
16356    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16357            boolean doingAll, long now) {
16358        if (mAdjSeq == app.adjSeq) {
16359            // This adjustment has already been computed.
16360            return app.curRawAdj;
16361        }
16362
16363        if (app.thread == null) {
16364            app.adjSeq = mAdjSeq;
16365            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16366            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16367            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16368        }
16369
16370        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16371        app.adjSource = null;
16372        app.adjTarget = null;
16373        app.empty = false;
16374        app.cached = false;
16375
16376        final int activitiesSize = app.activities.size();
16377
16378        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16379            // The max adjustment doesn't allow this app to be anything
16380            // below foreground, so it is not worth doing work for it.
16381            app.adjType = "fixed";
16382            app.adjSeq = mAdjSeq;
16383            app.curRawAdj = app.maxAdj;
16384            app.foregroundActivities = false;
16385            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16386            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16387            // System processes can do UI, and when they do we want to have
16388            // them trim their memory after the user leaves the UI.  To
16389            // facilitate this, here we need to determine whether or not it
16390            // is currently showing UI.
16391            app.systemNoUi = true;
16392            if (app == TOP_APP) {
16393                app.systemNoUi = false;
16394            } else if (activitiesSize > 0) {
16395                for (int j = 0; j < activitiesSize; j++) {
16396                    final ActivityRecord r = app.activities.get(j);
16397                    if (r.visible) {
16398                        app.systemNoUi = false;
16399                    }
16400                }
16401            }
16402            if (!app.systemNoUi) {
16403                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16404            }
16405            return (app.curAdj=app.maxAdj);
16406        }
16407
16408        app.systemNoUi = false;
16409
16410        // Determine the importance of the process, starting with most
16411        // important to least, and assign an appropriate OOM adjustment.
16412        int adj;
16413        int schedGroup;
16414        int procState;
16415        boolean foregroundActivities = false;
16416        BroadcastQueue queue;
16417        if (app == TOP_APP) {
16418            // The last app on the list is the foreground app.
16419            adj = ProcessList.FOREGROUND_APP_ADJ;
16420            schedGroup = Process.THREAD_GROUP_DEFAULT;
16421            app.adjType = "top-activity";
16422            foregroundActivities = true;
16423            procState = ActivityManager.PROCESS_STATE_TOP;
16424        } else if (app.instrumentationClass != null) {
16425            // Don't want to kill running instrumentation.
16426            adj = ProcessList.FOREGROUND_APP_ADJ;
16427            schedGroup = Process.THREAD_GROUP_DEFAULT;
16428            app.adjType = "instrumentation";
16429            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16430        } else if ((queue = isReceivingBroadcast(app)) != null) {
16431            // An app that is currently receiving a broadcast also
16432            // counts as being in the foreground for OOM killer purposes.
16433            // It's placed in a sched group based on the nature of the
16434            // broadcast as reflected by which queue it's active in.
16435            adj = ProcessList.FOREGROUND_APP_ADJ;
16436            schedGroup = (queue == mFgBroadcastQueue)
16437                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16438            app.adjType = "broadcast";
16439            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16440        } else if (app.executingServices.size() > 0) {
16441            // An app that is currently executing a service callback also
16442            // counts as being in the foreground.
16443            adj = ProcessList.FOREGROUND_APP_ADJ;
16444            schedGroup = app.execServicesFg ?
16445                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16446            app.adjType = "exec-service";
16447            procState = ActivityManager.PROCESS_STATE_SERVICE;
16448            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16449        } else {
16450            // As far as we know the process is empty.  We may change our mind later.
16451            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16452            // At this point we don't actually know the adjustment.  Use the cached adj
16453            // value that the caller wants us to.
16454            adj = cachedAdj;
16455            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16456            app.cached = true;
16457            app.empty = true;
16458            app.adjType = "cch-empty";
16459        }
16460
16461        // Examine all activities if not already foreground.
16462        if (!foregroundActivities && activitiesSize > 0) {
16463            for (int j = 0; j < activitiesSize; j++) {
16464                final ActivityRecord r = app.activities.get(j);
16465                if (r.app != app) {
16466                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16467                            + app + "?!?");
16468                    continue;
16469                }
16470                if (r.visible) {
16471                    // App has a visible activity; only upgrade adjustment.
16472                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16473                        adj = ProcessList.VISIBLE_APP_ADJ;
16474                        app.adjType = "visible";
16475                    }
16476                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16477                        procState = ActivityManager.PROCESS_STATE_TOP;
16478                    }
16479                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16480                    app.cached = false;
16481                    app.empty = false;
16482                    foregroundActivities = true;
16483                    break;
16484                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16485                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16486                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16487                        app.adjType = "pausing";
16488                    }
16489                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16490                        procState = ActivityManager.PROCESS_STATE_TOP;
16491                    }
16492                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16493                    app.cached = false;
16494                    app.empty = false;
16495                    foregroundActivities = true;
16496                } else if (r.state == ActivityState.STOPPING) {
16497                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16498                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16499                        app.adjType = "stopping";
16500                    }
16501                    // For the process state, we will at this point consider the
16502                    // process to be cached.  It will be cached either as an activity
16503                    // or empty depending on whether the activity is finishing.  We do
16504                    // this so that we can treat the process as cached for purposes of
16505                    // memory trimming (determing current memory level, trim command to
16506                    // send to process) since there can be an arbitrary number of stopping
16507                    // processes and they should soon all go into the cached state.
16508                    if (!r.finishing) {
16509                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16510                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16511                        }
16512                    }
16513                    app.cached = false;
16514                    app.empty = false;
16515                    foregroundActivities = true;
16516                } else {
16517                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16518                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16519                        app.adjType = "cch-act";
16520                    }
16521                }
16522            }
16523        }
16524
16525        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16526            if (app.foregroundServices) {
16527                // The user is aware of this app, so make it visible.
16528                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16529                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16530                app.cached = false;
16531                app.adjType = "fg-service";
16532                schedGroup = Process.THREAD_GROUP_DEFAULT;
16533            } else if (app.forcingToForeground != null) {
16534                // The user is aware of this app, so make it visible.
16535                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16536                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16537                app.cached = false;
16538                app.adjType = "force-fg";
16539                app.adjSource = app.forcingToForeground;
16540                schedGroup = Process.THREAD_GROUP_DEFAULT;
16541            }
16542        }
16543
16544        if (app == mHeavyWeightProcess) {
16545            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16546                // We don't want to kill the current heavy-weight process.
16547                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16548                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16549                app.cached = false;
16550                app.adjType = "heavy";
16551            }
16552            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16553                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16554            }
16555        }
16556
16557        if (app == mHomeProcess) {
16558            if (adj > ProcessList.HOME_APP_ADJ) {
16559                // This process is hosting what we currently consider to be the
16560                // home app, so we don't want to let it go into the background.
16561                adj = ProcessList.HOME_APP_ADJ;
16562                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16563                app.cached = false;
16564                app.adjType = "home";
16565            }
16566            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16567                procState = ActivityManager.PROCESS_STATE_HOME;
16568            }
16569        }
16570
16571        if (app == mPreviousProcess && app.activities.size() > 0) {
16572            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16573                // This was the previous process that showed UI to the user.
16574                // We want to try to keep it around more aggressively, to give
16575                // a good experience around switching between two apps.
16576                adj = ProcessList.PREVIOUS_APP_ADJ;
16577                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16578                app.cached = false;
16579                app.adjType = "previous";
16580            }
16581            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16582                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16583            }
16584        }
16585
16586        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16587                + " reason=" + app.adjType);
16588
16589        // By default, we use the computed adjustment.  It may be changed if
16590        // there are applications dependent on our services or providers, but
16591        // this gives us a baseline and makes sure we don't get into an
16592        // infinite recursion.
16593        app.adjSeq = mAdjSeq;
16594        app.curRawAdj = adj;
16595        app.hasStartedServices = false;
16596
16597        if (mBackupTarget != null && app == mBackupTarget.app) {
16598            // If possible we want to avoid killing apps while they're being backed up
16599            if (adj > ProcessList.BACKUP_APP_ADJ) {
16600                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16601                adj = ProcessList.BACKUP_APP_ADJ;
16602                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16603                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16604                }
16605                app.adjType = "backup";
16606                app.cached = false;
16607            }
16608            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16609                procState = ActivityManager.PROCESS_STATE_BACKUP;
16610            }
16611        }
16612
16613        boolean mayBeTop = false;
16614
16615        for (int is = app.services.size()-1;
16616                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16617                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16618                        || procState > ActivityManager.PROCESS_STATE_TOP);
16619                is--) {
16620            ServiceRecord s = app.services.valueAt(is);
16621            if (s.startRequested) {
16622                app.hasStartedServices = true;
16623                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16624                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16625                }
16626                if (app.hasShownUi && app != mHomeProcess) {
16627                    // If this process has shown some UI, let it immediately
16628                    // go to the LRU list because it may be pretty heavy with
16629                    // UI stuff.  We'll tag it with a label just to help
16630                    // debug and understand what is going on.
16631                    if (adj > ProcessList.SERVICE_ADJ) {
16632                        app.adjType = "cch-started-ui-services";
16633                    }
16634                } else {
16635                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16636                        // This service has seen some activity within
16637                        // recent memory, so we will keep its process ahead
16638                        // of the background processes.
16639                        if (adj > ProcessList.SERVICE_ADJ) {
16640                            adj = ProcessList.SERVICE_ADJ;
16641                            app.adjType = "started-services";
16642                            app.cached = false;
16643                        }
16644                    }
16645                    // If we have let the service slide into the background
16646                    // state, still have some text describing what it is doing
16647                    // even though the service no longer has an impact.
16648                    if (adj > ProcessList.SERVICE_ADJ) {
16649                        app.adjType = "cch-started-services";
16650                    }
16651                }
16652            }
16653            for (int conni = s.connections.size()-1;
16654                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16655                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16656                            || procState > ActivityManager.PROCESS_STATE_TOP);
16657                    conni--) {
16658                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16659                for (int i = 0;
16660                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16661                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16662                                || procState > ActivityManager.PROCESS_STATE_TOP);
16663                        i++) {
16664                    // XXX should compute this based on the max of
16665                    // all connected clients.
16666                    ConnectionRecord cr = clist.get(i);
16667                    if (cr.binding.client == app) {
16668                        // Binding to ourself is not interesting.
16669                        continue;
16670                    }
16671                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16672                        ProcessRecord client = cr.binding.client;
16673                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16674                                TOP_APP, doingAll, now);
16675                        int clientProcState = client.curProcState;
16676                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16677                            // If the other app is cached for any reason, for purposes here
16678                            // we are going to consider it empty.  The specific cached state
16679                            // doesn't propagate except under certain conditions.
16680                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16681                        }
16682                        String adjType = null;
16683                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16684                            // Not doing bind OOM management, so treat
16685                            // this guy more like a started service.
16686                            if (app.hasShownUi && app != mHomeProcess) {
16687                                // If this process has shown some UI, let it immediately
16688                                // go to the LRU list because it may be pretty heavy with
16689                                // UI stuff.  We'll tag it with a label just to help
16690                                // debug and understand what is going on.
16691                                if (adj > clientAdj) {
16692                                    adjType = "cch-bound-ui-services";
16693                                }
16694                                app.cached = false;
16695                                clientAdj = adj;
16696                                clientProcState = procState;
16697                            } else {
16698                                if (now >= (s.lastActivity
16699                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16700                                    // This service has not seen activity within
16701                                    // recent memory, so allow it to drop to the
16702                                    // LRU list if there is no other reason to keep
16703                                    // it around.  We'll also tag it with a label just
16704                                    // to help debug and undertand what is going on.
16705                                    if (adj > clientAdj) {
16706                                        adjType = "cch-bound-services";
16707                                    }
16708                                    clientAdj = adj;
16709                                }
16710                            }
16711                        }
16712                        if (adj > clientAdj) {
16713                            // If this process has recently shown UI, and
16714                            // the process that is binding to it is less
16715                            // important than being visible, then we don't
16716                            // care about the binding as much as we care
16717                            // about letting this process get into the LRU
16718                            // list to be killed and restarted if needed for
16719                            // memory.
16720                            if (app.hasShownUi && app != mHomeProcess
16721                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16722                                adjType = "cch-bound-ui-services";
16723                            } else {
16724                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16725                                        |Context.BIND_IMPORTANT)) != 0) {
16726                                    adj = clientAdj;
16727                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16728                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16729                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16730                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16731                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16732                                    adj = clientAdj;
16733                                } else {
16734                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16735                                        adj = ProcessList.VISIBLE_APP_ADJ;
16736                                    }
16737                                }
16738                                if (!client.cached) {
16739                                    app.cached = false;
16740                                }
16741                                adjType = "service";
16742                            }
16743                        }
16744                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16745                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16746                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16747                            }
16748                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16749                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16750                                    // Special handling of clients who are in the top state.
16751                                    // We *may* want to consider this process to be in the
16752                                    // top state as well, but only if there is not another
16753                                    // reason for it to be running.  Being on the top is a
16754                                    // special state, meaning you are specifically running
16755                                    // for the current top app.  If the process is already
16756                                    // running in the background for some other reason, it
16757                                    // is more important to continue considering it to be
16758                                    // in the background state.
16759                                    mayBeTop = true;
16760                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16761                                } else {
16762                                    // Special handling for above-top states (persistent
16763                                    // processes).  These should not bring the current process
16764                                    // into the top state, since they are not on top.  Instead
16765                                    // give them the best state after that.
16766                                    clientProcState =
16767                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16768                                }
16769                            }
16770                        } else {
16771                            if (clientProcState <
16772                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16773                                clientProcState =
16774                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16775                            }
16776                        }
16777                        if (procState > clientProcState) {
16778                            procState = clientProcState;
16779                        }
16780                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16781                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16782                            app.pendingUiClean = true;
16783                        }
16784                        if (adjType != null) {
16785                            app.adjType = adjType;
16786                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16787                                    .REASON_SERVICE_IN_USE;
16788                            app.adjSource = cr.binding.client;
16789                            app.adjSourceProcState = clientProcState;
16790                            app.adjTarget = s.name;
16791                        }
16792                    }
16793                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16794                        app.treatLikeActivity = true;
16795                    }
16796                    final ActivityRecord a = cr.activity;
16797                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16798                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16799                                (a.visible || a.state == ActivityState.RESUMED
16800                                 || a.state == ActivityState.PAUSING)) {
16801                            adj = ProcessList.FOREGROUND_APP_ADJ;
16802                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16803                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16804                            }
16805                            app.cached = false;
16806                            app.adjType = "service";
16807                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16808                                    .REASON_SERVICE_IN_USE;
16809                            app.adjSource = a;
16810                            app.adjSourceProcState = procState;
16811                            app.adjTarget = s.name;
16812                        }
16813                    }
16814                }
16815            }
16816        }
16817
16818        for (int provi = app.pubProviders.size()-1;
16819                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16820                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16821                        || procState > ActivityManager.PROCESS_STATE_TOP);
16822                provi--) {
16823            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16824            for (int i = cpr.connections.size()-1;
16825                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16826                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16827                            || procState > ActivityManager.PROCESS_STATE_TOP);
16828                    i--) {
16829                ContentProviderConnection conn = cpr.connections.get(i);
16830                ProcessRecord client = conn.client;
16831                if (client == app) {
16832                    // Being our own client is not interesting.
16833                    continue;
16834                }
16835                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16836                int clientProcState = client.curProcState;
16837                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16838                    // If the other app is cached for any reason, for purposes here
16839                    // we are going to consider it empty.
16840                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16841                }
16842                if (adj > clientAdj) {
16843                    if (app.hasShownUi && app != mHomeProcess
16844                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16845                        app.adjType = "cch-ui-provider";
16846                    } else {
16847                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16848                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16849                        app.adjType = "provider";
16850                    }
16851                    app.cached &= client.cached;
16852                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16853                            .REASON_PROVIDER_IN_USE;
16854                    app.adjSource = client;
16855                    app.adjSourceProcState = clientProcState;
16856                    app.adjTarget = cpr.name;
16857                }
16858                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16859                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16860                        // Special handling of clients who are in the top state.
16861                        // We *may* want to consider this process to be in the
16862                        // top state as well, but only if there is not another
16863                        // reason for it to be running.  Being on the top is a
16864                        // special state, meaning you are specifically running
16865                        // for the current top app.  If the process is already
16866                        // running in the background for some other reason, it
16867                        // is more important to continue considering it to be
16868                        // in the background state.
16869                        mayBeTop = true;
16870                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16871                    } else {
16872                        // Special handling for above-top states (persistent
16873                        // processes).  These should not bring the current process
16874                        // into the top state, since they are not on top.  Instead
16875                        // give them the best state after that.
16876                        clientProcState =
16877                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16878                    }
16879                }
16880                if (procState > clientProcState) {
16881                    procState = clientProcState;
16882                }
16883                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16884                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16885                }
16886            }
16887            // If the provider has external (non-framework) process
16888            // dependencies, ensure that its adjustment is at least
16889            // FOREGROUND_APP_ADJ.
16890            if (cpr.hasExternalProcessHandles()) {
16891                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16892                    adj = ProcessList.FOREGROUND_APP_ADJ;
16893                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16894                    app.cached = false;
16895                    app.adjType = "provider";
16896                    app.adjTarget = cpr.name;
16897                }
16898                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16899                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16900                }
16901            }
16902        }
16903
16904        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16905            // A client of one of our services or providers is in the top state.  We
16906            // *may* want to be in the top state, but not if we are already running in
16907            // the background for some other reason.  For the decision here, we are going
16908            // to pick out a few specific states that we want to remain in when a client
16909            // is top (states that tend to be longer-term) and otherwise allow it to go
16910            // to the top state.
16911            switch (procState) {
16912                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16913                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16914                case ActivityManager.PROCESS_STATE_SERVICE:
16915                    // These all are longer-term states, so pull them up to the top
16916                    // of the background states, but not all the way to the top state.
16917                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16918                    break;
16919                default:
16920                    // Otherwise, top is a better choice, so take it.
16921                    procState = ActivityManager.PROCESS_STATE_TOP;
16922                    break;
16923            }
16924        }
16925
16926        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16927            if (app.hasClientActivities) {
16928                // This is a cached process, but with client activities.  Mark it so.
16929                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16930                app.adjType = "cch-client-act";
16931            } else if (app.treatLikeActivity) {
16932                // This is a cached process, but somebody wants us to treat it like it has
16933                // an activity, okay!
16934                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16935                app.adjType = "cch-as-act";
16936            }
16937        }
16938
16939        if (adj == ProcessList.SERVICE_ADJ) {
16940            if (doingAll) {
16941                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16942                mNewNumServiceProcs++;
16943                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16944                if (!app.serviceb) {
16945                    // This service isn't far enough down on the LRU list to
16946                    // normally be a B service, but if we are low on RAM and it
16947                    // is large we want to force it down since we would prefer to
16948                    // keep launcher over it.
16949                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16950                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16951                        app.serviceHighRam = true;
16952                        app.serviceb = true;
16953                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16954                    } else {
16955                        mNewNumAServiceProcs++;
16956                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16957                    }
16958                } else {
16959                    app.serviceHighRam = false;
16960                }
16961            }
16962            if (app.serviceb) {
16963                adj = ProcessList.SERVICE_B_ADJ;
16964            }
16965        }
16966
16967        app.curRawAdj = adj;
16968
16969        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16970        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16971        if (adj > app.maxAdj) {
16972            adj = app.maxAdj;
16973            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16974                schedGroup = Process.THREAD_GROUP_DEFAULT;
16975            }
16976        }
16977
16978        // Do final modification to adj.  Everything we do between here and applying
16979        // the final setAdj must be done in this function, because we will also use
16980        // it when computing the final cached adj later.  Note that we don't need to
16981        // worry about this for max adj above, since max adj will always be used to
16982        // keep it out of the cached vaues.
16983        app.curAdj = app.modifyRawOomAdj(adj);
16984        app.curSchedGroup = schedGroup;
16985        app.curProcState = procState;
16986        app.foregroundActivities = foregroundActivities;
16987
16988        return app.curRawAdj;
16989    }
16990
16991    /**
16992     * Schedule PSS collection of a process.
16993     */
16994    void requestPssLocked(ProcessRecord proc, int procState) {
16995        if (mPendingPssProcesses.contains(proc)) {
16996            return;
16997        }
16998        if (mPendingPssProcesses.size() == 0) {
16999            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17000        }
17001        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17002        proc.pssProcState = procState;
17003        mPendingPssProcesses.add(proc);
17004    }
17005
17006    /**
17007     * Schedule PSS collection of all processes.
17008     */
17009    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17010        if (!always) {
17011            if (now < (mLastFullPssTime +
17012                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17013                return;
17014            }
17015        }
17016        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17017        mLastFullPssTime = now;
17018        mFullPssPending = true;
17019        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17020        mPendingPssProcesses.clear();
17021        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17022            ProcessRecord app = mLruProcesses.get(i);
17023            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17024                app.pssProcState = app.setProcState;
17025                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17026                        isSleeping(), now);
17027                mPendingPssProcesses.add(app);
17028            }
17029        }
17030        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17031    }
17032
17033    /**
17034     * Ask a given process to GC right now.
17035     */
17036    final void performAppGcLocked(ProcessRecord app) {
17037        try {
17038            app.lastRequestedGc = SystemClock.uptimeMillis();
17039            if (app.thread != null) {
17040                if (app.reportLowMemory) {
17041                    app.reportLowMemory = false;
17042                    app.thread.scheduleLowMemory();
17043                } else {
17044                    app.thread.processInBackground();
17045                }
17046            }
17047        } catch (Exception e) {
17048            // whatever.
17049        }
17050    }
17051
17052    /**
17053     * Returns true if things are idle enough to perform GCs.
17054     */
17055    private final boolean canGcNowLocked() {
17056        boolean processingBroadcasts = false;
17057        for (BroadcastQueue q : mBroadcastQueues) {
17058            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17059                processingBroadcasts = true;
17060            }
17061        }
17062        return !processingBroadcasts
17063                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17064    }
17065
17066    /**
17067     * Perform GCs on all processes that are waiting for it, but only
17068     * if things are idle.
17069     */
17070    final void performAppGcsLocked() {
17071        final int N = mProcessesToGc.size();
17072        if (N <= 0) {
17073            return;
17074        }
17075        if (canGcNowLocked()) {
17076            while (mProcessesToGc.size() > 0) {
17077                ProcessRecord proc = mProcessesToGc.remove(0);
17078                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17079                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17080                            <= SystemClock.uptimeMillis()) {
17081                        // To avoid spamming the system, we will GC processes one
17082                        // at a time, waiting a few seconds between each.
17083                        performAppGcLocked(proc);
17084                        scheduleAppGcsLocked();
17085                        return;
17086                    } else {
17087                        // It hasn't been long enough since we last GCed this
17088                        // process...  put it in the list to wait for its time.
17089                        addProcessToGcListLocked(proc);
17090                        break;
17091                    }
17092                }
17093            }
17094
17095            scheduleAppGcsLocked();
17096        }
17097    }
17098
17099    /**
17100     * If all looks good, perform GCs on all processes waiting for them.
17101     */
17102    final void performAppGcsIfAppropriateLocked() {
17103        if (canGcNowLocked()) {
17104            performAppGcsLocked();
17105            return;
17106        }
17107        // Still not idle, wait some more.
17108        scheduleAppGcsLocked();
17109    }
17110
17111    /**
17112     * Schedule the execution of all pending app GCs.
17113     */
17114    final void scheduleAppGcsLocked() {
17115        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17116
17117        if (mProcessesToGc.size() > 0) {
17118            // Schedule a GC for the time to the next process.
17119            ProcessRecord proc = mProcessesToGc.get(0);
17120            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17121
17122            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17123            long now = SystemClock.uptimeMillis();
17124            if (when < (now+GC_TIMEOUT)) {
17125                when = now + GC_TIMEOUT;
17126            }
17127            mHandler.sendMessageAtTime(msg, when);
17128        }
17129    }
17130
17131    /**
17132     * Add a process to the array of processes waiting to be GCed.  Keeps the
17133     * list in sorted order by the last GC time.  The process can't already be
17134     * on the list.
17135     */
17136    final void addProcessToGcListLocked(ProcessRecord proc) {
17137        boolean added = false;
17138        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17139            if (mProcessesToGc.get(i).lastRequestedGc <
17140                    proc.lastRequestedGc) {
17141                added = true;
17142                mProcessesToGc.add(i+1, proc);
17143                break;
17144            }
17145        }
17146        if (!added) {
17147            mProcessesToGc.add(0, proc);
17148        }
17149    }
17150
17151    /**
17152     * Set up to ask a process to GC itself.  This will either do it
17153     * immediately, or put it on the list of processes to gc the next
17154     * time things are idle.
17155     */
17156    final void scheduleAppGcLocked(ProcessRecord app) {
17157        long now = SystemClock.uptimeMillis();
17158        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17159            return;
17160        }
17161        if (!mProcessesToGc.contains(app)) {
17162            addProcessToGcListLocked(app);
17163            scheduleAppGcsLocked();
17164        }
17165    }
17166
17167    final void checkExcessivePowerUsageLocked(boolean doKills) {
17168        updateCpuStatsNow();
17169
17170        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17171        boolean doWakeKills = doKills;
17172        boolean doCpuKills = doKills;
17173        if (mLastPowerCheckRealtime == 0) {
17174            doWakeKills = false;
17175        }
17176        if (mLastPowerCheckUptime == 0) {
17177            doCpuKills = false;
17178        }
17179        if (stats.isScreenOn()) {
17180            doWakeKills = false;
17181        }
17182        final long curRealtime = SystemClock.elapsedRealtime();
17183        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17184        final long curUptime = SystemClock.uptimeMillis();
17185        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17186        mLastPowerCheckRealtime = curRealtime;
17187        mLastPowerCheckUptime = curUptime;
17188        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17189            doWakeKills = false;
17190        }
17191        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17192            doCpuKills = false;
17193        }
17194        int i = mLruProcesses.size();
17195        while (i > 0) {
17196            i--;
17197            ProcessRecord app = mLruProcesses.get(i);
17198            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17199                long wtime;
17200                synchronized (stats) {
17201                    wtime = stats.getProcessWakeTime(app.info.uid,
17202                            app.pid, curRealtime);
17203                }
17204                long wtimeUsed = wtime - app.lastWakeTime;
17205                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17206                if (DEBUG_POWER) {
17207                    StringBuilder sb = new StringBuilder(128);
17208                    sb.append("Wake for ");
17209                    app.toShortString(sb);
17210                    sb.append(": over ");
17211                    TimeUtils.formatDuration(realtimeSince, sb);
17212                    sb.append(" used ");
17213                    TimeUtils.formatDuration(wtimeUsed, sb);
17214                    sb.append(" (");
17215                    sb.append((wtimeUsed*100)/realtimeSince);
17216                    sb.append("%)");
17217                    Slog.i(TAG, sb.toString());
17218                    sb.setLength(0);
17219                    sb.append("CPU for ");
17220                    app.toShortString(sb);
17221                    sb.append(": over ");
17222                    TimeUtils.formatDuration(uptimeSince, sb);
17223                    sb.append(" used ");
17224                    TimeUtils.formatDuration(cputimeUsed, sb);
17225                    sb.append(" (");
17226                    sb.append((cputimeUsed*100)/uptimeSince);
17227                    sb.append("%)");
17228                    Slog.i(TAG, sb.toString());
17229                }
17230                // If a process has held a wake lock for more
17231                // than 50% of the time during this period,
17232                // that sounds bad.  Kill!
17233                if (doWakeKills && realtimeSince > 0
17234                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17235                    synchronized (stats) {
17236                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17237                                realtimeSince, wtimeUsed);
17238                    }
17239                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17240                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17241                } else if (doCpuKills && uptimeSince > 0
17242                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17243                    synchronized (stats) {
17244                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17245                                uptimeSince, cputimeUsed);
17246                    }
17247                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17248                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17249                } else {
17250                    app.lastWakeTime = wtime;
17251                    app.lastCpuTime = app.curCpuTime;
17252                }
17253            }
17254        }
17255    }
17256
17257    private final boolean applyOomAdjLocked(ProcessRecord app,
17258            ProcessRecord TOP_APP, boolean doingAll, long now) {
17259        boolean success = true;
17260
17261        if (app.curRawAdj != app.setRawAdj) {
17262            app.setRawAdj = app.curRawAdj;
17263        }
17264
17265        int changes = 0;
17266
17267        if (app.curAdj != app.setAdj) {
17268            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17269            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17270                TAG, "Set " + app.pid + " " + app.processName +
17271                " adj " + app.curAdj + ": " + app.adjType);
17272            app.setAdj = app.curAdj;
17273        }
17274
17275        if (app.setSchedGroup != app.curSchedGroup) {
17276            app.setSchedGroup = app.curSchedGroup;
17277            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17278                    "Setting process group of " + app.processName
17279                    + " to " + app.curSchedGroup);
17280            if (app.waitingToKill != null &&
17281                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17282                app.kill(app.waitingToKill, true);
17283                success = false;
17284            } else {
17285                if (true) {
17286                    long oldId = Binder.clearCallingIdentity();
17287                    try {
17288                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17289                    } catch (Exception e) {
17290                        Slog.w(TAG, "Failed setting process group of " + app.pid
17291                                + " to " + app.curSchedGroup);
17292                        e.printStackTrace();
17293                    } finally {
17294                        Binder.restoreCallingIdentity(oldId);
17295                    }
17296                } else {
17297                    if (app.thread != null) {
17298                        try {
17299                            app.thread.setSchedulingGroup(app.curSchedGroup);
17300                        } catch (RemoteException e) {
17301                        }
17302                    }
17303                }
17304                Process.setSwappiness(app.pid,
17305                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17306            }
17307        }
17308        if (app.repForegroundActivities != app.foregroundActivities) {
17309            app.repForegroundActivities = app.foregroundActivities;
17310            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17311        }
17312        if (app.repProcState != app.curProcState) {
17313            app.repProcState = app.curProcState;
17314            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17315            if (app.thread != null) {
17316                try {
17317                    if (false) {
17318                        //RuntimeException h = new RuntimeException("here");
17319                        Slog.i(TAG, "Sending new process state " + app.repProcState
17320                                + " to " + app /*, h*/);
17321                    }
17322                    app.thread.setProcessState(app.repProcState);
17323                } catch (RemoteException e) {
17324                }
17325            }
17326        }
17327        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17328                app.setProcState)) {
17329            app.lastStateTime = now;
17330            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17331                    isSleeping(), now);
17332            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17333                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17334                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17335                    + (app.nextPssTime-now) + ": " + app);
17336        } else {
17337            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17338                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17339                requestPssLocked(app, app.setProcState);
17340                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17341                        isSleeping(), now);
17342            } else if (false && DEBUG_PSS) {
17343                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17344            }
17345        }
17346        if (app.setProcState != app.curProcState) {
17347            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17348                    "Proc state change of " + app.processName
17349                    + " to " + app.curProcState);
17350            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17351            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17352            if (setImportant && !curImportant) {
17353                // This app is no longer something we consider important enough to allow to
17354                // use arbitrary amounts of battery power.  Note
17355                // its current wake lock time to later know to kill it if
17356                // it is not behaving well.
17357                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17358                synchronized (stats) {
17359                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17360                            app.pid, SystemClock.elapsedRealtime());
17361                }
17362                app.lastCpuTime = app.curCpuTime;
17363
17364            }
17365            app.setProcState = app.curProcState;
17366            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17367                app.notCachedSinceIdle = false;
17368            }
17369            if (!doingAll) {
17370                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17371            } else {
17372                app.procStateChanged = true;
17373            }
17374        }
17375
17376        if (changes != 0) {
17377            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17378            int i = mPendingProcessChanges.size()-1;
17379            ProcessChangeItem item = null;
17380            while (i >= 0) {
17381                item = mPendingProcessChanges.get(i);
17382                if (item.pid == app.pid) {
17383                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17384                    break;
17385                }
17386                i--;
17387            }
17388            if (i < 0) {
17389                // No existing item in pending changes; need a new one.
17390                final int NA = mAvailProcessChanges.size();
17391                if (NA > 0) {
17392                    item = mAvailProcessChanges.remove(NA-1);
17393                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17394                } else {
17395                    item = new ProcessChangeItem();
17396                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17397                }
17398                item.changes = 0;
17399                item.pid = app.pid;
17400                item.uid = app.info.uid;
17401                if (mPendingProcessChanges.size() == 0) {
17402                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17403                            "*** Enqueueing dispatch processes changed!");
17404                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17405                }
17406                mPendingProcessChanges.add(item);
17407            }
17408            item.changes |= changes;
17409            item.processState = app.repProcState;
17410            item.foregroundActivities = app.repForegroundActivities;
17411            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17412                    + Integer.toHexString(System.identityHashCode(item))
17413                    + " " + app.toShortString() + ": changes=" + item.changes
17414                    + " procState=" + item.processState
17415                    + " foreground=" + item.foregroundActivities
17416                    + " type=" + app.adjType + " source=" + app.adjSource
17417                    + " target=" + app.adjTarget);
17418        }
17419
17420        return success;
17421    }
17422
17423    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17424        if (proc.thread != null) {
17425            if (proc.baseProcessTracker != null) {
17426                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17427            }
17428            if (proc.repProcState >= 0) {
17429                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17430                        proc.repProcState);
17431            }
17432        }
17433    }
17434
17435    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17436            ProcessRecord TOP_APP, boolean doingAll, long now) {
17437        if (app.thread == null) {
17438            return false;
17439        }
17440
17441        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17442
17443        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17444    }
17445
17446    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17447            boolean oomAdj) {
17448        if (isForeground != proc.foregroundServices) {
17449            proc.foregroundServices = isForeground;
17450            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17451                    proc.info.uid);
17452            if (isForeground) {
17453                if (curProcs == null) {
17454                    curProcs = new ArrayList<ProcessRecord>();
17455                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17456                }
17457                if (!curProcs.contains(proc)) {
17458                    curProcs.add(proc);
17459                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17460                            proc.info.packageName, proc.info.uid);
17461                }
17462            } else {
17463                if (curProcs != null) {
17464                    if (curProcs.remove(proc)) {
17465                        mBatteryStatsService.noteEvent(
17466                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17467                                proc.info.packageName, proc.info.uid);
17468                        if (curProcs.size() <= 0) {
17469                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17470                        }
17471                    }
17472                }
17473            }
17474            if (oomAdj) {
17475                updateOomAdjLocked();
17476            }
17477        }
17478    }
17479
17480    private final ActivityRecord resumedAppLocked() {
17481        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17482        String pkg;
17483        int uid;
17484        if (act != null) {
17485            pkg = act.packageName;
17486            uid = act.info.applicationInfo.uid;
17487        } else {
17488            pkg = null;
17489            uid = -1;
17490        }
17491        // Has the UID or resumed package name changed?
17492        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17493                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17494            if (mCurResumedPackage != null) {
17495                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17496                        mCurResumedPackage, mCurResumedUid);
17497            }
17498            mCurResumedPackage = pkg;
17499            mCurResumedUid = uid;
17500            if (mCurResumedPackage != null) {
17501                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17502                        mCurResumedPackage, mCurResumedUid);
17503            }
17504        }
17505        return act;
17506    }
17507
17508    final boolean updateOomAdjLocked(ProcessRecord app) {
17509        final ActivityRecord TOP_ACT = resumedAppLocked();
17510        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17511        final boolean wasCached = app.cached;
17512
17513        mAdjSeq++;
17514
17515        // This is the desired cached adjusment we want to tell it to use.
17516        // If our app is currently cached, we know it, and that is it.  Otherwise,
17517        // we don't know it yet, and it needs to now be cached we will then
17518        // need to do a complete oom adj.
17519        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17520                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17521        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17522                SystemClock.uptimeMillis());
17523        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17524            // Changed to/from cached state, so apps after it in the LRU
17525            // list may also be changed.
17526            updateOomAdjLocked();
17527        }
17528        return success;
17529    }
17530
17531    final void updateOomAdjLocked() {
17532        final ActivityRecord TOP_ACT = resumedAppLocked();
17533        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17534        final long now = SystemClock.uptimeMillis();
17535        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17536        final int N = mLruProcesses.size();
17537
17538        if (false) {
17539            RuntimeException e = new RuntimeException();
17540            e.fillInStackTrace();
17541            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17542        }
17543
17544        mAdjSeq++;
17545        mNewNumServiceProcs = 0;
17546        mNewNumAServiceProcs = 0;
17547
17548        final int emptyProcessLimit;
17549        final int cachedProcessLimit;
17550        if (mProcessLimit <= 0) {
17551            emptyProcessLimit = cachedProcessLimit = 0;
17552        } else if (mProcessLimit == 1) {
17553            emptyProcessLimit = 1;
17554            cachedProcessLimit = 0;
17555        } else {
17556            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17557            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17558        }
17559
17560        // Let's determine how many processes we have running vs.
17561        // how many slots we have for background processes; we may want
17562        // to put multiple processes in a slot of there are enough of
17563        // them.
17564        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17565                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17566        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17567        if (numEmptyProcs > cachedProcessLimit) {
17568            // If there are more empty processes than our limit on cached
17569            // processes, then use the cached process limit for the factor.
17570            // This ensures that the really old empty processes get pushed
17571            // down to the bottom, so if we are running low on memory we will
17572            // have a better chance at keeping around more cached processes
17573            // instead of a gazillion empty processes.
17574            numEmptyProcs = cachedProcessLimit;
17575        }
17576        int emptyFactor = numEmptyProcs/numSlots;
17577        if (emptyFactor < 1) emptyFactor = 1;
17578        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17579        if (cachedFactor < 1) cachedFactor = 1;
17580        int stepCached = 0;
17581        int stepEmpty = 0;
17582        int numCached = 0;
17583        int numEmpty = 0;
17584        int numTrimming = 0;
17585
17586        mNumNonCachedProcs = 0;
17587        mNumCachedHiddenProcs = 0;
17588
17589        // First update the OOM adjustment for each of the
17590        // application processes based on their current state.
17591        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17592        int nextCachedAdj = curCachedAdj+1;
17593        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17594        int nextEmptyAdj = curEmptyAdj+2;
17595        for (int i=N-1; i>=0; i--) {
17596            ProcessRecord app = mLruProcesses.get(i);
17597            if (!app.killedByAm && app.thread != null) {
17598                app.procStateChanged = false;
17599                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17600
17601                // If we haven't yet assigned the final cached adj
17602                // to the process, do that now.
17603                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17604                    switch (app.curProcState) {
17605                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17606                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17607                            // This process is a cached process holding activities...
17608                            // assign it the next cached value for that type, and then
17609                            // step that cached level.
17610                            app.curRawAdj = curCachedAdj;
17611                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17612                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17613                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17614                                    + ")");
17615                            if (curCachedAdj != nextCachedAdj) {
17616                                stepCached++;
17617                                if (stepCached >= cachedFactor) {
17618                                    stepCached = 0;
17619                                    curCachedAdj = nextCachedAdj;
17620                                    nextCachedAdj += 2;
17621                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17622                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17623                                    }
17624                                }
17625                            }
17626                            break;
17627                        default:
17628                            // For everything else, assign next empty cached process
17629                            // level and bump that up.  Note that this means that
17630                            // long-running services that have dropped down to the
17631                            // cached level will be treated as empty (since their process
17632                            // state is still as a service), which is what we want.
17633                            app.curRawAdj = curEmptyAdj;
17634                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17635                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17636                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17637                                    + ")");
17638                            if (curEmptyAdj != nextEmptyAdj) {
17639                                stepEmpty++;
17640                                if (stepEmpty >= emptyFactor) {
17641                                    stepEmpty = 0;
17642                                    curEmptyAdj = nextEmptyAdj;
17643                                    nextEmptyAdj += 2;
17644                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17645                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17646                                    }
17647                                }
17648                            }
17649                            break;
17650                    }
17651                }
17652
17653                applyOomAdjLocked(app, TOP_APP, true, now);
17654
17655                // Count the number of process types.
17656                switch (app.curProcState) {
17657                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17658                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17659                        mNumCachedHiddenProcs++;
17660                        numCached++;
17661                        if (numCached > cachedProcessLimit) {
17662                            app.kill("cached #" + numCached, true);
17663                        }
17664                        break;
17665                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17666                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17667                                && app.lastActivityTime < oldTime) {
17668                            app.kill("empty for "
17669                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17670                                    / 1000) + "s", true);
17671                        } else {
17672                            numEmpty++;
17673                            if (numEmpty > emptyProcessLimit) {
17674                                app.kill("empty #" + numEmpty, true);
17675                            }
17676                        }
17677                        break;
17678                    default:
17679                        mNumNonCachedProcs++;
17680                        break;
17681                }
17682
17683                if (app.isolated && app.services.size() <= 0) {
17684                    // If this is an isolated process, and there are no
17685                    // services running in it, then the process is no longer
17686                    // needed.  We agressively kill these because we can by
17687                    // definition not re-use the same process again, and it is
17688                    // good to avoid having whatever code was running in them
17689                    // left sitting around after no longer needed.
17690                    app.kill("isolated not needed", true);
17691                }
17692
17693                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17694                        && !app.killedByAm) {
17695                    numTrimming++;
17696                }
17697            }
17698        }
17699
17700        mNumServiceProcs = mNewNumServiceProcs;
17701
17702        // Now determine the memory trimming level of background processes.
17703        // Unfortunately we need to start at the back of the list to do this
17704        // properly.  We only do this if the number of background apps we
17705        // are managing to keep around is less than half the maximum we desire;
17706        // if we are keeping a good number around, we'll let them use whatever
17707        // memory they want.
17708        final int numCachedAndEmpty = numCached + numEmpty;
17709        int memFactor;
17710        if (numCached <= ProcessList.TRIM_CACHED_APPS
17711                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17712            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17713                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17714            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17715                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17716            } else {
17717                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17718            }
17719        } else {
17720            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17721        }
17722        // We always allow the memory level to go up (better).  We only allow it to go
17723        // down if we are in a state where that is allowed, *and* the total number of processes
17724        // has gone down since last time.
17725        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17726                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17727                + " last=" + mLastNumProcesses);
17728        if (memFactor > mLastMemoryLevel) {
17729            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17730                memFactor = mLastMemoryLevel;
17731                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17732            }
17733        }
17734        mLastMemoryLevel = memFactor;
17735        mLastNumProcesses = mLruProcesses.size();
17736        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17737        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17738        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17739            if (mLowRamStartTime == 0) {
17740                mLowRamStartTime = now;
17741            }
17742            int step = 0;
17743            int fgTrimLevel;
17744            switch (memFactor) {
17745                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17746                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17747                    break;
17748                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17749                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17750                    break;
17751                default:
17752                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17753                    break;
17754            }
17755            int factor = numTrimming/3;
17756            int minFactor = 2;
17757            if (mHomeProcess != null) minFactor++;
17758            if (mPreviousProcess != null) minFactor++;
17759            if (factor < minFactor) factor = minFactor;
17760            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17761            for (int i=N-1; i>=0; i--) {
17762                ProcessRecord app = mLruProcesses.get(i);
17763                if (allChanged || app.procStateChanged) {
17764                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17765                    app.procStateChanged = false;
17766                }
17767                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17768                        && !app.killedByAm) {
17769                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17770                        try {
17771                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17772                                    "Trimming memory of " + app.processName
17773                                    + " to " + curLevel);
17774                            app.thread.scheduleTrimMemory(curLevel);
17775                        } catch (RemoteException e) {
17776                        }
17777                        if (false) {
17778                            // For now we won't do this; our memory trimming seems
17779                            // to be good enough at this point that destroying
17780                            // activities causes more harm than good.
17781                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17782                                    && app != mHomeProcess && app != mPreviousProcess) {
17783                                // Need to do this on its own message because the stack may not
17784                                // be in a consistent state at this point.
17785                                // For these apps we will also finish their activities
17786                                // to help them free memory.
17787                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17788                            }
17789                        }
17790                    }
17791                    app.trimMemoryLevel = curLevel;
17792                    step++;
17793                    if (step >= factor) {
17794                        step = 0;
17795                        switch (curLevel) {
17796                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17797                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17798                                break;
17799                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17800                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17801                                break;
17802                        }
17803                    }
17804                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17805                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17806                            && app.thread != null) {
17807                        try {
17808                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17809                                    "Trimming memory of heavy-weight " + app.processName
17810                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17811                            app.thread.scheduleTrimMemory(
17812                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17813                        } catch (RemoteException e) {
17814                        }
17815                    }
17816                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17817                } else {
17818                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17819                            || app.systemNoUi) && app.pendingUiClean) {
17820                        // If this application is now in the background and it
17821                        // had done UI, then give it the special trim level to
17822                        // have it free UI resources.
17823                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17824                        if (app.trimMemoryLevel < level && app.thread != null) {
17825                            try {
17826                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17827                                        "Trimming memory of bg-ui " + app.processName
17828                                        + " to " + level);
17829                                app.thread.scheduleTrimMemory(level);
17830                            } catch (RemoteException e) {
17831                            }
17832                        }
17833                        app.pendingUiClean = false;
17834                    }
17835                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17836                        try {
17837                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17838                                    "Trimming memory of fg " + app.processName
17839                                    + " to " + fgTrimLevel);
17840                            app.thread.scheduleTrimMemory(fgTrimLevel);
17841                        } catch (RemoteException e) {
17842                        }
17843                    }
17844                    app.trimMemoryLevel = fgTrimLevel;
17845                }
17846            }
17847        } else {
17848            if (mLowRamStartTime != 0) {
17849                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17850                mLowRamStartTime = 0;
17851            }
17852            for (int i=N-1; i>=0; i--) {
17853                ProcessRecord app = mLruProcesses.get(i);
17854                if (allChanged || app.procStateChanged) {
17855                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17856                    app.procStateChanged = false;
17857                }
17858                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17859                        || app.systemNoUi) && app.pendingUiClean) {
17860                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17861                            && app.thread != null) {
17862                        try {
17863                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17864                                    "Trimming memory of ui hidden " + app.processName
17865                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17866                            app.thread.scheduleTrimMemory(
17867                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17868                        } catch (RemoteException e) {
17869                        }
17870                    }
17871                    app.pendingUiClean = false;
17872                }
17873                app.trimMemoryLevel = 0;
17874            }
17875        }
17876
17877        if (mAlwaysFinishActivities) {
17878            // Need to do this on its own message because the stack may not
17879            // be in a consistent state at this point.
17880            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17881        }
17882
17883        if (allChanged) {
17884            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17885        }
17886
17887        if (mProcessStats.shouldWriteNowLocked(now)) {
17888            mHandler.post(new Runnable() {
17889                @Override public void run() {
17890                    synchronized (ActivityManagerService.this) {
17891                        mProcessStats.writeStateAsyncLocked();
17892                    }
17893                }
17894            });
17895        }
17896
17897        if (DEBUG_OOM_ADJ) {
17898            if (false) {
17899                RuntimeException here = new RuntimeException("here");
17900                here.fillInStackTrace();
17901                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17902            } else {
17903                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17904            }
17905        }
17906    }
17907
17908    final void trimApplications() {
17909        synchronized (this) {
17910            int i;
17911
17912            // First remove any unused application processes whose package
17913            // has been removed.
17914            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17915                final ProcessRecord app = mRemovedProcesses.get(i);
17916                if (app.activities.size() == 0
17917                        && app.curReceiver == null && app.services.size() == 0) {
17918                    Slog.i(
17919                        TAG, "Exiting empty application process "
17920                        + app.processName + " ("
17921                        + (app.thread != null ? app.thread.asBinder() : null)
17922                        + ")\n");
17923                    if (app.pid > 0 && app.pid != MY_PID) {
17924                        app.kill("empty", false);
17925                    } else {
17926                        try {
17927                            app.thread.scheduleExit();
17928                        } catch (Exception e) {
17929                            // Ignore exceptions.
17930                        }
17931                    }
17932                    cleanUpApplicationRecordLocked(app, false, true, -1);
17933                    mRemovedProcesses.remove(i);
17934
17935                    if (app.persistent) {
17936                        addAppLocked(app.info, false, null /* ABI override */);
17937                    }
17938                }
17939            }
17940
17941            // Now update the oom adj for all processes.
17942            updateOomAdjLocked();
17943        }
17944    }
17945
17946    /** This method sends the specified signal to each of the persistent apps */
17947    public void signalPersistentProcesses(int sig) throws RemoteException {
17948        if (sig != Process.SIGNAL_USR1) {
17949            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17950        }
17951
17952        synchronized (this) {
17953            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17954                    != PackageManager.PERMISSION_GRANTED) {
17955                throw new SecurityException("Requires permission "
17956                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17957            }
17958
17959            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17960                ProcessRecord r = mLruProcesses.get(i);
17961                if (r.thread != null && r.persistent) {
17962                    Process.sendSignal(r.pid, sig);
17963                }
17964            }
17965        }
17966    }
17967
17968    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17969        if (proc == null || proc == mProfileProc) {
17970            proc = mProfileProc;
17971            profileType = mProfileType;
17972            clearProfilerLocked();
17973        }
17974        if (proc == null) {
17975            return;
17976        }
17977        try {
17978            proc.thread.profilerControl(false, null, profileType);
17979        } catch (RemoteException e) {
17980            throw new IllegalStateException("Process disappeared");
17981        }
17982    }
17983
17984    private void clearProfilerLocked() {
17985        if (mProfileFd != null) {
17986            try {
17987                mProfileFd.close();
17988            } catch (IOException e) {
17989            }
17990        }
17991        mProfileApp = null;
17992        mProfileProc = null;
17993        mProfileFile = null;
17994        mProfileType = 0;
17995        mAutoStopProfiler = false;
17996        mSamplingInterval = 0;
17997    }
17998
17999    public boolean profileControl(String process, int userId, boolean start,
18000            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18001
18002        try {
18003            synchronized (this) {
18004                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18005                // its own permission.
18006                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18007                        != PackageManager.PERMISSION_GRANTED) {
18008                    throw new SecurityException("Requires permission "
18009                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18010                }
18011
18012                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18013                    throw new IllegalArgumentException("null profile info or fd");
18014                }
18015
18016                ProcessRecord proc = null;
18017                if (process != null) {
18018                    proc = findProcessLocked(process, userId, "profileControl");
18019                }
18020
18021                if (start && (proc == null || proc.thread == null)) {
18022                    throw new IllegalArgumentException("Unknown process: " + process);
18023                }
18024
18025                if (start) {
18026                    stopProfilerLocked(null, 0);
18027                    setProfileApp(proc.info, proc.processName, profilerInfo);
18028                    mProfileProc = proc;
18029                    mProfileType = profileType;
18030                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18031                    try {
18032                        fd = fd.dup();
18033                    } catch (IOException e) {
18034                        fd = null;
18035                    }
18036                    profilerInfo.profileFd = fd;
18037                    proc.thread.profilerControl(start, profilerInfo, profileType);
18038                    fd = null;
18039                    mProfileFd = null;
18040                } else {
18041                    stopProfilerLocked(proc, profileType);
18042                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18043                        try {
18044                            profilerInfo.profileFd.close();
18045                        } catch (IOException e) {
18046                        }
18047                    }
18048                }
18049
18050                return true;
18051            }
18052        } catch (RemoteException e) {
18053            throw new IllegalStateException("Process disappeared");
18054        } finally {
18055            if (profilerInfo != null && profilerInfo.profileFd != null) {
18056                try {
18057                    profilerInfo.profileFd.close();
18058                } catch (IOException e) {
18059                }
18060            }
18061        }
18062    }
18063
18064    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18065        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18066                userId, true, ALLOW_FULL_ONLY, callName, null);
18067        ProcessRecord proc = null;
18068        try {
18069            int pid = Integer.parseInt(process);
18070            synchronized (mPidsSelfLocked) {
18071                proc = mPidsSelfLocked.get(pid);
18072            }
18073        } catch (NumberFormatException e) {
18074        }
18075
18076        if (proc == null) {
18077            ArrayMap<String, SparseArray<ProcessRecord>> all
18078                    = mProcessNames.getMap();
18079            SparseArray<ProcessRecord> procs = all.get(process);
18080            if (procs != null && procs.size() > 0) {
18081                proc = procs.valueAt(0);
18082                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18083                    for (int i=1; i<procs.size(); i++) {
18084                        ProcessRecord thisProc = procs.valueAt(i);
18085                        if (thisProc.userId == userId) {
18086                            proc = thisProc;
18087                            break;
18088                        }
18089                    }
18090                }
18091            }
18092        }
18093
18094        return proc;
18095    }
18096
18097    public boolean dumpHeap(String process, int userId, boolean managed,
18098            String path, ParcelFileDescriptor fd) throws RemoteException {
18099
18100        try {
18101            synchronized (this) {
18102                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18103                // its own permission (same as profileControl).
18104                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18105                        != PackageManager.PERMISSION_GRANTED) {
18106                    throw new SecurityException("Requires permission "
18107                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18108                }
18109
18110                if (fd == null) {
18111                    throw new IllegalArgumentException("null fd");
18112                }
18113
18114                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18115                if (proc == null || proc.thread == null) {
18116                    throw new IllegalArgumentException("Unknown process: " + process);
18117                }
18118
18119                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18120                if (!isDebuggable) {
18121                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18122                        throw new SecurityException("Process not debuggable: " + proc);
18123                    }
18124                }
18125
18126                proc.thread.dumpHeap(managed, path, fd);
18127                fd = null;
18128                return true;
18129            }
18130        } catch (RemoteException e) {
18131            throw new IllegalStateException("Process disappeared");
18132        } finally {
18133            if (fd != null) {
18134                try {
18135                    fd.close();
18136                } catch (IOException e) {
18137                }
18138            }
18139        }
18140    }
18141
18142    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18143    public void monitor() {
18144        synchronized (this) { }
18145    }
18146
18147    void onCoreSettingsChange(Bundle settings) {
18148        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18149            ProcessRecord processRecord = mLruProcesses.get(i);
18150            try {
18151                if (processRecord.thread != null) {
18152                    processRecord.thread.setCoreSettings(settings);
18153                }
18154            } catch (RemoteException re) {
18155                /* ignore */
18156            }
18157        }
18158    }
18159
18160    // Multi-user methods
18161
18162    /**
18163     * Start user, if its not already running, but don't bring it to foreground.
18164     */
18165    @Override
18166    public boolean startUserInBackground(final int userId) {
18167        return startUser(userId, /* foreground */ false);
18168    }
18169
18170    /**
18171     * Start user, if its not already running, and bring it to foreground.
18172     */
18173    boolean startUserInForeground(final int userId, Dialog dlg) {
18174        boolean result = startUser(userId, /* foreground */ true);
18175        dlg.dismiss();
18176        return result;
18177    }
18178
18179    /**
18180     * Refreshes the list of users related to the current user when either a
18181     * user switch happens or when a new related user is started in the
18182     * background.
18183     */
18184    private void updateCurrentProfileIdsLocked() {
18185        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18186                mCurrentUserId, false /* enabledOnly */);
18187        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18188        for (int i = 0; i < currentProfileIds.length; i++) {
18189            currentProfileIds[i] = profiles.get(i).id;
18190        }
18191        mCurrentProfileIds = currentProfileIds;
18192
18193        synchronized (mUserProfileGroupIdsSelfLocked) {
18194            mUserProfileGroupIdsSelfLocked.clear();
18195            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18196            for (int i = 0; i < users.size(); i++) {
18197                UserInfo user = users.get(i);
18198                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18199                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18200                }
18201            }
18202        }
18203    }
18204
18205    private Set getProfileIdsLocked(int userId) {
18206        Set userIds = new HashSet<Integer>();
18207        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18208                userId, false /* enabledOnly */);
18209        for (UserInfo user : profiles) {
18210            userIds.add(Integer.valueOf(user.id));
18211        }
18212        return userIds;
18213    }
18214
18215    @Override
18216    public boolean switchUser(final int userId) {
18217        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18218        String userName;
18219        synchronized (this) {
18220            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18221            if (userInfo == null) {
18222                Slog.w(TAG, "No user info for user #" + userId);
18223                return false;
18224            }
18225            if (userInfo.isManagedProfile()) {
18226                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18227                return false;
18228            }
18229            userName = userInfo.name;
18230            mTargetUserId = userId;
18231        }
18232        mHandler.removeMessages(START_USER_SWITCH_MSG);
18233        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18234        return true;
18235    }
18236
18237    private void showUserSwitchDialog(int userId, String userName) {
18238        // The dialog will show and then initiate the user switch by calling startUserInForeground
18239        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18240                true /* above system */);
18241        d.show();
18242    }
18243
18244    private boolean startUser(final int userId, final boolean foreground) {
18245        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18246                != PackageManager.PERMISSION_GRANTED) {
18247            String msg = "Permission Denial: switchUser() from pid="
18248                    + Binder.getCallingPid()
18249                    + ", uid=" + Binder.getCallingUid()
18250                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18251            Slog.w(TAG, msg);
18252            throw new SecurityException(msg);
18253        }
18254
18255        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18256
18257        final long ident = Binder.clearCallingIdentity();
18258        try {
18259            synchronized (this) {
18260                final int oldUserId = mCurrentUserId;
18261                if (oldUserId == userId) {
18262                    return true;
18263                }
18264
18265                mStackSupervisor.setLockTaskModeLocked(null, false);
18266
18267                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18268                if (userInfo == null) {
18269                    Slog.w(TAG, "No user info for user #" + userId);
18270                    return false;
18271                }
18272                if (foreground && userInfo.isManagedProfile()) {
18273                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18274                    return false;
18275                }
18276
18277                if (foreground) {
18278                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18279                            R.anim.screen_user_enter);
18280                }
18281
18282                boolean needStart = false;
18283
18284                // If the user we are switching to is not currently started, then
18285                // we need to start it now.
18286                if (mStartedUsers.get(userId) == null) {
18287                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18288                    updateStartedUserArrayLocked();
18289                    needStart = true;
18290                }
18291
18292                final Integer userIdInt = Integer.valueOf(userId);
18293                mUserLru.remove(userIdInt);
18294                mUserLru.add(userIdInt);
18295
18296                if (foreground) {
18297                    mCurrentUserId = userId;
18298                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18299                    updateCurrentProfileIdsLocked();
18300                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18301                    // Once the internal notion of the active user has switched, we lock the device
18302                    // with the option to show the user switcher on the keyguard.
18303                    mWindowManager.lockNow(null);
18304                } else {
18305                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18306                    updateCurrentProfileIdsLocked();
18307                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18308                    mUserLru.remove(currentUserIdInt);
18309                    mUserLru.add(currentUserIdInt);
18310                }
18311
18312                final UserStartedState uss = mStartedUsers.get(userId);
18313
18314                // Make sure user is in the started state.  If it is currently
18315                // stopping, we need to knock that off.
18316                if (uss.mState == UserStartedState.STATE_STOPPING) {
18317                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18318                    // so we can just fairly silently bring the user back from
18319                    // the almost-dead.
18320                    uss.mState = UserStartedState.STATE_RUNNING;
18321                    updateStartedUserArrayLocked();
18322                    needStart = true;
18323                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18324                    // This means ACTION_SHUTDOWN has been sent, so we will
18325                    // need to treat this as a new boot of the user.
18326                    uss.mState = UserStartedState.STATE_BOOTING;
18327                    updateStartedUserArrayLocked();
18328                    needStart = true;
18329                }
18330
18331                if (uss.mState == UserStartedState.STATE_BOOTING) {
18332                    // Booting up a new user, need to tell system services about it.
18333                    // Note that this is on the same handler as scheduling of broadcasts,
18334                    // which is important because it needs to go first.
18335                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18336                }
18337
18338                if (foreground) {
18339                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18340                            oldUserId));
18341                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18342                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18343                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18344                            oldUserId, userId, uss));
18345                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18346                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18347                }
18348
18349                if (needStart) {
18350                    // Send USER_STARTED broadcast
18351                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18352                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18353                            | Intent.FLAG_RECEIVER_FOREGROUND);
18354                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18355                    broadcastIntentLocked(null, null, intent,
18356                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18357                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18358                }
18359
18360                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18361                    if (userId != UserHandle.USER_OWNER) {
18362                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18363                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18364                        broadcastIntentLocked(null, null, intent, null,
18365                                new IIntentReceiver.Stub() {
18366                                    public void performReceive(Intent intent, int resultCode,
18367                                            String data, Bundle extras, boolean ordered,
18368                                            boolean sticky, int sendingUser) {
18369                                        onUserInitialized(uss, foreground, oldUserId, userId);
18370                                    }
18371                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18372                                true, false, MY_PID, Process.SYSTEM_UID,
18373                                userId);
18374                        uss.initializing = true;
18375                    } else {
18376                        getUserManagerLocked().makeInitialized(userInfo.id);
18377                    }
18378                }
18379
18380                if (foreground) {
18381                    if (!uss.initializing) {
18382                        moveUserToForeground(uss, oldUserId, userId);
18383                    }
18384                } else {
18385                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18386                }
18387
18388                if (needStart) {
18389                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18390                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18391                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18392                    broadcastIntentLocked(null, null, intent,
18393                            null, new IIntentReceiver.Stub() {
18394                                @Override
18395                                public void performReceive(Intent intent, int resultCode, String data,
18396                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18397                                        throws RemoteException {
18398                                }
18399                            }, 0, null, null,
18400                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18401                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18402                }
18403            }
18404        } finally {
18405            Binder.restoreCallingIdentity(ident);
18406        }
18407
18408        return true;
18409    }
18410
18411    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18412        long ident = Binder.clearCallingIdentity();
18413        try {
18414            Intent intent;
18415            if (oldUserId >= 0) {
18416                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18417                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18418                int count = profiles.size();
18419                for (int i = 0; i < count; i++) {
18420                    int profileUserId = profiles.get(i).id;
18421                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18422                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18423                            | Intent.FLAG_RECEIVER_FOREGROUND);
18424                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18425                    broadcastIntentLocked(null, null, intent,
18426                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18427                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18428                }
18429            }
18430            if (newUserId >= 0) {
18431                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18432                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18433                int count = profiles.size();
18434                for (int i = 0; i < count; i++) {
18435                    int profileUserId = profiles.get(i).id;
18436                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18437                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18438                            | Intent.FLAG_RECEIVER_FOREGROUND);
18439                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18440                    broadcastIntentLocked(null, null, intent,
18441                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18442                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18443                }
18444                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18445                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18446                        | Intent.FLAG_RECEIVER_FOREGROUND);
18447                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18448                broadcastIntentLocked(null, null, intent,
18449                        null, null, 0, null, null,
18450                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18451                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18452            }
18453        } finally {
18454            Binder.restoreCallingIdentity(ident);
18455        }
18456    }
18457
18458    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18459            final int newUserId) {
18460        final int N = mUserSwitchObservers.beginBroadcast();
18461        if (N > 0) {
18462            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18463                int mCount = 0;
18464                @Override
18465                public void sendResult(Bundle data) throws RemoteException {
18466                    synchronized (ActivityManagerService.this) {
18467                        if (mCurUserSwitchCallback == this) {
18468                            mCount++;
18469                            if (mCount == N) {
18470                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18471                            }
18472                        }
18473                    }
18474                }
18475            };
18476            synchronized (this) {
18477                uss.switching = true;
18478                mCurUserSwitchCallback = callback;
18479            }
18480            for (int i=0; i<N; i++) {
18481                try {
18482                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18483                            newUserId, callback);
18484                } catch (RemoteException e) {
18485                }
18486            }
18487        } else {
18488            synchronized (this) {
18489                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18490            }
18491        }
18492        mUserSwitchObservers.finishBroadcast();
18493    }
18494
18495    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18496        synchronized (this) {
18497            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18498            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18499        }
18500    }
18501
18502    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18503        mCurUserSwitchCallback = null;
18504        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18505        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18506                oldUserId, newUserId, uss));
18507    }
18508
18509    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18510        synchronized (this) {
18511            if (foreground) {
18512                moveUserToForeground(uss, oldUserId, newUserId);
18513            }
18514        }
18515
18516        completeSwitchAndInitalize(uss, newUserId, true, false);
18517    }
18518
18519    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18520        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18521        if (homeInFront) {
18522            startHomeActivityLocked(newUserId);
18523        } else {
18524            mStackSupervisor.resumeTopActivitiesLocked();
18525        }
18526        EventLogTags.writeAmSwitchUser(newUserId);
18527        getUserManagerLocked().userForeground(newUserId);
18528        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18529    }
18530
18531    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18532        completeSwitchAndInitalize(uss, newUserId, false, true);
18533    }
18534
18535    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18536            boolean clearInitializing, boolean clearSwitching) {
18537        boolean unfrozen = false;
18538        synchronized (this) {
18539            if (clearInitializing) {
18540                uss.initializing = false;
18541                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18542            }
18543            if (clearSwitching) {
18544                uss.switching = false;
18545            }
18546            if (!uss.switching && !uss.initializing) {
18547                mWindowManager.stopFreezingScreen();
18548                unfrozen = true;
18549            }
18550        }
18551        if (unfrozen) {
18552            final int N = mUserSwitchObservers.beginBroadcast();
18553            for (int i=0; i<N; i++) {
18554                try {
18555                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18556                } catch (RemoteException e) {
18557                }
18558            }
18559            mUserSwitchObservers.finishBroadcast();
18560        }
18561    }
18562
18563    void scheduleStartProfilesLocked() {
18564        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18565            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18566                    DateUtils.SECOND_IN_MILLIS);
18567        }
18568    }
18569
18570    void startProfilesLocked() {
18571        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18572        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18573                mCurrentUserId, false /* enabledOnly */);
18574        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18575        for (UserInfo user : profiles) {
18576            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18577                    && user.id != mCurrentUserId) {
18578                toStart.add(user);
18579            }
18580        }
18581        final int n = toStart.size();
18582        int i = 0;
18583        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18584            startUserInBackground(toStart.get(i).id);
18585        }
18586        if (i < n) {
18587            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18588        }
18589    }
18590
18591    void finishUserBoot(UserStartedState uss) {
18592        synchronized (this) {
18593            if (uss.mState == UserStartedState.STATE_BOOTING
18594                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18595                uss.mState = UserStartedState.STATE_RUNNING;
18596                final int userId = uss.mHandle.getIdentifier();
18597                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18598                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18599                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18600                broadcastIntentLocked(null, null, intent,
18601                        null, null, 0, null, null,
18602                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18603                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18604            }
18605        }
18606    }
18607
18608    void finishUserSwitch(UserStartedState uss) {
18609        synchronized (this) {
18610            finishUserBoot(uss);
18611
18612            startProfilesLocked();
18613
18614            int num = mUserLru.size();
18615            int i = 0;
18616            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18617                Integer oldUserId = mUserLru.get(i);
18618                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18619                if (oldUss == null) {
18620                    // Shouldn't happen, but be sane if it does.
18621                    mUserLru.remove(i);
18622                    num--;
18623                    continue;
18624                }
18625                if (oldUss.mState == UserStartedState.STATE_STOPPING
18626                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18627                    // This user is already stopping, doesn't count.
18628                    num--;
18629                    i++;
18630                    continue;
18631                }
18632                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18633                    // Owner and current can't be stopped, but count as running.
18634                    i++;
18635                    continue;
18636                }
18637                // This is a user to be stopped.
18638                stopUserLocked(oldUserId, null);
18639                num--;
18640                i++;
18641            }
18642        }
18643    }
18644
18645    @Override
18646    public int stopUser(final int userId, final IStopUserCallback callback) {
18647        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18648                != PackageManager.PERMISSION_GRANTED) {
18649            String msg = "Permission Denial: switchUser() from pid="
18650                    + Binder.getCallingPid()
18651                    + ", uid=" + Binder.getCallingUid()
18652                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18653            Slog.w(TAG, msg);
18654            throw new SecurityException(msg);
18655        }
18656        if (userId <= 0) {
18657            throw new IllegalArgumentException("Can't stop primary user " + userId);
18658        }
18659        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18660        synchronized (this) {
18661            return stopUserLocked(userId, callback);
18662        }
18663    }
18664
18665    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18666        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18667        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18668            return ActivityManager.USER_OP_IS_CURRENT;
18669        }
18670
18671        final UserStartedState uss = mStartedUsers.get(userId);
18672        if (uss == null) {
18673            // User is not started, nothing to do...  but we do need to
18674            // callback if requested.
18675            if (callback != null) {
18676                mHandler.post(new Runnable() {
18677                    @Override
18678                    public void run() {
18679                        try {
18680                            callback.userStopped(userId);
18681                        } catch (RemoteException e) {
18682                        }
18683                    }
18684                });
18685            }
18686            return ActivityManager.USER_OP_SUCCESS;
18687        }
18688
18689        if (callback != null) {
18690            uss.mStopCallbacks.add(callback);
18691        }
18692
18693        if (uss.mState != UserStartedState.STATE_STOPPING
18694                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18695            uss.mState = UserStartedState.STATE_STOPPING;
18696            updateStartedUserArrayLocked();
18697
18698            long ident = Binder.clearCallingIdentity();
18699            try {
18700                // We are going to broadcast ACTION_USER_STOPPING and then
18701                // once that is done send a final ACTION_SHUTDOWN and then
18702                // stop the user.
18703                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18704                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18705                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18706                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18707                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18708                // This is the result receiver for the final shutdown broadcast.
18709                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18710                    @Override
18711                    public void performReceive(Intent intent, int resultCode, String data,
18712                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18713                        finishUserStop(uss);
18714                    }
18715                };
18716                // This is the result receiver for the initial stopping broadcast.
18717                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18718                    @Override
18719                    public void performReceive(Intent intent, int resultCode, String data,
18720                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18721                        // On to the next.
18722                        synchronized (ActivityManagerService.this) {
18723                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18724                                // Whoops, we are being started back up.  Abort, abort!
18725                                return;
18726                            }
18727                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18728                        }
18729                        mBatteryStatsService.noteEvent(
18730                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18731                                Integer.toString(userId), userId);
18732                        mSystemServiceManager.stopUser(userId);
18733                        broadcastIntentLocked(null, null, shutdownIntent,
18734                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18735                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18736                    }
18737                };
18738                // Kick things off.
18739                broadcastIntentLocked(null, null, stoppingIntent,
18740                        null, stoppingReceiver, 0, null, null,
18741                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18742                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18743            } finally {
18744                Binder.restoreCallingIdentity(ident);
18745            }
18746        }
18747
18748        return ActivityManager.USER_OP_SUCCESS;
18749    }
18750
18751    void finishUserStop(UserStartedState uss) {
18752        final int userId = uss.mHandle.getIdentifier();
18753        boolean stopped;
18754        ArrayList<IStopUserCallback> callbacks;
18755        synchronized (this) {
18756            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18757            if (mStartedUsers.get(userId) != uss) {
18758                stopped = false;
18759            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18760                stopped = false;
18761            } else {
18762                stopped = true;
18763                // User can no longer run.
18764                mStartedUsers.remove(userId);
18765                mUserLru.remove(Integer.valueOf(userId));
18766                updateStartedUserArrayLocked();
18767
18768                // Clean up all state and processes associated with the user.
18769                // Kill all the processes for the user.
18770                forceStopUserLocked(userId, "finish user");
18771            }
18772
18773            // Explicitly remove the old information in mRecentTasks.
18774            removeRecentTasksForUserLocked(userId);
18775        }
18776
18777        for (int i=0; i<callbacks.size(); i++) {
18778            try {
18779                if (stopped) callbacks.get(i).userStopped(userId);
18780                else callbacks.get(i).userStopAborted(userId);
18781            } catch (RemoteException e) {
18782            }
18783        }
18784
18785        if (stopped) {
18786            mSystemServiceManager.cleanupUser(userId);
18787            synchronized (this) {
18788                mStackSupervisor.removeUserLocked(userId);
18789            }
18790        }
18791    }
18792
18793    @Override
18794    public UserInfo getCurrentUser() {
18795        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18796                != PackageManager.PERMISSION_GRANTED) && (
18797                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18798                != PackageManager.PERMISSION_GRANTED)) {
18799            String msg = "Permission Denial: getCurrentUser() from pid="
18800                    + Binder.getCallingPid()
18801                    + ", uid=" + Binder.getCallingUid()
18802                    + " requires " + INTERACT_ACROSS_USERS;
18803            Slog.w(TAG, msg);
18804            throw new SecurityException(msg);
18805        }
18806        synchronized (this) {
18807            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18808            return getUserManagerLocked().getUserInfo(userId);
18809        }
18810    }
18811
18812    int getCurrentUserIdLocked() {
18813        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18814    }
18815
18816    @Override
18817    public boolean isUserRunning(int userId, boolean orStopped) {
18818        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18819                != PackageManager.PERMISSION_GRANTED) {
18820            String msg = "Permission Denial: isUserRunning() from pid="
18821                    + Binder.getCallingPid()
18822                    + ", uid=" + Binder.getCallingUid()
18823                    + " requires " + INTERACT_ACROSS_USERS;
18824            Slog.w(TAG, msg);
18825            throw new SecurityException(msg);
18826        }
18827        synchronized (this) {
18828            return isUserRunningLocked(userId, orStopped);
18829        }
18830    }
18831
18832    boolean isUserRunningLocked(int userId, boolean orStopped) {
18833        UserStartedState state = mStartedUsers.get(userId);
18834        if (state == null) {
18835            return false;
18836        }
18837        if (orStopped) {
18838            return true;
18839        }
18840        return state.mState != UserStartedState.STATE_STOPPING
18841                && state.mState != UserStartedState.STATE_SHUTDOWN;
18842    }
18843
18844    @Override
18845    public int[] getRunningUserIds() {
18846        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18847                != PackageManager.PERMISSION_GRANTED) {
18848            String msg = "Permission Denial: isUserRunning() from pid="
18849                    + Binder.getCallingPid()
18850                    + ", uid=" + Binder.getCallingUid()
18851                    + " requires " + INTERACT_ACROSS_USERS;
18852            Slog.w(TAG, msg);
18853            throw new SecurityException(msg);
18854        }
18855        synchronized (this) {
18856            return mStartedUserArray;
18857        }
18858    }
18859
18860    private void updateStartedUserArrayLocked() {
18861        int num = 0;
18862        for (int i=0; i<mStartedUsers.size();  i++) {
18863            UserStartedState uss = mStartedUsers.valueAt(i);
18864            // This list does not include stopping users.
18865            if (uss.mState != UserStartedState.STATE_STOPPING
18866                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18867                num++;
18868            }
18869        }
18870        mStartedUserArray = new int[num];
18871        num = 0;
18872        for (int i=0; i<mStartedUsers.size();  i++) {
18873            UserStartedState uss = mStartedUsers.valueAt(i);
18874            if (uss.mState != UserStartedState.STATE_STOPPING
18875                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18876                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18877                num++;
18878            }
18879        }
18880    }
18881
18882    @Override
18883    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18884        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18885                != PackageManager.PERMISSION_GRANTED) {
18886            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18887                    + Binder.getCallingPid()
18888                    + ", uid=" + Binder.getCallingUid()
18889                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18890            Slog.w(TAG, msg);
18891            throw new SecurityException(msg);
18892        }
18893
18894        mUserSwitchObservers.register(observer);
18895    }
18896
18897    @Override
18898    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18899        mUserSwitchObservers.unregister(observer);
18900    }
18901
18902    private boolean userExists(int userId) {
18903        if (userId == 0) {
18904            return true;
18905        }
18906        UserManagerService ums = getUserManagerLocked();
18907        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18908    }
18909
18910    int[] getUsersLocked() {
18911        UserManagerService ums = getUserManagerLocked();
18912        return ums != null ? ums.getUserIds() : new int[] { 0 };
18913    }
18914
18915    UserManagerService getUserManagerLocked() {
18916        if (mUserManager == null) {
18917            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18918            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18919        }
18920        return mUserManager;
18921    }
18922
18923    private int applyUserId(int uid, int userId) {
18924        return UserHandle.getUid(userId, uid);
18925    }
18926
18927    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18928        if (info == null) return null;
18929        ApplicationInfo newInfo = new ApplicationInfo(info);
18930        newInfo.uid = applyUserId(info.uid, userId);
18931        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18932                + info.packageName;
18933        return newInfo;
18934    }
18935
18936    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18937        if (aInfo == null
18938                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18939            return aInfo;
18940        }
18941
18942        ActivityInfo info = new ActivityInfo(aInfo);
18943        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18944        return info;
18945    }
18946
18947    private final class LocalService extends ActivityManagerInternal {
18948        @Override
18949        public void goingToSleep() {
18950            ActivityManagerService.this.goingToSleep();
18951        }
18952
18953        @Override
18954        public void wakingUp() {
18955            ActivityManagerService.this.wakingUp();
18956        }
18957
18958        @Override
18959        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18960                String processName, String abiOverride, int uid, Runnable crashHandler) {
18961            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18962                    processName, abiOverride, uid, crashHandler);
18963        }
18964    }
18965
18966    /**
18967     * An implementation of IAppTask, that allows an app to manage its own tasks via
18968     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18969     * only the process that calls getAppTasks() can call the AppTask methods.
18970     */
18971    class AppTaskImpl extends IAppTask.Stub {
18972        private int mTaskId;
18973        private int mCallingUid;
18974
18975        public AppTaskImpl(int taskId, int callingUid) {
18976            mTaskId = taskId;
18977            mCallingUid = callingUid;
18978        }
18979
18980        private void checkCaller() {
18981            if (mCallingUid != Binder.getCallingUid()) {
18982                throw new SecurityException("Caller " + mCallingUid
18983                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18984            }
18985        }
18986
18987        @Override
18988        public void finishAndRemoveTask() {
18989            checkCaller();
18990
18991            synchronized (ActivityManagerService.this) {
18992                long origId = Binder.clearCallingIdentity();
18993                try {
18994                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18995                    if (tr == null) {
18996                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18997                    }
18998                    // Only kill the process if we are not a new document
18999                    int flags = tr.getBaseIntent().getFlags();
19000                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19001                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19002                    removeTaskByIdLocked(mTaskId,
19003                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19004                } finally {
19005                    Binder.restoreCallingIdentity(origId);
19006                }
19007            }
19008        }
19009
19010        @Override
19011        public ActivityManager.RecentTaskInfo getTaskInfo() {
19012            checkCaller();
19013
19014            synchronized (ActivityManagerService.this) {
19015                long origId = Binder.clearCallingIdentity();
19016                try {
19017                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19018                    if (tr == null) {
19019                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19020                    }
19021                    return createRecentTaskInfoFromTaskRecord(tr);
19022                } finally {
19023                    Binder.restoreCallingIdentity(origId);
19024                }
19025            }
19026        }
19027
19028        @Override
19029        public void moveToFront() {
19030            checkCaller();
19031
19032            final TaskRecord tr;
19033            synchronized (ActivityManagerService.this) {
19034                tr = recentTaskForIdLocked(mTaskId);
19035                if (tr == null) {
19036                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19037                }
19038                if (tr.getRootActivity() != null) {
19039                    moveTaskToFrontLocked(tr.taskId, 0, null);
19040                    return;
19041                }
19042            }
19043
19044            startActivityFromRecentsInner(tr.taskId, null);
19045        }
19046
19047        @Override
19048        public int startActivity(IBinder whoThread, String callingPackage,
19049                Intent intent, String resolvedType, Bundle options) {
19050            checkCaller();
19051
19052            int callingUser = UserHandle.getCallingUserId();
19053            TaskRecord tr;
19054            IApplicationThread appThread;
19055            synchronized (ActivityManagerService.this) {
19056                tr = recentTaskForIdLocked(mTaskId);
19057                if (tr == null) {
19058                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19059                }
19060                appThread = ApplicationThreadNative.asInterface(whoThread);
19061                if (appThread == null) {
19062                    throw new IllegalArgumentException("Bad app thread " + appThread);
19063                }
19064            }
19065            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19066                    resolvedType, null, null, null, null, 0, 0, null, null,
19067                    null, options, callingUser, null, tr);
19068        }
19069
19070        @Override
19071        public void setExcludeFromRecents(boolean exclude) {
19072            checkCaller();
19073
19074            synchronized (ActivityManagerService.this) {
19075                long origId = Binder.clearCallingIdentity();
19076                try {
19077                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19078                    if (tr == null) {
19079                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19080                    }
19081                    Intent intent = tr.getBaseIntent();
19082                    if (exclude) {
19083                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19084                    } else {
19085                        intent.setFlags(intent.getFlags()
19086                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19087                    }
19088                } finally {
19089                    Binder.restoreCallingIdentity(origId);
19090                }
19091            }
19092        }
19093    }
19094}
19095