ActivityManagerService.java revision d7b8621bde44857ebb07130693a00f5f777887d4
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_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
274
275    // Amount of time after a call to stopAppSwitches() during which we will
276    // prevent further untrusted switches from happening.
277    static final long APP_SWITCH_DELAY_TIME = 5*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real.
281    static final int PROC_START_TIMEOUT = 10*1000;
282
283    // How long we wait for a launched process to attach to the activity manager
284    // before we decide it's never going to come up for real, when the process was
285    // started with a wrapper for instrumentation (such as Valgrind) because it
286    // could take much longer than usual.
287    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
288
289    // How long to wait after going idle before forcing apps to GC.
290    static final int GC_TIMEOUT = 5*1000;
291
292    // The minimum amount of time between successive GC requests for a process.
293    static final int GC_MIN_INTERVAL = 60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process.
296    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process
299    // when the request is due to the memory state being lowered.
300    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
301
302    // The rate at which we check for apps using excessive power -- 15 mins.
303    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on wake locks to start killing things.
307    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // The minimum sample duration we will allow before deciding we have
310    // enough data on CPU usage to start killing things.
311    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
312
313    // How long we allow a receiver to run before giving up on it.
314    static final int BROADCAST_FG_TIMEOUT = 10*1000;
315    static final int BROADCAST_BG_TIMEOUT = 60*1000;
316
317    // How long we wait until we timeout on key dispatching.
318    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
319
320    // How long we wait until we timeout on key dispatching during instrumentation.
321    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
322
323    // Amount of time we wait for observers to handle a user switch before
324    // giving up on them and unfreezing the screen.
325    static final int USER_SWITCH_TIMEOUT = 2*1000;
326
327    // Maximum number of users we allow to be running at a time.
328    static final int MAX_RUNNING_USERS = 3;
329
330    // How long to wait in getAssistContextExtras for the activity and foreground services
331    // to respond with the result.
332    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
333
334    // Maximum number of persisted Uri grants a package is allowed
335    static final int MAX_PERSISTED_URI_GRANTS = 128;
336
337    static final int MY_PID = Process.myPid();
338
339    static final String[] EMPTY_STRING_ARRAY = new String[0];
340
341    // How many bytes to write into the dropbox log before truncating
342    static final int DROPBOX_MAX_SIZE = 256 * 1024;
343
344    /** All system services */
345    SystemServiceManager mSystemServiceManager;
346
347    /** Run all ActivityStacks through this */
348    ActivityStackSupervisor mStackSupervisor;
349
350    public IntentFirewall mIntentFirewall;
351
352    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
353    // default actuion automatically.  Important for devices without direct input
354    // devices.
355    private boolean mShowDialogs = true;
356
357    /**
358     * Description of a request to start a new activity, which has been held
359     * due to app switches being disabled.
360     */
361    static class PendingActivityLaunch {
362        final ActivityRecord r;
363        final ActivityRecord sourceRecord;
364        final int startFlags;
365        final ActivityStack stack;
366
367        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
368                int _startFlags, ActivityStack _stack) {
369            r = _r;
370            sourceRecord = _sourceRecord;
371            startFlags = _startFlags;
372            stack = _stack;
373        }
374    }
375
376    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
377            = new ArrayList<PendingActivityLaunch>();
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414
415    public class PendingAssistExtras extends Binder implements Runnable {
416        public final ActivityRecord activity;
417        public boolean haveResult = false;
418        public Bundle result = null;
419        public PendingAssistExtras(ActivityRecord _activity) {
420            activity = _activity;
421        }
422        @Override
423        public void run() {
424            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
425            synchronized (this) {
426                haveResult = true;
427                notifyAll();
428            }
429        }
430    }
431
432    final ArrayList<PendingAssistExtras> mPendingAssistExtras
433            = new ArrayList<PendingAssistExtras>();
434
435    /**
436     * Process management.
437     */
438    final ProcessList mProcessList = new ProcessList();
439
440    /**
441     * All of the applications we currently have running organized by name.
442     * The keys are strings of the application package name (as
443     * returned by the package manager), and the keys are ApplicationRecord
444     * objects.
445     */
446    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
447
448    /**
449     * Tracking long-term execution of processes to look for abuse and other
450     * bad app behavior.
451     */
452    final ProcessStatsService mProcessStats;
453
454    /**
455     * The currently running isolated processes.
456     */
457    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
458
459    /**
460     * Counter for assigning isolated process uids, to avoid frequently reusing the
461     * same ones.
462     */
463    int mNextIsolatedProcessUid = 0;
464
465    /**
466     * The currently running heavy-weight process, if any.
467     */
468    ProcessRecord mHeavyWeightProcess = null;
469
470    /**
471     * The last time that various processes have crashed.
472     */
473    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
474
475    /**
476     * Information about a process that is currently marked as bad.
477     */
478    static final class BadProcessInfo {
479        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
480            this.time = time;
481            this.shortMsg = shortMsg;
482            this.longMsg = longMsg;
483            this.stack = stack;
484        }
485
486        final long time;
487        final String shortMsg;
488        final String longMsg;
489        final String stack;
490    }
491
492    /**
493     * Set of applications that we consider to be bad, and will reject
494     * incoming broadcasts from (which the user has no control over).
495     * Processes are added to this set when they have crashed twice within
496     * a minimum amount of time; they are removed from it when they are
497     * later restarted (hopefully due to some user action).  The value is the
498     * time it was added to the list.
499     */
500    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
501
502    /**
503     * All of the processes we currently have running organized by pid.
504     * The keys are the pid running the application.
505     *
506     * <p>NOTE: This object is protected by its own lock, NOT the global
507     * activity manager lock!
508     */
509    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
510
511    /**
512     * All of the processes that have been forced to be foreground.  The key
513     * is the pid of the caller who requested it (we hold a death
514     * link on it).
515     */
516    abstract class ForegroundToken implements IBinder.DeathRecipient {
517        int pid;
518        IBinder token;
519    }
520    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
521
522    /**
523     * List of records for processes that someone had tried to start before the
524     * system was ready.  We don't start them at that point, but ensure they
525     * are started by the time booting is complete.
526     */
527    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
528
529    /**
530     * List of persistent applications that are in the process
531     * of being started.
532     */
533    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
534
535    /**
536     * Processes that are being forcibly torn down.
537     */
538    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
539
540    /**
541     * List of running applications, sorted by recent usage.
542     * The first entry in the list is the least recently used.
543     */
544    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
545
546    /**
547     * Where in mLruProcesses that the processes hosting activities start.
548     */
549    int mLruProcessActivityStart = 0;
550
551    /**
552     * Where in mLruProcesses that the processes hosting services start.
553     * This is after (lower index) than mLruProcessesActivityStart.
554     */
555    int mLruProcessServiceStart = 0;
556
557    /**
558     * List of processes that should gc as soon as things are idle.
559     */
560    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
561
562    /**
563     * Processes we want to collect PSS data from.
564     */
565    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Last time we requested PSS data of all processes.
569     */
570    long mLastFullPssTime = SystemClock.uptimeMillis();
571
572    /**
573     * This is the process holding what we currently consider to be
574     * the "home" activity.
575     */
576    ProcessRecord mHomeProcess;
577
578    /**
579     * This is the process holding the activity the user last visited that
580     * is in a different process from the one they are currently in.
581     */
582    ProcessRecord mPreviousProcess;
583
584    /**
585     * The time at which the previous process was last visible.
586     */
587    long mPreviousProcessVisibleTime;
588
589    /**
590     * Which uses have been started, so are allowed to run code.
591     */
592    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
593
594    /**
595     * LRU list of history of current users.  Most recently current is at the end.
596     */
597    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
598
599    /**
600     * Constant array of the users that are currently started.
601     */
602    int[] mStartedUserArray = new int[] { 0 };
603
604    /**
605     * Registered observers of the user switching mechanics.
606     */
607    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
608            = new RemoteCallbackList<IUserSwitchObserver>();
609
610    /**
611     * Currently active user switch.
612     */
613    Object mCurUserSwitchCallback;
614
615    /**
616     * Packages that the user has asked to have run in screen size
617     * compatibility mode instead of filling the screen.
618     */
619    final CompatModePackages mCompatModePackages;
620
621    /**
622     * Set of IntentSenderRecord objects that are currently active.
623     */
624    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
625            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
626
627    /**
628     * Fingerprints (hashCode()) of stack traces that we've
629     * already logged DropBox entries for.  Guarded by itself.  If
630     * something (rogue user app) forces this over
631     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
632     */
633    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
634    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
635
636    /**
637     * Strict Mode background batched logging state.
638     *
639     * The string buffer is guarded by itself, and its lock is also
640     * used to determine if another batched write is already
641     * in-flight.
642     */
643    private final StringBuilder mStrictModeBuffer = new StringBuilder();
644
645    /**
646     * Keeps track of all IIntentReceivers that have been registered for
647     * broadcasts.  Hash keys are the receiver IBinder, hash value is
648     * a ReceiverList.
649     */
650    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
651            new HashMap<IBinder, ReceiverList>();
652
653    /**
654     * Resolver for broadcast intents to registered receivers.
655     * Holds BroadcastFilter (subclass of IntentFilter).
656     */
657    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
658            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
659        @Override
660        protected boolean allowFilterResult(
661                BroadcastFilter filter, List<BroadcastFilter> dest) {
662            IBinder target = filter.receiverList.receiver.asBinder();
663            for (int i=dest.size()-1; i>=0; i--) {
664                if (dest.get(i).receiverList.receiver.asBinder() == target) {
665                    return false;
666                }
667            }
668            return true;
669        }
670
671        @Override
672        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
673            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
674                    || userId == filter.owningUserId) {
675                return super.newResult(filter, match, userId);
676            }
677            return null;
678        }
679
680        @Override
681        protected BroadcastFilter[] newArray(int size) {
682            return new BroadcastFilter[size];
683        }
684
685        @Override
686        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
687            return packageName.equals(filter.packageName);
688        }
689    };
690
691    /**
692     * State of all active sticky broadcasts per user.  Keys are the action of the
693     * sticky Intent, values are an ArrayList of all broadcasted intents with
694     * that action (which should usually be one).  The SparseArray is keyed
695     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
696     * for stickies that are sent to all users.
697     */
698    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
699            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
700
701    final ActiveServices mServices;
702
703    /**
704     * Backup/restore process management
705     */
706    String mBackupAppName = null;
707    BackupRecord mBackupTarget = null;
708
709    final ProviderMap mProviderMap;
710
711    /**
712     * List of content providers who have clients waiting for them.  The
713     * application is currently being launched and the provider will be
714     * removed from this list once it is published.
715     */
716    final ArrayList<ContentProviderRecord> mLaunchingProviders
717            = new ArrayList<ContentProviderRecord>();
718
719    /**
720     * File storing persisted {@link #mGrantedUriPermissions}.
721     */
722    private final AtomicFile mGrantFile;
723
724    /** XML constants used in {@link #mGrantFile} */
725    private static final String TAG_URI_GRANTS = "uri-grants";
726    private static final String TAG_URI_GRANT = "uri-grant";
727    private static final String ATTR_USER_HANDLE = "userHandle";
728    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
729    private static final String ATTR_TARGET_USER_ID = "targetUserId";
730    private static final String ATTR_SOURCE_PKG = "sourcePkg";
731    private static final String ATTR_TARGET_PKG = "targetPkg";
732    private static final String ATTR_URI = "uri";
733    private static final String ATTR_MODE_FLAGS = "modeFlags";
734    private static final String ATTR_CREATED_TIME = "createdTime";
735    private static final String ATTR_PREFIX = "prefix";
736
737    /**
738     * Global set of specific {@link Uri} permissions that have been granted.
739     * This optimized lookup structure maps from {@link UriPermission#targetUid}
740     * to {@link UriPermission#uri} to {@link UriPermission}.
741     */
742    @GuardedBy("this")
743    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
744            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
745
746    public static class GrantUri {
747        public final int sourceUserId;
748        public final Uri uri;
749        public boolean prefix;
750
751        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
752            this.sourceUserId = sourceUserId;
753            this.uri = uri;
754            this.prefix = prefix;
755        }
756
757        @Override
758        public int hashCode() {
759            return toString().hashCode();
760        }
761
762        @Override
763        public boolean equals(Object o) {
764            if (o instanceof GrantUri) {
765                GrantUri other = (GrantUri) o;
766                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
767                        && prefix == other.prefix;
768            }
769            return false;
770        }
771
772        @Override
773        public String toString() {
774            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
775            if (prefix) result += " [prefix]";
776            return result;
777        }
778
779        public String toSafeString() {
780            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
781            if (prefix) result += " [prefix]";
782            return result;
783        }
784
785        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
786            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
787                    ContentProvider.getUriWithoutUserId(uri), false);
788        }
789    }
790
791    CoreSettingsObserver mCoreSettingsObserver;
792
793    /**
794     * Thread-local storage used to carry caller permissions over through
795     * indirect content-provider access.
796     */
797    private class Identity {
798        public int pid;
799        public int uid;
800
801        Identity(int _pid, int _uid) {
802            pid = _pid;
803            uid = _uid;
804        }
805    }
806
807    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
808
809    /**
810     * All information we have collected about the runtime performance of
811     * any user id that can impact battery performance.
812     */
813    final BatteryStatsService mBatteryStatsService;
814
815    /**
816     * Information about component usage
817     */
818    final UsageStatsService mUsageStatsService;
819
820    /**
821     * Information about and control over application operations
822     */
823    final AppOpsService mAppOpsService;
824
825    /**
826     * Save recent tasks information across reboots.
827     */
828    final TaskPersister mTaskPersister;
829
830    /**
831     * Current configuration information.  HistoryRecord objects are given
832     * a reference to this object to indicate which configuration they are
833     * currently running in, so this object must be kept immutable.
834     */
835    Configuration mConfiguration = new Configuration();
836
837    /**
838     * Current sequencing integer of the configuration, for skipping old
839     * configurations.
840     */
841    int mConfigurationSeq = 0;
842
843    /**
844     * Hardware-reported OpenGLES version.
845     */
846    final int GL_ES_VERSION;
847
848    /**
849     * List of initialization arguments to pass to all processes when binding applications to them.
850     * For example, references to the commonly used services.
851     */
852    HashMap<String, IBinder> mAppBindArgs;
853
854    /**
855     * Temporary to avoid allocations.  Protected by main lock.
856     */
857    final StringBuilder mStringBuilder = new StringBuilder(256);
858
859    /**
860     * Used to control how we initialize the service.
861     */
862    ComponentName mTopComponent;
863    String mTopAction = Intent.ACTION_MAIN;
864    String mTopData;
865    boolean mProcessesReady = false;
866    boolean mSystemReady = false;
867    boolean mBooting = false;
868    boolean mWaitingUpdate = false;
869    boolean mDidUpdate = false;
870    boolean mOnBattery = false;
871    boolean mLaunchWarningShown = false;
872
873    Context mContext;
874
875    int mFactoryTest;
876
877    boolean mCheckedForSetup;
878
879    /**
880     * The time at which we will allow normal application switches again,
881     * after a call to {@link #stopAppSwitches()}.
882     */
883    long mAppSwitchesAllowedTime;
884
885    /**
886     * This is set to true after the first switch after mAppSwitchesAllowedTime
887     * is set; any switches after that will clear the time.
888     */
889    boolean mDidAppSwitch;
890
891    /**
892     * Last time (in realtime) at which we checked for power usage.
893     */
894    long mLastPowerCheckRealtime;
895
896    /**
897     * Last time (in uptime) at which we checked for power usage.
898     */
899    long mLastPowerCheckUptime;
900
901    /**
902     * Set while we are wanting to sleep, to prevent any
903     * activities from being started/resumed.
904     */
905    private boolean mSleeping = false;
906
907    /**
908     * Set while we are running a voice interaction.  This overrides
909     * sleeping while it is active.
910     */
911    private boolean mRunningVoice = false;
912
913    /**
914     * State of external calls telling us if the device is asleep.
915     */
916    private boolean mWentToSleep = false;
917
918    /**
919     * State of external call telling us if the lock screen is shown.
920     */
921    private boolean mLockScreenShown = false;
922
923    /**
924     * Set if we are shutting down the system, similar to sleeping.
925     */
926    boolean mShuttingDown = false;
927
928    /**
929     * Current sequence id for oom_adj computation traversal.
930     */
931    int mAdjSeq = 0;
932
933    /**
934     * Current sequence id for process LRU updating.
935     */
936    int mLruSeq = 0;
937
938    /**
939     * Keep track of the non-cached/empty process we last found, to help
940     * determine how to distribute cached/empty processes next time.
941     */
942    int mNumNonCachedProcs = 0;
943
944    /**
945     * Keep track of the number of cached hidden procs, to balance oom adj
946     * distribution between those and empty procs.
947     */
948    int mNumCachedHiddenProcs = 0;
949
950    /**
951     * Keep track of the number of service processes we last found, to
952     * determine on the next iteration which should be B services.
953     */
954    int mNumServiceProcs = 0;
955    int mNewNumAServiceProcs = 0;
956    int mNewNumServiceProcs = 0;
957
958    /**
959     * Allow the current computed overall memory level of the system to go down?
960     * This is set to false when we are killing processes for reasons other than
961     * memory management, so that the now smaller process list will not be taken as
962     * an indication that memory is tighter.
963     */
964    boolean mAllowLowerMemLevel = false;
965
966    /**
967     * The last computed memory level, for holding when we are in a state that
968     * processes are going away for other reasons.
969     */
970    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
971
972    /**
973     * The last total number of process we have, to determine if changes actually look
974     * like a shrinking number of process due to lower RAM.
975     */
976    int mLastNumProcesses;
977
978    /**
979     * The uptime of the last time we performed idle maintenance.
980     */
981    long mLastIdleTime = SystemClock.uptimeMillis();
982
983    /**
984     * Total time spent with RAM that has been added in the past since the last idle time.
985     */
986    long mLowRamTimeSinceLastIdle = 0;
987
988    /**
989     * If RAM is currently low, when that horrible situation started.
990     */
991    long mLowRamStartTime = 0;
992
993    /**
994     * For reporting to battery stats the current top application.
995     */
996    private String mCurResumedPackage = null;
997    private int mCurResumedUid = -1;
998
999    /**
1000     * For reporting to battery stats the apps currently running foreground
1001     * service.  The ProcessMap is package/uid tuples; each of these contain
1002     * an array of the currently foreground processes.
1003     */
1004    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1005            = new ProcessMap<ArrayList<ProcessRecord>>();
1006
1007    /**
1008     * This is set if we had to do a delayed dexopt of an app before launching
1009     * it, to increase the ANR timeouts in that case.
1010     */
1011    boolean mDidDexOpt;
1012
1013    /**
1014     * Set if the systemServer made a call to enterSafeMode.
1015     */
1016    boolean mSafeMode;
1017
1018    String mDebugApp = null;
1019    boolean mWaitForDebugger = false;
1020    boolean mDebugTransient = false;
1021    String mOrigDebugApp = null;
1022    boolean mOrigWaitForDebugger = false;
1023    boolean mAlwaysFinishActivities = false;
1024    IActivityController mController = null;
1025    String mProfileApp = null;
1026    ProcessRecord mProfileProc = null;
1027    String mProfileFile;
1028    ParcelFileDescriptor mProfileFd;
1029    int mProfileType = 0;
1030    boolean mAutoStopProfiler = false;
1031    String mOpenGlTraceApp = null;
1032
1033    static class ProcessChangeItem {
1034        static final int CHANGE_ACTIVITIES = 1<<0;
1035        static final int CHANGE_PROCESS_STATE = 1<<1;
1036        int changes;
1037        int uid;
1038        int pid;
1039        int processState;
1040        boolean foregroundActivities;
1041    }
1042
1043    final RemoteCallbackList<IProcessObserver> mProcessObservers
1044            = new RemoteCallbackList<IProcessObserver>();
1045    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1046
1047    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1048            = new ArrayList<ProcessChangeItem>();
1049    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1050            = new ArrayList<ProcessChangeItem>();
1051
1052    /**
1053     * Runtime CPU use collection thread.  This object's lock is used to
1054     * protect all related state.
1055     */
1056    final Thread mProcessCpuThread;
1057
1058    /**
1059     * Used to collect process stats when showing not responding dialog.
1060     * Protected by mProcessCpuThread.
1061     */
1062    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1063            MONITOR_THREAD_CPU_USAGE);
1064    final AtomicLong mLastCpuTime = new AtomicLong(0);
1065    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1066
1067    long mLastWriteTime = 0;
1068
1069    /**
1070     * Used to retain an update lock when the foreground activity is in
1071     * immersive mode.
1072     */
1073    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1074
1075    /**
1076     * Set to true after the system has finished booting.
1077     */
1078    boolean mBooted = false;
1079
1080    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1081    int mProcessLimitOverride = -1;
1082
1083    WindowManagerService mWindowManager;
1084
1085    final ActivityThread mSystemThread;
1086
1087    int mCurrentUserId = 0;
1088    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1089    private UserManagerService mUserManager;
1090
1091    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1092        final ProcessRecord mApp;
1093        final int mPid;
1094        final IApplicationThread mAppThread;
1095
1096        AppDeathRecipient(ProcessRecord app, int pid,
1097                IApplicationThread thread) {
1098            if (localLOGV) Slog.v(
1099                TAG, "New death recipient " + this
1100                + " for thread " + thread.asBinder());
1101            mApp = app;
1102            mPid = pid;
1103            mAppThread = thread;
1104        }
1105
1106        @Override
1107        public void binderDied() {
1108            if (localLOGV) Slog.v(
1109                TAG, "Death received in " + this
1110                + " for thread " + mAppThread.asBinder());
1111            synchronized(ActivityManagerService.this) {
1112                appDiedLocked(mApp, mPid, mAppThread);
1113            }
1114        }
1115    }
1116
1117    static final int SHOW_ERROR_MSG = 1;
1118    static final int SHOW_NOT_RESPONDING_MSG = 2;
1119    static final int SHOW_FACTORY_ERROR_MSG = 3;
1120    static final int UPDATE_CONFIGURATION_MSG = 4;
1121    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1122    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1123    static final int SERVICE_TIMEOUT_MSG = 12;
1124    static final int UPDATE_TIME_ZONE = 13;
1125    static final int SHOW_UID_ERROR_MSG = 14;
1126    static final int IM_FEELING_LUCKY_MSG = 15;
1127    static final int PROC_START_TIMEOUT_MSG = 20;
1128    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1129    static final int KILL_APPLICATION_MSG = 22;
1130    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1131    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1132    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1133    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1134    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1135    static final int CLEAR_DNS_CACHE_MSG = 28;
1136    static final int UPDATE_HTTP_PROXY_MSG = 29;
1137    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1138    static final int DISPATCH_PROCESSES_CHANGED = 31;
1139    static final int DISPATCH_PROCESS_DIED = 32;
1140    static final int REPORT_MEM_USAGE_MSG = 33;
1141    static final int REPORT_USER_SWITCH_MSG = 34;
1142    static final int CONTINUE_USER_SWITCH_MSG = 35;
1143    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1144    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1145    static final int PERSIST_URI_GRANTS_MSG = 38;
1146    static final int REQUEST_ALL_PSS_MSG = 39;
1147    static final int START_PROFILES_MSG = 40;
1148    static final int UPDATE_TIME = 41;
1149    static final int SYSTEM_USER_START_MSG = 42;
1150    static final int SYSTEM_USER_CURRENT_MSG = 43;
1151
1152    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1153    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1154    static final int FIRST_COMPAT_MODE_MSG = 300;
1155    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1156
1157    AlertDialog mUidAlert;
1158    CompatModeDialog mCompatModeDialog;
1159    long mLastMemUsageReportTime = 0;
1160
1161    /**
1162     * Flag whether the current user is a "monkey", i.e. whether
1163     * the UI is driven by a UI automation tool.
1164     */
1165    private boolean mUserIsMonkey;
1166
1167    final ServiceThread mHandlerThread;
1168    final MainHandler mHandler;
1169
1170    final class MainHandler extends Handler {
1171        public MainHandler(Looper looper) {
1172            super(looper, null, true);
1173        }
1174
1175        @Override
1176        public void handleMessage(Message msg) {
1177            switch (msg.what) {
1178            case SHOW_ERROR_MSG: {
1179                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1180                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1181                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1182                synchronized (ActivityManagerService.this) {
1183                    ProcessRecord proc = (ProcessRecord)data.get("app");
1184                    AppErrorResult res = (AppErrorResult) data.get("result");
1185                    if (proc != null && proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has crash dialog: " + proc);
1187                        if (res != null) {
1188                            res.set(0);
1189                        }
1190                        return;
1191                    }
1192                    if (!showBackground && UserHandle.getAppId(proc.uid)
1193                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1194                            && proc.pid != MY_PID) {
1195                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1196                        if (res != null) {
1197                            res.set(0);
1198                        }
1199                        return;
1200                    }
1201                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1202                        Dialog d = new AppErrorDialog(mContext,
1203                                ActivityManagerService.this, res, proc);
1204                        d.show();
1205                        proc.crashDialog = d;
1206                    } else {
1207                        // The device is asleep, so just pretend that the user
1208                        // saw a crash dialog and hit "force quit".
1209                        if (res != null) {
1210                            res.set(0);
1211                        }
1212                    }
1213                }
1214
1215                ensureBootCompleted();
1216            } break;
1217            case SHOW_NOT_RESPONDING_MSG: {
1218                synchronized (ActivityManagerService.this) {
1219                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1220                    ProcessRecord proc = (ProcessRecord)data.get("app");
1221                    if (proc != null && proc.anrDialog != null) {
1222                        Slog.e(TAG, "App already has anr dialog: " + proc);
1223                        return;
1224                    }
1225
1226                    Intent intent = new Intent("android.intent.action.ANR");
1227                    if (!mProcessesReady) {
1228                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1229                                | Intent.FLAG_RECEIVER_FOREGROUND);
1230                    }
1231                    broadcastIntentLocked(null, null, intent,
1232                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1233                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1234
1235                    if (mShowDialogs) {
1236                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1237                                mContext, proc, (ActivityRecord)data.get("activity"),
1238                                msg.arg1 != 0);
1239                        d.show();
1240                        proc.anrDialog = d;
1241                    } else {
1242                        // Just kill the app if there is no dialog to be shown.
1243                        killAppAtUsersRequest(proc, null);
1244                    }
1245                }
1246
1247                ensureBootCompleted();
1248            } break;
1249            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1250                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1251                synchronized (ActivityManagerService.this) {
1252                    ProcessRecord proc = (ProcessRecord) data.get("app");
1253                    if (proc == null) {
1254                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1255                        break;
1256                    }
1257                    if (proc.crashDialog != null) {
1258                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1259                        return;
1260                    }
1261                    AppErrorResult res = (AppErrorResult) data.get("result");
1262                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1263                        Dialog d = new StrictModeViolationDialog(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                        res.set(0);
1271                    }
1272                }
1273                ensureBootCompleted();
1274            } break;
1275            case SHOW_FACTORY_ERROR_MSG: {
1276                Dialog d = new FactoryErrorDialog(
1277                    mContext, msg.getData().getCharSequence("msg"));
1278                d.show();
1279                ensureBootCompleted();
1280            } break;
1281            case UPDATE_CONFIGURATION_MSG: {
1282                final ContentResolver resolver = mContext.getContentResolver();
1283                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1284            } break;
1285            case GC_BACKGROUND_PROCESSES_MSG: {
1286                synchronized (ActivityManagerService.this) {
1287                    performAppGcsIfAppropriateLocked();
1288                }
1289            } break;
1290            case WAIT_FOR_DEBUGGER_MSG: {
1291                synchronized (ActivityManagerService.this) {
1292                    ProcessRecord app = (ProcessRecord)msg.obj;
1293                    if (msg.arg1 != 0) {
1294                        if (!app.waitedForDebugger) {
1295                            Dialog d = new AppWaitingForDebuggerDialog(
1296                                    ActivityManagerService.this,
1297                                    mContext, app);
1298                            app.waitDialog = d;
1299                            app.waitedForDebugger = true;
1300                            d.show();
1301                        }
1302                    } else {
1303                        if (app.waitDialog != null) {
1304                            app.waitDialog.dismiss();
1305                            app.waitDialog = null;
1306                        }
1307                    }
1308                }
1309            } break;
1310            case SERVICE_TIMEOUT_MSG: {
1311                if (mDidDexOpt) {
1312                    mDidDexOpt = false;
1313                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1314                    nmsg.obj = msg.obj;
1315                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1316                    return;
1317                }
1318                mServices.serviceTimeout((ProcessRecord)msg.obj);
1319            } break;
1320            case UPDATE_TIME_ZONE: {
1321                synchronized (ActivityManagerService.this) {
1322                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1323                        ProcessRecord r = mLruProcesses.get(i);
1324                        if (r.thread != null) {
1325                            try {
1326                                r.thread.updateTimeZone();
1327                            } catch (RemoteException ex) {
1328                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1329                            }
1330                        }
1331                    }
1332                }
1333            } break;
1334            case CLEAR_DNS_CACHE_MSG: {
1335                synchronized (ActivityManagerService.this) {
1336                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1337                        ProcessRecord r = mLruProcesses.get(i);
1338                        if (r.thread != null) {
1339                            try {
1340                                r.thread.clearDnsCache();
1341                            } catch (RemoteException ex) {
1342                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1343                            }
1344                        }
1345                    }
1346                }
1347            } break;
1348            case UPDATE_HTTP_PROXY_MSG: {
1349                ProxyInfo proxy = (ProxyInfo)msg.obj;
1350                String host = "";
1351                String port = "";
1352                String exclList = "";
1353                Uri pacFileUrl = Uri.EMPTY;
1354                if (proxy != null) {
1355                    host = proxy.getHost();
1356                    port = Integer.toString(proxy.getPort());
1357                    exclList = proxy.getExclusionListAsString();
1358                    pacFileUrl = proxy.getPacFileUrl();
1359                }
1360                synchronized (ActivityManagerService.this) {
1361                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1362                        ProcessRecord r = mLruProcesses.get(i);
1363                        if (r.thread != null) {
1364                            try {
1365                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1366                            } catch (RemoteException ex) {
1367                                Slog.w(TAG, "Failed to update http proxy for: " +
1368                                        r.info.processName);
1369                            }
1370                        }
1371                    }
1372                }
1373            } break;
1374            case SHOW_UID_ERROR_MSG: {
1375                String title = "System UIDs Inconsistent";
1376                String text = "UIDs on the system are inconsistent, you need to wipe your"
1377                        + " data partition or your device will be unstable.";
1378                Log.e(TAG, title + ": " + text);
1379                if (mShowDialogs) {
1380                    // XXX This is a temporary dialog, no need to localize.
1381                    AlertDialog d = new BaseErrorDialog(mContext);
1382                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1383                    d.setCancelable(false);
1384                    d.setTitle(title);
1385                    d.setMessage(text);
1386                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1387                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1388                    mUidAlert = d;
1389                    d.show();
1390                }
1391            } break;
1392            case IM_FEELING_LUCKY_MSG: {
1393                if (mUidAlert != null) {
1394                    mUidAlert.dismiss();
1395                    mUidAlert = null;
1396                }
1397            } break;
1398            case PROC_START_TIMEOUT_MSG: {
1399                if (mDidDexOpt) {
1400                    mDidDexOpt = false;
1401                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1402                    nmsg.obj = msg.obj;
1403                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1404                    return;
1405                }
1406                ProcessRecord app = (ProcessRecord)msg.obj;
1407                synchronized (ActivityManagerService.this) {
1408                    processStartTimedOutLocked(app);
1409                }
1410            } break;
1411            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1412                synchronized (ActivityManagerService.this) {
1413                    doPendingActivityLaunchesLocked(true);
1414                }
1415            } break;
1416            case KILL_APPLICATION_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    int appid = msg.arg1;
1419                    boolean restart = (msg.arg2 == 1);
1420                    Bundle bundle = (Bundle)msg.obj;
1421                    String pkg = bundle.getString("pkg");
1422                    String reason = bundle.getString("reason");
1423                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1424                            false, UserHandle.USER_ALL, reason);
1425                }
1426            } break;
1427            case FINALIZE_PENDING_INTENT_MSG: {
1428                ((PendingIntentRecord)msg.obj).completeFinalize();
1429            } break;
1430            case POST_HEAVY_NOTIFICATION_MSG: {
1431                INotificationManager inm = NotificationManager.getService();
1432                if (inm == null) {
1433                    return;
1434                }
1435
1436                ActivityRecord root = (ActivityRecord)msg.obj;
1437                ProcessRecord process = root.app;
1438                if (process == null) {
1439                    return;
1440                }
1441
1442                try {
1443                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1444                    String text = mContext.getString(R.string.heavy_weight_notification,
1445                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1446                    Notification notification = new Notification();
1447                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1448                    notification.when = 0;
1449                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1450                    notification.tickerText = text;
1451                    notification.defaults = 0; // please be quiet
1452                    notification.sound = null;
1453                    notification.vibrate = null;
1454                    notification.setLatestEventInfo(context, text,
1455                            mContext.getText(R.string.heavy_weight_notification_detail),
1456                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1457                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1458                                    new UserHandle(root.userId)));
1459
1460                    try {
1461                        int[] outId = new int[1];
1462                        inm.enqueueNotificationWithTag("android", "android", null,
1463                                R.string.heavy_weight_notification,
1464                                notification, outId, root.userId);
1465                    } catch (RuntimeException e) {
1466                        Slog.w(ActivityManagerService.TAG,
1467                                "Error showing notification for heavy-weight app", e);
1468                    } catch (RemoteException e) {
1469                    }
1470                } catch (NameNotFoundException e) {
1471                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1472                }
1473            } break;
1474            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1475                INotificationManager inm = NotificationManager.getService();
1476                if (inm == null) {
1477                    return;
1478                }
1479                try {
1480                    inm.cancelNotificationWithTag("android", null,
1481                            R.string.heavy_weight_notification,  msg.arg1);
1482                } catch (RuntimeException e) {
1483                    Slog.w(ActivityManagerService.TAG,
1484                            "Error canceling notification for service", e);
1485                } catch (RemoteException e) {
1486                }
1487            } break;
1488            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1489                synchronized (ActivityManagerService.this) {
1490                    checkExcessivePowerUsageLocked(true);
1491                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1492                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1493                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1494                }
1495            } break;
1496            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1497                synchronized (ActivityManagerService.this) {
1498                    ActivityRecord ar = (ActivityRecord)msg.obj;
1499                    if (mCompatModeDialog != null) {
1500                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1501                                ar.info.applicationInfo.packageName)) {
1502                            return;
1503                        }
1504                        mCompatModeDialog.dismiss();
1505                        mCompatModeDialog = null;
1506                    }
1507                    if (ar != null && false) {
1508                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1509                                ar.packageName)) {
1510                            int mode = mCompatModePackages.computeCompatModeLocked(
1511                                    ar.info.applicationInfo);
1512                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1513                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1514                                mCompatModeDialog = new CompatModeDialog(
1515                                        ActivityManagerService.this, mContext,
1516                                        ar.info.applicationInfo);
1517                                mCompatModeDialog.show();
1518                            }
1519                        }
1520                    }
1521                }
1522                break;
1523            }
1524            case DISPATCH_PROCESSES_CHANGED: {
1525                dispatchProcessesChanged();
1526                break;
1527            }
1528            case DISPATCH_PROCESS_DIED: {
1529                final int pid = msg.arg1;
1530                final int uid = msg.arg2;
1531                dispatchProcessDied(pid, uid);
1532                break;
1533            }
1534            case REPORT_MEM_USAGE_MSG: {
1535                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1536                Thread thread = new Thread() {
1537                    @Override public void run() {
1538                        final SparseArray<ProcessMemInfo> infoMap
1539                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1540                        for (int i=0, N=memInfos.size(); i<N; i++) {
1541                            ProcessMemInfo mi = memInfos.get(i);
1542                            infoMap.put(mi.pid, mi);
1543                        }
1544                        updateCpuStatsNow();
1545                        synchronized (mProcessCpuThread) {
1546                            final int N = mProcessCpuTracker.countStats();
1547                            for (int i=0; i<N; i++) {
1548                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1549                                if (st.vsize > 0) {
1550                                    long pss = Debug.getPss(st.pid, null);
1551                                    if (pss > 0) {
1552                                        if (infoMap.indexOfKey(st.pid) < 0) {
1553                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1554                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1555                                            mi.pss = pss;
1556                                            memInfos.add(mi);
1557                                        }
1558                                    }
1559                                }
1560                            }
1561                        }
1562
1563                        long totalPss = 0;
1564                        for (int i=0, N=memInfos.size(); i<N; i++) {
1565                            ProcessMemInfo mi = memInfos.get(i);
1566                            if (mi.pss == 0) {
1567                                mi.pss = Debug.getPss(mi.pid, null);
1568                            }
1569                            totalPss += mi.pss;
1570                        }
1571                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1572                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1573                                if (lhs.oomAdj != rhs.oomAdj) {
1574                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1575                                }
1576                                if (lhs.pss != rhs.pss) {
1577                                    return lhs.pss < rhs.pss ? 1 : -1;
1578                                }
1579                                return 0;
1580                            }
1581                        });
1582
1583                        StringBuilder tag = new StringBuilder(128);
1584                        StringBuilder stack = new StringBuilder(128);
1585                        tag.append("Low on memory -- ");
1586                        appendMemBucket(tag, totalPss, "total", false);
1587                        appendMemBucket(stack, totalPss, "total", true);
1588
1589                        StringBuilder logBuilder = new StringBuilder(1024);
1590                        logBuilder.append("Low on memory:\n");
1591
1592                        boolean firstLine = true;
1593                        int lastOomAdj = Integer.MIN_VALUE;
1594                        for (int i=0, N=memInfos.size(); i<N; i++) {
1595                            ProcessMemInfo mi = memInfos.get(i);
1596
1597                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1598                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1599                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1600                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1601                                if (lastOomAdj != mi.oomAdj) {
1602                                    lastOomAdj = mi.oomAdj;
1603                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1604                                        tag.append(" / ");
1605                                    }
1606                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1607                                        if (firstLine) {
1608                                            stack.append(":");
1609                                            firstLine = false;
1610                                        }
1611                                        stack.append("\n\t at ");
1612                                    } else {
1613                                        stack.append("$");
1614                                    }
1615                                } else {
1616                                    tag.append(" ");
1617                                    stack.append("$");
1618                                }
1619                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                    appendMemBucket(tag, mi.pss, mi.name, false);
1621                                }
1622                                appendMemBucket(stack, mi.pss, mi.name, true);
1623                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1624                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1625                                    stack.append("(");
1626                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1627                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1628                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1629                                            stack.append(":");
1630                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1631                                        }
1632                                    }
1633                                    stack.append(")");
1634                                }
1635                            }
1636
1637                            logBuilder.append("  ");
1638                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1639                            logBuilder.append(' ');
1640                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1641                            logBuilder.append(' ');
1642                            ProcessList.appendRamKb(logBuilder, mi.pss);
1643                            logBuilder.append(" kB: ");
1644                            logBuilder.append(mi.name);
1645                            logBuilder.append(" (");
1646                            logBuilder.append(mi.pid);
1647                            logBuilder.append(") ");
1648                            logBuilder.append(mi.adjType);
1649                            logBuilder.append('\n');
1650                            if (mi.adjReason != null) {
1651                                logBuilder.append("                      ");
1652                                logBuilder.append(mi.adjReason);
1653                                logBuilder.append('\n');
1654                            }
1655                        }
1656
1657                        logBuilder.append("           ");
1658                        ProcessList.appendRamKb(logBuilder, totalPss);
1659                        logBuilder.append(" kB: TOTAL\n");
1660
1661                        long[] infos = new long[Debug.MEMINFO_COUNT];
1662                        Debug.getMemInfo(infos);
1663                        logBuilder.append("  MemInfo: ");
1664                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1667                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1668                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1669                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1670                            logBuilder.append("  ZRAM: ");
1671                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1672                            logBuilder.append(" kB RAM, ");
1673                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1674                            logBuilder.append(" kB swap total, ");
1675                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1676                            logBuilder.append(" kB swap free\n");
1677                        }
1678                        Slog.i(TAG, logBuilder.toString());
1679
1680                        StringBuilder dropBuilder = new StringBuilder(1024);
1681                        /*
1682                        StringWriter oomSw = new StringWriter();
1683                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1684                        StringWriter catSw = new StringWriter();
1685                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1686                        String[] emptyArgs = new String[] { };
1687                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1688                        oomPw.flush();
1689                        String oomString = oomSw.toString();
1690                        */
1691                        dropBuilder.append(stack);
1692                        dropBuilder.append('\n');
1693                        dropBuilder.append('\n');
1694                        dropBuilder.append(logBuilder);
1695                        dropBuilder.append('\n');
1696                        /*
1697                        dropBuilder.append(oomString);
1698                        dropBuilder.append('\n');
1699                        */
1700                        StringWriter catSw = new StringWriter();
1701                        synchronized (ActivityManagerService.this) {
1702                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                            String[] emptyArgs = new String[] { };
1704                            catPw.println();
1705                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1706                            catPw.println();
1707                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1708                                    false, false, null);
1709                            catPw.println();
1710                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1711                            catPw.flush();
1712                        }
1713                        dropBuilder.append(catSw.toString());
1714                        addErrorToDropBox("lowmem", null, "system_server", null,
1715                                null, tag.toString(), dropBuilder.toString(), null, null);
1716                        //Slog.i(TAG, "Sent to dropbox:");
1717                        //Slog.i(TAG, dropBuilder.toString());
1718                        synchronized (ActivityManagerService.this) {
1719                            long now = SystemClock.uptimeMillis();
1720                            if (mLastMemUsageReportTime < now) {
1721                                mLastMemUsageReportTime = now;
1722                            }
1723                        }
1724                    }
1725                };
1726                thread.start();
1727                break;
1728            }
1729            case REPORT_USER_SWITCH_MSG: {
1730                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1731                break;
1732            }
1733            case CONTINUE_USER_SWITCH_MSG: {
1734                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1735                break;
1736            }
1737            case USER_SWITCH_TIMEOUT_MSG: {
1738                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1739                break;
1740            }
1741            case IMMERSIVE_MODE_LOCK_MSG: {
1742                final boolean nextState = (msg.arg1 != 0);
1743                if (mUpdateLock.isHeld() != nextState) {
1744                    if (DEBUG_IMMERSIVE) {
1745                        final ActivityRecord r = (ActivityRecord) msg.obj;
1746                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1747                    }
1748                    if (nextState) {
1749                        mUpdateLock.acquire();
1750                    } else {
1751                        mUpdateLock.release();
1752                    }
1753                }
1754                break;
1755            }
1756            case PERSIST_URI_GRANTS_MSG: {
1757                writeGrantedUriPermissions();
1758                break;
1759            }
1760            case REQUEST_ALL_PSS_MSG: {
1761                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1762                break;
1763            }
1764            case START_PROFILES_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    startProfilesLocked();
1767                }
1768                break;
1769            }
1770            case UPDATE_TIME: {
1771                synchronized (ActivityManagerService.this) {
1772                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1773                        ProcessRecord r = mLruProcesses.get(i);
1774                        if (r.thread != null) {
1775                            try {
1776                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1777                            } catch (RemoteException ex) {
1778                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1779                            }
1780                        }
1781                    }
1782                }
1783                break;
1784            }
1785            case SYSTEM_USER_START_MSG: {
1786                mSystemServiceManager.startUser(msg.arg1);
1787                break;
1788            }
1789            case SYSTEM_USER_CURRENT_MSG: {
1790                mSystemServiceManager.switchUser(msg.arg1);
1791                break;
1792            }
1793            }
1794        }
1795    };
1796
1797    static final int COLLECT_PSS_BG_MSG = 1;
1798
1799    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1800        @Override
1801        public void handleMessage(Message msg) {
1802            switch (msg.what) {
1803            case COLLECT_PSS_BG_MSG: {
1804                int i=0, num=0;
1805                long start = SystemClock.uptimeMillis();
1806                long[] tmp = new long[1];
1807                do {
1808                    ProcessRecord proc;
1809                    int procState;
1810                    int pid;
1811                    synchronized (ActivityManagerService.this) {
1812                        if (i >= mPendingPssProcesses.size()) {
1813                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1814                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1815                            mPendingPssProcesses.clear();
1816                            return;
1817                        }
1818                        proc = mPendingPssProcesses.get(i);
1819                        procState = proc.pssProcState;
1820                        if (proc.thread != null && procState == proc.setProcState) {
1821                            pid = proc.pid;
1822                        } else {
1823                            proc = null;
1824                            pid = 0;
1825                        }
1826                        i++;
1827                    }
1828                    if (proc != null) {
1829                        long pss = Debug.getPss(pid, tmp);
1830                        synchronized (ActivityManagerService.this) {
1831                            if (proc.thread != null && proc.setProcState == procState
1832                                    && proc.pid == pid) {
1833                                num++;
1834                                proc.lastPssTime = SystemClock.uptimeMillis();
1835                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1836                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1837                                        + ": " + pss + " lastPss=" + proc.lastPss
1838                                        + " state=" + ProcessList.makeProcStateString(procState));
1839                                if (proc.initialIdlePss == 0) {
1840                                    proc.initialIdlePss = pss;
1841                                }
1842                                proc.lastPss = pss;
1843                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1844                                    proc.lastCachedPss = pss;
1845                                }
1846                            }
1847                        }
1848                    }
1849                } while (true);
1850            }
1851            }
1852        }
1853    };
1854
1855    /**
1856     * Monitor for package changes and update our internal state.
1857     */
1858    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1859        @Override
1860        public void onPackageRemoved(String packageName, int uid) {
1861            // Remove all tasks with activities in the specified package from the list of recent tasks
1862            synchronized (ActivityManagerService.this) {
1863                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1864                    TaskRecord tr = mRecentTasks.get(i);
1865                    ComponentName cn = tr.intent.getComponent();
1866                    if (cn != null && cn.getPackageName().equals(packageName)) {
1867                        // If the package name matches, remove the task and kill the process
1868                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1869                    }
1870                }
1871            }
1872        }
1873
1874        @Override
1875        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1876            onPackageModified(packageName);
1877            return true;
1878        }
1879
1880        @Override
1881        public void onPackageModified(String packageName) {
1882            final PackageManager pm = mContext.getPackageManager();
1883            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1884                    new ArrayList<Pair<Intent, Integer>>();
1885            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1886            // Copy the list of recent tasks so that we don't hold onto the lock on
1887            // ActivityManagerService for long periods while checking if components exist.
1888            synchronized (ActivityManagerService.this) {
1889                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1890                    TaskRecord tr = mRecentTasks.get(i);
1891                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1892                }
1893            }
1894            // Check the recent tasks and filter out all tasks with components that no longer exist.
1895            Intent tmpI = new Intent();
1896            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1897                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1898                ComponentName cn = p.first.getComponent();
1899                if (cn != null && cn.getPackageName().equals(packageName)) {
1900                    try {
1901                        // Add the task to the list to remove if the component no longer exists
1902                        tmpI.setComponent(cn);
1903                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1904                            tasksToRemove.add(p.second);
1905                        }
1906                    } catch (Exception e) {}
1907                }
1908            }
1909            // Prune all the tasks with removed components from the list of recent tasks
1910            synchronized (ActivityManagerService.this) {
1911                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1912                    // Remove the task but don't kill the process (since other components in that
1913                    // package may still be running and in the background)
1914                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1915                }
1916            }
1917        }
1918
1919        @Override
1920        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1921            // Force stop the specified packages
1922            if (packages != null) {
1923                for (String pkg : packages) {
1924                    synchronized (ActivityManagerService.this) {
1925                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1926                                "finished booting")) {
1927                            return true;
1928                        }
1929                    }
1930                }
1931            }
1932            return false;
1933        }
1934    };
1935
1936    public void setSystemProcess() {
1937        try {
1938            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1939            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1940            ServiceManager.addService("meminfo", new MemBinder(this));
1941            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1942            ServiceManager.addService("dbinfo", new DbBinder(this));
1943            if (MONITOR_CPU_USAGE) {
1944                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1945            }
1946            ServiceManager.addService("permission", new PermissionController(this));
1947
1948            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1949                    "android", STOCK_PM_FLAGS);
1950            mSystemThread.installSystemApplicationInfo(info);
1951
1952            synchronized (this) {
1953                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1954                app.persistent = true;
1955                app.pid = MY_PID;
1956                app.maxAdj = ProcessList.SYSTEM_ADJ;
1957                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1958                mProcessNames.put(app.processName, app.uid, app);
1959                synchronized (mPidsSelfLocked) {
1960                    mPidsSelfLocked.put(app.pid, app);
1961                }
1962                updateLruProcessLocked(app, false, null);
1963                updateOomAdjLocked();
1964            }
1965        } catch (PackageManager.NameNotFoundException e) {
1966            throw new RuntimeException(
1967                    "Unable to find android system package", e);
1968        }
1969    }
1970
1971    public void setWindowManager(WindowManagerService wm) {
1972        mWindowManager = wm;
1973        mStackSupervisor.setWindowManager(wm);
1974    }
1975
1976    public void startObservingNativeCrashes() {
1977        final NativeCrashListener ncl = new NativeCrashListener(this);
1978        ncl.start();
1979    }
1980
1981    public IAppOpsService getAppOpsService() {
1982        return mAppOpsService;
1983    }
1984
1985    static class MemBinder extends Binder {
1986        ActivityManagerService mActivityManagerService;
1987        MemBinder(ActivityManagerService activityManagerService) {
1988            mActivityManagerService = activityManagerService;
1989        }
1990
1991        @Override
1992        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1993            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1994                    != PackageManager.PERMISSION_GRANTED) {
1995                pw.println("Permission Denial: can't dump meminfo from from pid="
1996                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1997                        + " without permission " + android.Manifest.permission.DUMP);
1998                return;
1999            }
2000
2001            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2002        }
2003    }
2004
2005    static class GraphicsBinder extends Binder {
2006        ActivityManagerService mActivityManagerService;
2007        GraphicsBinder(ActivityManagerService activityManagerService) {
2008            mActivityManagerService = activityManagerService;
2009        }
2010
2011        @Override
2012        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2013            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2014                    != PackageManager.PERMISSION_GRANTED) {
2015                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2016                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2017                        + " without permission " + android.Manifest.permission.DUMP);
2018                return;
2019            }
2020
2021            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2022        }
2023    }
2024
2025    static class DbBinder extends Binder {
2026        ActivityManagerService mActivityManagerService;
2027        DbBinder(ActivityManagerService activityManagerService) {
2028            mActivityManagerService = activityManagerService;
2029        }
2030
2031        @Override
2032        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2033            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2034                    != PackageManager.PERMISSION_GRANTED) {
2035                pw.println("Permission Denial: can't dump dbinfo from from pid="
2036                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2037                        + " without permission " + android.Manifest.permission.DUMP);
2038                return;
2039            }
2040
2041            mActivityManagerService.dumpDbInfo(fd, pw, args);
2042        }
2043    }
2044
2045    static class CpuBinder extends Binder {
2046        ActivityManagerService mActivityManagerService;
2047        CpuBinder(ActivityManagerService activityManagerService) {
2048            mActivityManagerService = activityManagerService;
2049        }
2050
2051        @Override
2052        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2053            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2054                    != PackageManager.PERMISSION_GRANTED) {
2055                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2056                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2057                        + " without permission " + android.Manifest.permission.DUMP);
2058                return;
2059            }
2060
2061            synchronized (mActivityManagerService.mProcessCpuThread) {
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2063                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2064                        SystemClock.uptimeMillis()));
2065            }
2066        }
2067    }
2068
2069    public static final class Lifecycle extends SystemService {
2070        private final ActivityManagerService mService;
2071
2072        public Lifecycle(Context context) {
2073            super(context);
2074            mService = new ActivityManagerService(context);
2075        }
2076
2077        @Override
2078        public void onStart() {
2079            mService.start();
2080        }
2081
2082        public ActivityManagerService getService() {
2083            return mService;
2084        }
2085    }
2086
2087    // Note: This method is invoked on the main thread but may need to attach various
2088    // handlers to other threads.  So take care to be explicit about the looper.
2089    public ActivityManagerService(Context systemContext) {
2090        mContext = systemContext;
2091        mFactoryTest = FactoryTest.getMode();
2092        mSystemThread = ActivityThread.currentActivityThread();
2093
2094        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2095
2096        mHandlerThread = new ServiceThread(TAG,
2097                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2098        mHandlerThread.start();
2099        mHandler = new MainHandler(mHandlerThread.getLooper());
2100
2101        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2102                "foreground", BROADCAST_FG_TIMEOUT, false);
2103        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2104                "background", BROADCAST_BG_TIMEOUT, true);
2105        mBroadcastQueues[0] = mFgBroadcastQueue;
2106        mBroadcastQueues[1] = mBgBroadcastQueue;
2107
2108        mServices = new ActiveServices(this);
2109        mProviderMap = new ProviderMap(this);
2110
2111        // TODO: Move creation of battery stats service outside of activity manager service.
2112        File dataDir = Environment.getDataDirectory();
2113        File systemDir = new File(dataDir, "system");
2114        systemDir.mkdirs();
2115        mBatteryStatsService = new BatteryStatsService(new File(
2116                systemDir, "batterystats.bin").toString(), mHandler);
2117        mBatteryStatsService.getActiveStatistics().readLocked();
2118        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2119        mOnBattery = DEBUG_POWER ? true
2120                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2121        mBatteryStatsService.getActiveStatistics().setCallback(this);
2122
2123        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2124
2125        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2126        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2127
2128        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2129
2130        // User 0 is the first and only user that runs at boot.
2131        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2132        mUserLru.add(Integer.valueOf(0));
2133        updateStartedUserArrayLocked();
2134
2135        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2136            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2137
2138        mConfiguration.setToDefaults();
2139        mConfiguration.setLocale(Locale.getDefault());
2140
2141        mConfigurationSeq = mConfiguration.seq = 1;
2142        mProcessCpuTracker.init();
2143
2144        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2145        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2146        mStackSupervisor = new ActivityStackSupervisor(this);
2147        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2148
2149        mProcessCpuThread = new Thread("CpuTracker") {
2150            @Override
2151            public void run() {
2152                while (true) {
2153                    try {
2154                        try {
2155                            synchronized(this) {
2156                                final long now = SystemClock.uptimeMillis();
2157                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2158                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2159                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2160                                //        + ", write delay=" + nextWriteDelay);
2161                                if (nextWriteDelay < nextCpuDelay) {
2162                                    nextCpuDelay = nextWriteDelay;
2163                                }
2164                                if (nextCpuDelay > 0) {
2165                                    mProcessCpuMutexFree.set(true);
2166                                    this.wait(nextCpuDelay);
2167                                }
2168                            }
2169                        } catch (InterruptedException e) {
2170                        }
2171                        updateCpuStatsNow();
2172                    } catch (Exception e) {
2173                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2174                    }
2175                }
2176            }
2177        };
2178
2179        Watchdog.getInstance().addMonitor(this);
2180        Watchdog.getInstance().addThread(mHandler);
2181    }
2182
2183    public void setSystemServiceManager(SystemServiceManager mgr) {
2184        mSystemServiceManager = mgr;
2185    }
2186
2187    private void start() {
2188        mProcessCpuThread.start();
2189
2190        mBatteryStatsService.publish(mContext);
2191        mUsageStatsService.publish(mContext);
2192        mAppOpsService.publish(mContext);
2193        Slog.d("AppOps", "AppOpsService published");
2194        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2195    }
2196
2197    @Override
2198    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2199            throws RemoteException {
2200        if (code == SYSPROPS_TRANSACTION) {
2201            // We need to tell all apps about the system property change.
2202            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2203            synchronized(this) {
2204                final int NP = mProcessNames.getMap().size();
2205                for (int ip=0; ip<NP; ip++) {
2206                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2207                    final int NA = apps.size();
2208                    for (int ia=0; ia<NA; ia++) {
2209                        ProcessRecord app = apps.valueAt(ia);
2210                        if (app.thread != null) {
2211                            procs.add(app.thread.asBinder());
2212                        }
2213                    }
2214                }
2215            }
2216
2217            int N = procs.size();
2218            for (int i=0; i<N; i++) {
2219                Parcel data2 = Parcel.obtain();
2220                try {
2221                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2222                } catch (RemoteException e) {
2223                }
2224                data2.recycle();
2225            }
2226        }
2227        try {
2228            return super.onTransact(code, data, reply, flags);
2229        } catch (RuntimeException e) {
2230            // The activity manager only throws security exceptions, so let's
2231            // log all others.
2232            if (!(e instanceof SecurityException)) {
2233                Slog.wtf(TAG, "Activity Manager Crash", e);
2234            }
2235            throw e;
2236        }
2237    }
2238
2239    void updateCpuStats() {
2240        final long now = SystemClock.uptimeMillis();
2241        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2242            return;
2243        }
2244        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2245            synchronized (mProcessCpuThread) {
2246                mProcessCpuThread.notify();
2247            }
2248        }
2249    }
2250
2251    void updateCpuStatsNow() {
2252        synchronized (mProcessCpuThread) {
2253            mProcessCpuMutexFree.set(false);
2254            final long now = SystemClock.uptimeMillis();
2255            boolean haveNewCpuStats = false;
2256
2257            if (MONITOR_CPU_USAGE &&
2258                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2259                mLastCpuTime.set(now);
2260                haveNewCpuStats = true;
2261                mProcessCpuTracker.update();
2262                //Slog.i(TAG, mProcessCpu.printCurrentState());
2263                //Slog.i(TAG, "Total CPU usage: "
2264                //        + mProcessCpu.getTotalCpuPercent() + "%");
2265
2266                // Slog the cpu usage if the property is set.
2267                if ("true".equals(SystemProperties.get("events.cpu"))) {
2268                    int user = mProcessCpuTracker.getLastUserTime();
2269                    int system = mProcessCpuTracker.getLastSystemTime();
2270                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2271                    int irq = mProcessCpuTracker.getLastIrqTime();
2272                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2273                    int idle = mProcessCpuTracker.getLastIdleTime();
2274
2275                    int total = user + system + iowait + irq + softIrq + idle;
2276                    if (total == 0) total = 1;
2277
2278                    EventLog.writeEvent(EventLogTags.CPU,
2279                            ((user+system+iowait+irq+softIrq) * 100) / total,
2280                            (user * 100) / total,
2281                            (system * 100) / total,
2282                            (iowait * 100) / total,
2283                            (irq * 100) / total,
2284                            (softIrq * 100) / total);
2285                }
2286            }
2287
2288            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2289            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2290            synchronized(bstats) {
2291                synchronized(mPidsSelfLocked) {
2292                    if (haveNewCpuStats) {
2293                        if (mOnBattery) {
2294                            int perc = bstats.startAddingCpuLocked();
2295                            int totalUTime = 0;
2296                            int totalSTime = 0;
2297                            final int N = mProcessCpuTracker.countStats();
2298                            for (int i=0; i<N; i++) {
2299                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2300                                if (!st.working) {
2301                                    continue;
2302                                }
2303                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2304                                int otherUTime = (st.rel_utime*perc)/100;
2305                                int otherSTime = (st.rel_stime*perc)/100;
2306                                totalUTime += otherUTime;
2307                                totalSTime += otherSTime;
2308                                if (pr != null) {
2309                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2312                                                pr.info.uid, pr.processName);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2318                                } else {
2319                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2320                                    if (ps == null || !ps.isActive()) {
2321                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2322                                                bstats.mapUid(st.uid), st.name);
2323                                    }
2324                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2325                                            st.rel_stime-otherSTime);
2326                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2327                                }
2328                            }
2329                            bstats.finishAddingCpuLocked(perc, totalUTime,
2330                                    totalSTime, cpuSpeedTimes);
2331                        }
2332                    }
2333                }
2334
2335                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2336                    mLastWriteTime = now;
2337                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2338                }
2339            }
2340        }
2341    }
2342
2343    @Override
2344    public void batteryNeedsCpuUpdate() {
2345        updateCpuStatsNow();
2346    }
2347
2348    @Override
2349    public void batteryPowerChanged(boolean onBattery) {
2350        // When plugging in, update the CPU stats first before changing
2351        // the plug state.
2352        updateCpuStatsNow();
2353        synchronized (this) {
2354            synchronized(mPidsSelfLocked) {
2355                mOnBattery = DEBUG_POWER ? true : onBattery;
2356            }
2357        }
2358    }
2359
2360    /**
2361     * Initialize the application bind args. These are passed to each
2362     * process when the bindApplication() IPC is sent to the process. They're
2363     * lazily setup to make sure the services are running when they're asked for.
2364     */
2365    private HashMap<String, IBinder> getCommonServicesLocked() {
2366        if (mAppBindArgs == null) {
2367            mAppBindArgs = new HashMap<String, IBinder>();
2368
2369            // Setup the application init args
2370            mAppBindArgs.put("package", ServiceManager.getService("package"));
2371            mAppBindArgs.put("window", ServiceManager.getService("window"));
2372            mAppBindArgs.put(Context.ALARM_SERVICE,
2373                    ServiceManager.getService(Context.ALARM_SERVICE));
2374        }
2375        return mAppBindArgs;
2376    }
2377
2378    final void setFocusedActivityLocked(ActivityRecord r) {
2379        if (mFocusedActivity != r) {
2380            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2381            mFocusedActivity = r;
2382            if (r.task != null && r.task.voiceInteractor != null) {
2383                startRunningVoiceLocked();
2384            } else {
2385                finishRunningVoiceLocked();
2386            }
2387            mStackSupervisor.setFocusedStack(r);
2388            if (r != null) {
2389                mWindowManager.setFocusedApp(r.appToken, true);
2390            }
2391            applyUpdateLockStateLocked(r);
2392        }
2393    }
2394
2395    final void clearFocusedActivity(ActivityRecord r) {
2396        if (mFocusedActivity == r) {
2397            mFocusedActivity = null;
2398        }
2399    }
2400
2401    @Override
2402    public void setFocusedStack(int stackId) {
2403        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2404        synchronized (ActivityManagerService.this) {
2405            ActivityStack stack = mStackSupervisor.getStack(stackId);
2406            if (stack != null) {
2407                ActivityRecord r = stack.topRunningActivityLocked(null);
2408                if (r != null) {
2409                    setFocusedActivityLocked(r);
2410                }
2411            }
2412        }
2413    }
2414
2415    @Override
2416    public void notifyActivityDrawn(IBinder token) {
2417        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2418        synchronized (this) {
2419            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2420            if (r != null) {
2421                r.task.stack.notifyActivityDrawnLocked(r);
2422            }
2423        }
2424    }
2425
2426    final void applyUpdateLockStateLocked(ActivityRecord r) {
2427        // Modifications to the UpdateLock state are done on our handler, outside
2428        // the activity manager's locks.  The new state is determined based on the
2429        // state *now* of the relevant activity record.  The object is passed to
2430        // the handler solely for logging detail, not to be consulted/modified.
2431        final boolean nextState = r != null && r.immersive;
2432        mHandler.sendMessage(
2433                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2434    }
2435
2436    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2437        Message msg = Message.obtain();
2438        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2439        msg.obj = r.task.askedCompatMode ? null : r;
2440        mHandler.sendMessage(msg);
2441    }
2442
2443    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2444            String what, Object obj, ProcessRecord srcApp) {
2445        app.lastActivityTime = now;
2446
2447        if (app.activities.size() > 0) {
2448            // Don't want to touch dependent processes that are hosting activities.
2449            return index;
2450        }
2451
2452        int lrui = mLruProcesses.lastIndexOf(app);
2453        if (lrui < 0) {
2454            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2455                    + what + " " + obj + " from " + srcApp);
2456            return index;
2457        }
2458
2459        if (lrui >= index) {
2460            // Don't want to cause this to move dependent processes *back* in the
2461            // list as if they were less frequently used.
2462            return index;
2463        }
2464
2465        if (lrui >= mLruProcessActivityStart) {
2466            // Don't want to touch dependent processes that are hosting activities.
2467            return index;
2468        }
2469
2470        mLruProcesses.remove(lrui);
2471        if (index > 0) {
2472            index--;
2473        }
2474        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2475                + " in LRU list: " + app);
2476        mLruProcesses.add(index, app);
2477        return index;
2478    }
2479
2480    final void removeLruProcessLocked(ProcessRecord app) {
2481        int lrui = mLruProcesses.lastIndexOf(app);
2482        if (lrui >= 0) {
2483            if (lrui <= mLruProcessActivityStart) {
2484                mLruProcessActivityStart--;
2485            }
2486            if (lrui <= mLruProcessServiceStart) {
2487                mLruProcessServiceStart--;
2488            }
2489            mLruProcesses.remove(lrui);
2490        }
2491    }
2492
2493    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2494            ProcessRecord client) {
2495        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2496                || app.treatLikeActivity;
2497        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2498        if (!activityChange && hasActivity) {
2499            // The process has activities, so we are only allowing activity-based adjustments
2500            // to move it.  It should be kept in the front of the list with other
2501            // processes that have activities, and we don't want those to change their
2502            // order except due to activity operations.
2503            return;
2504        }
2505
2506        mLruSeq++;
2507        final long now = SystemClock.uptimeMillis();
2508        app.lastActivityTime = now;
2509
2510        // First a quick reject: if the app is already at the position we will
2511        // put it, then there is nothing to do.
2512        if (hasActivity) {
2513            final int N = mLruProcesses.size();
2514            if (N > 0 && mLruProcesses.get(N-1) == app) {
2515                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2516                return;
2517            }
2518        } else {
2519            if (mLruProcessServiceStart > 0
2520                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2521                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2522                return;
2523            }
2524        }
2525
2526        int lrui = mLruProcesses.lastIndexOf(app);
2527
2528        if (app.persistent && lrui >= 0) {
2529            // We don't care about the position of persistent processes, as long as
2530            // they are in the list.
2531            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2532            return;
2533        }
2534
2535        /* In progress: compute new position first, so we can avoid doing work
2536           if the process is not actually going to move.  Not yet working.
2537        int addIndex;
2538        int nextIndex;
2539        boolean inActivity = false, inService = false;
2540        if (hasActivity) {
2541            // Process has activities, put it at the very tipsy-top.
2542            addIndex = mLruProcesses.size();
2543            nextIndex = mLruProcessServiceStart;
2544            inActivity = true;
2545        } else if (hasService) {
2546            // Process has services, put it at the top of the service list.
2547            addIndex = mLruProcessActivityStart;
2548            nextIndex = mLruProcessServiceStart;
2549            inActivity = true;
2550            inService = true;
2551        } else  {
2552            // Process not otherwise of interest, it goes to the top of the non-service area.
2553            addIndex = mLruProcessServiceStart;
2554            if (client != null) {
2555                int clientIndex = mLruProcesses.lastIndexOf(client);
2556                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2557                        + app);
2558                if (clientIndex >= 0 && addIndex > clientIndex) {
2559                    addIndex = clientIndex;
2560                }
2561            }
2562            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2563        }
2564
2565        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2566                + mLruProcessActivityStart + "): " + app);
2567        */
2568
2569        if (lrui >= 0) {
2570            if (lrui < mLruProcessActivityStart) {
2571                mLruProcessActivityStart--;
2572            }
2573            if (lrui < mLruProcessServiceStart) {
2574                mLruProcessServiceStart--;
2575            }
2576            /*
2577            if (addIndex > lrui) {
2578                addIndex--;
2579            }
2580            if (nextIndex > lrui) {
2581                nextIndex--;
2582            }
2583            */
2584            mLruProcesses.remove(lrui);
2585        }
2586
2587        /*
2588        mLruProcesses.add(addIndex, app);
2589        if (inActivity) {
2590            mLruProcessActivityStart++;
2591        }
2592        if (inService) {
2593            mLruProcessActivityStart++;
2594        }
2595        */
2596
2597        int nextIndex;
2598        if (hasActivity) {
2599            final int N = mLruProcesses.size();
2600            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2601                // Process doesn't have activities, but has clients with
2602                // activities...  move it up, but one below the top (the top
2603                // should always have a real activity).
2604                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2605                mLruProcesses.add(N-1, app);
2606                // To keep it from spamming the LRU list (by making a bunch of clients),
2607                // we will push down any other entries owned by the app.
2608                final int uid = app.info.uid;
2609                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2610                    ProcessRecord subProc = mLruProcesses.get(i);
2611                    if (subProc.info.uid == uid) {
2612                        // We want to push this one down the list.  If the process after
2613                        // it is for the same uid, however, don't do so, because we don't
2614                        // want them internally to be re-ordered.
2615                        if (mLruProcesses.get(i-1).info.uid != uid) {
2616                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2617                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2618                            ProcessRecord tmp = mLruProcesses.get(i);
2619                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2620                            mLruProcesses.set(i-1, tmp);
2621                            i--;
2622                        }
2623                    } else {
2624                        // A gap, we can stop here.
2625                        break;
2626                    }
2627                }
2628            } else {
2629                // Process has activities, put it at the very tipsy-top.
2630                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2631                mLruProcesses.add(app);
2632            }
2633            nextIndex = mLruProcessServiceStart;
2634        } else if (hasService) {
2635            // Process has services, put it at the top of the service list.
2636            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2637            mLruProcesses.add(mLruProcessActivityStart, app);
2638            nextIndex = mLruProcessServiceStart;
2639            mLruProcessActivityStart++;
2640        } else  {
2641            // Process not otherwise of interest, it goes to the top of the non-service area.
2642            int index = mLruProcessServiceStart;
2643            if (client != null) {
2644                // If there is a client, don't allow the process to be moved up higher
2645                // in the list than that client.
2646                int clientIndex = mLruProcesses.lastIndexOf(client);
2647                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2648                        + " when updating " + app);
2649                if (clientIndex <= lrui) {
2650                    // Don't allow the client index restriction to push it down farther in the
2651                    // list than it already is.
2652                    clientIndex = lrui;
2653                }
2654                if (clientIndex >= 0 && index > clientIndex) {
2655                    index = clientIndex;
2656                }
2657            }
2658            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2659            mLruProcesses.add(index, app);
2660            nextIndex = index-1;
2661            mLruProcessActivityStart++;
2662            mLruProcessServiceStart++;
2663        }
2664
2665        // If the app is currently using a content provider or service,
2666        // bump those processes as well.
2667        for (int j=app.connections.size()-1; j>=0; j--) {
2668            ConnectionRecord cr = app.connections.valueAt(j);
2669            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2670                    && cr.binding.service.app != null
2671                    && cr.binding.service.app.lruSeq != mLruSeq
2672                    && !cr.binding.service.app.persistent) {
2673                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2674                        "service connection", cr, app);
2675            }
2676        }
2677        for (int j=app.conProviders.size()-1; j>=0; j--) {
2678            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2679            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2680                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2681                        "provider reference", cpr, app);
2682            }
2683        }
2684    }
2685
2686    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2687        if (uid == Process.SYSTEM_UID) {
2688            // The system gets to run in any process.  If there are multiple
2689            // processes with the same uid, just pick the first (this
2690            // should never happen).
2691            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2692            if (procs == null) return null;
2693            final int N = procs.size();
2694            for (int i = 0; i < N; i++) {
2695                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2696            }
2697        }
2698        ProcessRecord proc = mProcessNames.get(processName, uid);
2699        if (false && proc != null && !keepIfLarge
2700                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2701                && proc.lastCachedPss >= 4000) {
2702            // Turn this condition on to cause killing to happen regularly, for testing.
2703            if (proc.baseProcessTracker != null) {
2704                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2705            }
2706            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2707                    + "k from cached");
2708        } else if (proc != null && !keepIfLarge
2709                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2710                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2711            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2712            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2713                if (proc.baseProcessTracker != null) {
2714                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2715                }
2716                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2717                        + "k from cached");
2718            }
2719        }
2720        return proc;
2721    }
2722
2723    void ensurePackageDexOpt(String packageName) {
2724        IPackageManager pm = AppGlobals.getPackageManager();
2725        try {
2726            if (pm.performDexOpt(packageName)) {
2727                mDidDexOpt = true;
2728            }
2729        } catch (RemoteException e) {
2730        }
2731    }
2732
2733    boolean isNextTransitionForward() {
2734        int transit = mWindowManager.getPendingAppTransition();
2735        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_OPEN
2737                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2738    }
2739
2740    final ProcessRecord startProcessLocked(String processName,
2741            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2742            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2743            boolean isolated, boolean keepIfLarge) {
2744        ProcessRecord app;
2745        if (!isolated) {
2746            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2747        } else {
2748            // If this is an isolated process, it can't re-use an existing process.
2749            app = null;
2750        }
2751        // We don't have to do anything more if:
2752        // (1) There is an existing application record; and
2753        // (2) The caller doesn't think it is dead, OR there is no thread
2754        //     object attached to it so we know it couldn't have crashed; and
2755        // (3) There is a pid assigned to it, so it is either starting or
2756        //     already running.
2757        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2758                + " app=" + app + " knownToBeDead=" + knownToBeDead
2759                + " thread=" + (app != null ? app.thread : null)
2760                + " pid=" + (app != null ? app.pid : -1));
2761        if (app != null && app.pid > 0) {
2762            if (!knownToBeDead || app.thread == null) {
2763                // We already have the app running, or are waiting for it to
2764                // come up (we have a pid but not yet its thread), so keep it.
2765                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2766                // If this is a new package in the process, add the package to the list
2767                app.addPackage(info.packageName, mProcessStats);
2768                return app;
2769            }
2770
2771            // An application record is attached to a previous process,
2772            // clean it up now.
2773            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2774            handleAppDiedLocked(app, true, true);
2775        }
2776
2777        String hostingNameStr = hostingName != null
2778                ? hostingName.flattenToShortString() : null;
2779
2780        if (!isolated) {
2781            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2782                // If we are in the background, then check to see if this process
2783                // is bad.  If so, we will just silently fail.
2784                if (mBadProcesses.get(info.processName, info.uid) != null) {
2785                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2786                            + "/" + info.processName);
2787                    return null;
2788                }
2789            } else {
2790                // When the user is explicitly starting a process, then clear its
2791                // crash count so that we won't make it bad until they see at
2792                // least one crash dialog again, and make the process good again
2793                // if it had been bad.
2794                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2795                        + "/" + info.processName);
2796                mProcessCrashTimes.remove(info.processName, info.uid);
2797                if (mBadProcesses.get(info.processName, info.uid) != null) {
2798                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2799                            UserHandle.getUserId(info.uid), info.uid,
2800                            info.processName);
2801                    mBadProcesses.remove(info.processName, info.uid);
2802                    if (app != null) {
2803                        app.bad = false;
2804                    }
2805                }
2806            }
2807        }
2808
2809        if (app == null) {
2810            app = newProcessRecordLocked(info, processName, isolated);
2811            if (app == null) {
2812                Slog.w(TAG, "Failed making new process record for "
2813                        + processName + "/" + info.uid + " isolated=" + isolated);
2814                return null;
2815            }
2816            mProcessNames.put(processName, app.uid, app);
2817            if (isolated) {
2818                mIsolatedProcesses.put(app.uid, app);
2819            }
2820        } else {
2821            // If this is a new package in the process, add the package to the list
2822            app.addPackage(info.packageName, mProcessStats);
2823        }
2824
2825        // If the system is not ready yet, then hold off on starting this
2826        // process until it is.
2827        if (!mProcessesReady
2828                && !isAllowedWhileBooting(info)
2829                && !allowWhileBooting) {
2830            if (!mProcessesOnHold.contains(app)) {
2831                mProcessesOnHold.add(app);
2832            }
2833            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2834            return app;
2835        }
2836
2837        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2838        return (app.pid != 0) ? app : null;
2839    }
2840
2841    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2842        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2843    }
2844
2845    private final void startProcessLocked(ProcessRecord app,
2846            String hostingType, String hostingNameStr, String abiOverride) {
2847        if (app.pid > 0 && app.pid != MY_PID) {
2848            synchronized (mPidsSelfLocked) {
2849                mPidsSelfLocked.remove(app.pid);
2850                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2851            }
2852            app.setPid(0);
2853        }
2854
2855        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2856                "startProcessLocked removing on hold: " + app);
2857        mProcessesOnHold.remove(app);
2858
2859        updateCpuStats();
2860
2861        try {
2862            int uid = app.uid;
2863
2864            int[] gids = null;
2865            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2866            if (!app.isolated) {
2867                int[] permGids = null;
2868                try {
2869                    final PackageManager pm = mContext.getPackageManager();
2870                    permGids = pm.getPackageGids(app.info.packageName);
2871
2872                    if (Environment.isExternalStorageEmulated()) {
2873                        if (pm.checkPermission(
2874                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2875                                app.info.packageName) == PERMISSION_GRANTED) {
2876                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2877                        } else {
2878                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2879                        }
2880                    }
2881                } catch (PackageManager.NameNotFoundException e) {
2882                    Slog.w(TAG, "Unable to retrieve gids", e);
2883                }
2884
2885                /*
2886                 * Add shared application and profile GIDs so applications can share some
2887                 * resources like shared libraries and access user-wide resources
2888                 */
2889                if (permGids == null) {
2890                    gids = new int[2];
2891                } else {
2892                    gids = new int[permGids.length + 2];
2893                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2894                }
2895                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2896                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2897            }
2898            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2899                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2900                        && mTopComponent != null
2901                        && app.processName.equals(mTopComponent.getPackageName())) {
2902                    uid = 0;
2903                }
2904                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2905                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2906                    uid = 0;
2907                }
2908            }
2909            int debugFlags = 0;
2910            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2911                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2912                // Also turn on CheckJNI for debuggable apps. It's quite
2913                // awkward to turn on otherwise.
2914                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2915            }
2916            // Run the app in safe mode if its manifest requests so or the
2917            // system is booted in safe mode.
2918            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2919                mSafeMode == true) {
2920                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2921            }
2922            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2923                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2924            }
2925            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2926                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2927            }
2928            if ("1".equals(SystemProperties.get("debug.assert"))) {
2929                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2930            }
2931
2932            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2933            if (requiredAbi == null) {
2934                requiredAbi = Build.SUPPORTED_ABIS[0];
2935            }
2936
2937            // Start the process.  It will either succeed and return a result containing
2938            // the PID of the new process, or else throw a RuntimeException.
2939            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2940                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2941                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2942
2943            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2944            synchronized (bs) {
2945                if (bs.isOnBattery()) {
2946                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2947                }
2948            }
2949
2950            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2951                    UserHandle.getUserId(uid), startResult.pid, uid,
2952                    app.processName, hostingType,
2953                    hostingNameStr != null ? hostingNameStr : "");
2954
2955            if (app.persistent) {
2956                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2957            }
2958
2959            StringBuilder buf = mStringBuilder;
2960            buf.setLength(0);
2961            buf.append("Start proc ");
2962            buf.append(app.processName);
2963            buf.append(" for ");
2964            buf.append(hostingType);
2965            if (hostingNameStr != null) {
2966                buf.append(" ");
2967                buf.append(hostingNameStr);
2968            }
2969            buf.append(": pid=");
2970            buf.append(startResult.pid);
2971            buf.append(" uid=");
2972            buf.append(uid);
2973            buf.append(" gids={");
2974            if (gids != null) {
2975                for (int gi=0; gi<gids.length; gi++) {
2976                    if (gi != 0) buf.append(", ");
2977                    buf.append(gids[gi]);
2978
2979                }
2980            }
2981            buf.append("}");
2982            if (requiredAbi != null) {
2983                buf.append(" abi=");
2984                buf.append(requiredAbi);
2985            }
2986            Slog.i(TAG, buf.toString());
2987            app.setPid(startResult.pid);
2988            app.usingWrapper = startResult.usingWrapper;
2989            app.removed = false;
2990            synchronized (mPidsSelfLocked) {
2991                this.mPidsSelfLocked.put(startResult.pid, app);
2992                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2993                msg.obj = app;
2994                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2995                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2996            }
2997            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2998                    app.processName, app.info.uid);
2999            if (app.isolated) {
3000                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3001            }
3002        } catch (RuntimeException e) {
3003            // XXX do better error recovery.
3004            app.setPid(0);
3005            Slog.e(TAG, "Failure starting process " + app.processName, e);
3006        }
3007    }
3008
3009    void updateUsageStats(ActivityRecord component, boolean resumed) {
3010        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3011        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3012        if (resumed) {
3013            mUsageStatsService.noteResumeComponent(component.realActivity);
3014            synchronized (stats) {
3015                stats.noteActivityResumedLocked(component.app.uid);
3016            }
3017        } else {
3018            mUsageStatsService.notePauseComponent(component.realActivity);
3019            synchronized (stats) {
3020                stats.noteActivityPausedLocked(component.app.uid);
3021            }
3022        }
3023    }
3024
3025    Intent getHomeIntent() {
3026        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3027        intent.setComponent(mTopComponent);
3028        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3029            intent.addCategory(Intent.CATEGORY_HOME);
3030        }
3031        return intent;
3032    }
3033
3034    boolean startHomeActivityLocked(int userId) {
3035        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3036                && mTopAction == null) {
3037            // We are running in factory test mode, but unable to find
3038            // the factory test app, so just sit around displaying the
3039            // error message and don't try to start anything.
3040            return false;
3041        }
3042        Intent intent = getHomeIntent();
3043        ActivityInfo aInfo =
3044            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3045        if (aInfo != null) {
3046            intent.setComponent(new ComponentName(
3047                    aInfo.applicationInfo.packageName, aInfo.name));
3048            // Don't do this if the home app is currently being
3049            // instrumented.
3050            aInfo = new ActivityInfo(aInfo);
3051            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3052            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3053                    aInfo.applicationInfo.uid, true);
3054            if (app == null || app.instrumentationClass == null) {
3055                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3056                mStackSupervisor.startHomeActivity(intent, aInfo);
3057            }
3058        }
3059
3060        return true;
3061    }
3062
3063    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3064        ActivityInfo ai = null;
3065        ComponentName comp = intent.getComponent();
3066        try {
3067            if (comp != null) {
3068                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3069            } else {
3070                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3071                        intent,
3072                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3073                            flags, userId);
3074
3075                if (info != null) {
3076                    ai = info.activityInfo;
3077                }
3078            }
3079        } catch (RemoteException e) {
3080            // ignore
3081        }
3082
3083        return ai;
3084    }
3085
3086    /**
3087     * Starts the "new version setup screen" if appropriate.
3088     */
3089    void startSetupActivityLocked() {
3090        // Only do this once per boot.
3091        if (mCheckedForSetup) {
3092            return;
3093        }
3094
3095        // We will show this screen if the current one is a different
3096        // version than the last one shown, and we are not running in
3097        // low-level factory test mode.
3098        final ContentResolver resolver = mContext.getContentResolver();
3099        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3100                Settings.Global.getInt(resolver,
3101                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3102            mCheckedForSetup = true;
3103
3104            // See if we should be showing the platform update setup UI.
3105            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3106            List<ResolveInfo> ris = mContext.getPackageManager()
3107                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3108
3109            // We don't allow third party apps to replace this.
3110            ResolveInfo ri = null;
3111            for (int i=0; ris != null && i<ris.size(); i++) {
3112                if ((ris.get(i).activityInfo.applicationInfo.flags
3113                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3114                    ri = ris.get(i);
3115                    break;
3116                }
3117            }
3118
3119            if (ri != null) {
3120                String vers = ri.activityInfo.metaData != null
3121                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3122                        : null;
3123                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3124                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3125                            Intent.METADATA_SETUP_VERSION);
3126                }
3127                String lastVers = Settings.Secure.getString(
3128                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3129                if (vers != null && !vers.equals(lastVers)) {
3130                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3131                    intent.setComponent(new ComponentName(
3132                            ri.activityInfo.packageName, ri.activityInfo.name));
3133                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3134                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3135                }
3136            }
3137        }
3138    }
3139
3140    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3141        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3142    }
3143
3144    void enforceNotIsolatedCaller(String caller) {
3145        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3146            throw new SecurityException("Isolated process not allowed to call " + caller);
3147        }
3148    }
3149
3150    @Override
3151    public int getFrontActivityScreenCompatMode() {
3152        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3153        synchronized (this) {
3154            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3155        }
3156    }
3157
3158    @Override
3159    public void setFrontActivityScreenCompatMode(int mode) {
3160        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3161                "setFrontActivityScreenCompatMode");
3162        synchronized (this) {
3163            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3164        }
3165    }
3166
3167    @Override
3168    public int getPackageScreenCompatMode(String packageName) {
3169        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3170        synchronized (this) {
3171            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3172        }
3173    }
3174
3175    @Override
3176    public void setPackageScreenCompatMode(String packageName, int mode) {
3177        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3178                "setPackageScreenCompatMode");
3179        synchronized (this) {
3180            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3181        }
3182    }
3183
3184    @Override
3185    public boolean getPackageAskScreenCompat(String packageName) {
3186        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3187        synchronized (this) {
3188            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3189        }
3190    }
3191
3192    @Override
3193    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3194        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3195                "setPackageAskScreenCompat");
3196        synchronized (this) {
3197            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3198        }
3199    }
3200
3201    private void dispatchProcessesChanged() {
3202        int N;
3203        synchronized (this) {
3204            N = mPendingProcessChanges.size();
3205            if (mActiveProcessChanges.length < N) {
3206                mActiveProcessChanges = new ProcessChangeItem[N];
3207            }
3208            mPendingProcessChanges.toArray(mActiveProcessChanges);
3209            mAvailProcessChanges.addAll(mPendingProcessChanges);
3210            mPendingProcessChanges.clear();
3211            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3212        }
3213
3214        int i = mProcessObservers.beginBroadcast();
3215        while (i > 0) {
3216            i--;
3217            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3218            if (observer != null) {
3219                try {
3220                    for (int j=0; j<N; j++) {
3221                        ProcessChangeItem item = mActiveProcessChanges[j];
3222                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3223                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3224                                    + item.pid + " uid=" + item.uid + ": "
3225                                    + item.foregroundActivities);
3226                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3227                                    item.foregroundActivities);
3228                        }
3229                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3230                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3231                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3232                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3233                        }
3234                    }
3235                } catch (RemoteException e) {
3236                }
3237            }
3238        }
3239        mProcessObservers.finishBroadcast();
3240    }
3241
3242    private void dispatchProcessDied(int pid, int uid) {
3243        int i = mProcessObservers.beginBroadcast();
3244        while (i > 0) {
3245            i--;
3246            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3247            if (observer != null) {
3248                try {
3249                    observer.onProcessDied(pid, uid);
3250                } catch (RemoteException e) {
3251                }
3252            }
3253        }
3254        mProcessObservers.finishBroadcast();
3255    }
3256
3257    final void doPendingActivityLaunchesLocked(boolean doResume) {
3258        final int N = mPendingActivityLaunches.size();
3259        if (N <= 0) {
3260            return;
3261        }
3262        for (int i=0; i<N; i++) {
3263            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3264            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3265                    doResume && i == (N-1), null);
3266        }
3267        mPendingActivityLaunches.clear();
3268    }
3269
3270    @Override
3271    public final int startActivity(IApplicationThread caller, String callingPackage,
3272            Intent intent, String resolvedType, IBinder resultTo,
3273            String resultWho, int requestCode, int startFlags,
3274            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3275        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3276                resultWho, requestCode,
3277                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3278    }
3279
3280    @Override
3281    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3282            Intent intent, String resolvedType, IBinder resultTo,
3283            String resultWho, int requestCode, int startFlags,
3284            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3285        enforceNotIsolatedCaller("startActivity");
3286        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3287                false, true, "startActivity", null);
3288        // TODO: Switch to user app stacks here.
3289        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3290                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3291                null, null, options, userId, null);
3292    }
3293
3294    @Override
3295    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3296            Intent intent, String resolvedType, IBinder resultTo,
3297            String resultWho, int requestCode, int startFlags, String profileFile,
3298            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3299        enforceNotIsolatedCaller("startActivityAndWait");
3300        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3301                false, true, "startActivityAndWait", null);
3302        WaitResult res = new WaitResult();
3303        // TODO: Switch to user app stacks here.
3304        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3305                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3306                res, null, options, UserHandle.getCallingUserId(), null);
3307        return res;
3308    }
3309
3310    @Override
3311    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3312            Intent intent, String resolvedType, IBinder resultTo,
3313            String resultWho, int requestCode, int startFlags, Configuration config,
3314            Bundle options, int userId) {
3315        enforceNotIsolatedCaller("startActivityWithConfig");
3316        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3317                false, true, "startActivityWithConfig", null);
3318        // TODO: Switch to user app stacks here.
3319        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3320                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3321                null, null, null, config, options, userId, null);
3322        return ret;
3323    }
3324
3325    @Override
3326    public int startActivityIntentSender(IApplicationThread caller,
3327            IntentSender intent, Intent fillInIntent, String resolvedType,
3328            IBinder resultTo, String resultWho, int requestCode,
3329            int flagsMask, int flagsValues, Bundle options) {
3330        enforceNotIsolatedCaller("startActivityIntentSender");
3331        // Refuse possible leaked file descriptors
3332        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3333            throw new IllegalArgumentException("File descriptors passed in Intent");
3334        }
3335
3336        IIntentSender sender = intent.getTarget();
3337        if (!(sender instanceof PendingIntentRecord)) {
3338            throw new IllegalArgumentException("Bad PendingIntent object");
3339        }
3340
3341        PendingIntentRecord pir = (PendingIntentRecord)sender;
3342
3343        synchronized (this) {
3344            // If this is coming from the currently resumed activity, it is
3345            // effectively saying that app switches are allowed at this point.
3346            final ActivityStack stack = getFocusedStack();
3347            if (stack.mResumedActivity != null &&
3348                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3349                mAppSwitchesAllowedTime = 0;
3350            }
3351        }
3352        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3353                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3354        return ret;
3355    }
3356
3357    @Override
3358    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3359            Intent intent, String resolvedType, IVoiceInteractionSession session,
3360            IVoiceInteractor interactor, int startFlags, String profileFile,
3361            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3362        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3363                != PackageManager.PERMISSION_GRANTED) {
3364            String msg = "Permission Denial: startVoiceActivity() from pid="
3365                    + Binder.getCallingPid()
3366                    + ", uid=" + Binder.getCallingUid()
3367                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3368            Slog.w(TAG, msg);
3369            throw new SecurityException(msg);
3370        }
3371        if (session == null || interactor == null) {
3372            throw new NullPointerException("null session or interactor");
3373        }
3374        userId = handleIncomingUser(callingPid, callingUid, userId,
3375                false, true, "startVoiceActivity", null);
3376        // TODO: Switch to user app stacks here.
3377        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3378                resolvedType, session, interactor, null, null, 0, startFlags,
3379                profileFile, profileFd, null, null, options, userId, null);
3380    }
3381
3382    @Override
3383    public boolean startNextMatchingActivity(IBinder callingActivity,
3384            Intent intent, Bundle options) {
3385        // Refuse possible leaked file descriptors
3386        if (intent != null && intent.hasFileDescriptors() == true) {
3387            throw new IllegalArgumentException("File descriptors passed in Intent");
3388        }
3389
3390        synchronized (this) {
3391            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3392            if (r == null) {
3393                ActivityOptions.abort(options);
3394                return false;
3395            }
3396            if (r.app == null || r.app.thread == null) {
3397                // The caller is not running...  d'oh!
3398                ActivityOptions.abort(options);
3399                return false;
3400            }
3401            intent = new Intent(intent);
3402            // The caller is not allowed to change the data.
3403            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3404            // And we are resetting to find the next component...
3405            intent.setComponent(null);
3406
3407            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3408
3409            ActivityInfo aInfo = null;
3410            try {
3411                List<ResolveInfo> resolves =
3412                    AppGlobals.getPackageManager().queryIntentActivities(
3413                            intent, r.resolvedType,
3414                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3415                            UserHandle.getCallingUserId());
3416
3417                // Look for the original activity in the list...
3418                final int N = resolves != null ? resolves.size() : 0;
3419                for (int i=0; i<N; i++) {
3420                    ResolveInfo rInfo = resolves.get(i);
3421                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3422                            && rInfo.activityInfo.name.equals(r.info.name)) {
3423                        // We found the current one...  the next matching is
3424                        // after it.
3425                        i++;
3426                        if (i<N) {
3427                            aInfo = resolves.get(i).activityInfo;
3428                        }
3429                        if (debug) {
3430                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3431                                    + "/" + r.info.name);
3432                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3433                                    + "/" + aInfo.name);
3434                        }
3435                        break;
3436                    }
3437                }
3438            } catch (RemoteException e) {
3439            }
3440
3441            if (aInfo == null) {
3442                // Nobody who is next!
3443                ActivityOptions.abort(options);
3444                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3445                return false;
3446            }
3447
3448            intent.setComponent(new ComponentName(
3449                    aInfo.applicationInfo.packageName, aInfo.name));
3450            intent.setFlags(intent.getFlags()&~(
3451                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3452                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3453                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3454                    Intent.FLAG_ACTIVITY_NEW_TASK));
3455
3456            // Okay now we need to start the new activity, replacing the
3457            // currently running activity.  This is a little tricky because
3458            // we want to start the new one as if the current one is finished,
3459            // but not finish the current one first so that there is no flicker.
3460            // And thus...
3461            final boolean wasFinishing = r.finishing;
3462            r.finishing = true;
3463
3464            // Propagate reply information over to the new activity.
3465            final ActivityRecord resultTo = r.resultTo;
3466            final String resultWho = r.resultWho;
3467            final int requestCode = r.requestCode;
3468            r.resultTo = null;
3469            if (resultTo != null) {
3470                resultTo.removeResultsLocked(r, resultWho, requestCode);
3471            }
3472
3473            final long origId = Binder.clearCallingIdentity();
3474            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3475                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3476                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3477                    options, false, null, null);
3478            Binder.restoreCallingIdentity(origId);
3479
3480            r.finishing = wasFinishing;
3481            if (res != ActivityManager.START_SUCCESS) {
3482                return false;
3483            }
3484            return true;
3485        }
3486    }
3487
3488    final int startActivityInPackage(int uid, String callingPackage,
3489            Intent intent, String resolvedType, IBinder resultTo,
3490            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3491                    IActivityContainer container) {
3492
3493        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3494                false, true, "startActivityInPackage", null);
3495
3496        // TODO: Switch to user app stacks here.
3497        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3498                null, null, resultTo, resultWho, requestCode, startFlags,
3499                null, null, null, null, options, userId, container);
3500        return ret;
3501    }
3502
3503    @Override
3504    public final int startActivities(IApplicationThread caller, String callingPackage,
3505            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3506            int userId) {
3507        enforceNotIsolatedCaller("startActivities");
3508        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3509                false, true, "startActivity", null);
3510        // TODO: Switch to user app stacks here.
3511        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3512                resolvedTypes, resultTo, options, userId);
3513        return ret;
3514    }
3515
3516    final int startActivitiesInPackage(int uid, String callingPackage,
3517            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3518            Bundle options, int userId) {
3519
3520        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3521                false, true, "startActivityInPackage", null);
3522        // TODO: Switch to user app stacks here.
3523        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3524                resultTo, options, userId);
3525        return ret;
3526    }
3527
3528    final void addRecentTaskLocked(TaskRecord task) {
3529        int N = mRecentTasks.size();
3530        // Quick case: check if the top-most recent task is the same.
3531        if (N > 0 && mRecentTasks.get(0) == task) {
3532            return;
3533        }
3534        // Another quick case: never add voice sessions.
3535        if (task.voiceSession != null) {
3536            return;
3537        }
3538        // Remove any existing entries that are the same kind of task.
3539        final Intent intent = task.intent;
3540        final boolean document = intent != null && intent.isDocument();
3541        final ComponentName comp = intent.getComponent();
3542
3543        int maxRecents = task.maxRecents - 1;
3544        for (int i=0; i<N; i++) {
3545            TaskRecord tr = mRecentTasks.get(i);
3546            if (task != tr) {
3547                if (task.userId != tr.userId) {
3548                    continue;
3549                }
3550                final Intent trIntent = tr.intent;
3551                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3552                    (intent == null || !intent.filterEquals(trIntent))) {
3553                    continue;
3554                }
3555                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3556                if (document && trIsDocument) {
3557                    // These are the same document activity (not necessarily the same doc).
3558                    if (maxRecents > 0) {
3559                        --maxRecents;
3560                        continue;
3561                    }
3562                    // Hit the maximum number of documents for this task. Fall through
3563                    // and remove this document from recents.
3564                } else if (document || trIsDocument) {
3565                    // Only one of these is a document. Not the droid we're looking for.
3566                    continue;
3567                }
3568            }
3569
3570            // Either task and tr are the same or, their affinities match or their intents match
3571            // and neither of them is a document, or they are documents using the same activity
3572            // and their maxRecents has been reached.
3573            tr.disposeThumbnail();
3574            mRecentTasks.remove(i);
3575            i--;
3576            N--;
3577            if (task.intent == null) {
3578                // If the new recent task we are adding is not fully
3579                // specified, then replace it with the existing recent task.
3580                task = tr;
3581            }
3582            mTaskPersister.notify(tr, false);
3583        }
3584        if (N >= MAX_RECENT_TASKS) {
3585            mRecentTasks.remove(N-1).disposeThumbnail();
3586        }
3587        mRecentTasks.add(0, task);
3588    }
3589
3590    @Override
3591    public void reportActivityFullyDrawn(IBinder token) {
3592        synchronized (this) {
3593            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3594            if (r == null) {
3595                return;
3596            }
3597            r.reportFullyDrawnLocked();
3598        }
3599    }
3600
3601    @Override
3602    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3603        synchronized (this) {
3604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3605            if (r == null) {
3606                return;
3607            }
3608            final long origId = Binder.clearCallingIdentity();
3609            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3610            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3611                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3612            if (config != null) {
3613                r.frozenBeforeDestroy = true;
3614                if (!updateConfigurationLocked(config, r, false, false)) {
3615                    mStackSupervisor.resumeTopActivitiesLocked();
3616                }
3617            }
3618            Binder.restoreCallingIdentity(origId);
3619        }
3620    }
3621
3622    @Override
3623    public int getRequestedOrientation(IBinder token) {
3624        synchronized (this) {
3625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3626            if (r == null) {
3627                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3628            }
3629            return mWindowManager.getAppOrientation(r.appToken);
3630        }
3631    }
3632
3633    /**
3634     * This is the internal entry point for handling Activity.finish().
3635     *
3636     * @param token The Binder token referencing the Activity we want to finish.
3637     * @param resultCode Result code, if any, from this Activity.
3638     * @param resultData Result data (Intent), if any, from this Activity.
3639     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3640     *            the root Activity in the task.
3641     *
3642     * @return Returns true if the activity successfully finished, or false if it is still running.
3643     */
3644    @Override
3645    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3646            boolean finishTask) {
3647        // Refuse possible leaked file descriptors
3648        if (resultData != null && resultData.hasFileDescriptors() == true) {
3649            throw new IllegalArgumentException("File descriptors passed in Intent");
3650        }
3651
3652        synchronized(this) {
3653            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3654            if (r == null) {
3655                return true;
3656            }
3657            // Keep track of the root activity of the task before we finish it
3658            TaskRecord tr = r.task;
3659            ActivityRecord rootR = tr.getRootActivity();
3660            if (mController != null) {
3661                // Find the first activity that is not finishing.
3662                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3663                if (next != null) {
3664                    // ask watcher if this is allowed
3665                    boolean resumeOK = true;
3666                    try {
3667                        resumeOK = mController.activityResuming(next.packageName);
3668                    } catch (RemoteException e) {
3669                        mController = null;
3670                        Watchdog.getInstance().setActivityController(null);
3671                    }
3672
3673                    if (!resumeOK) {
3674                        return false;
3675                    }
3676                }
3677            }
3678            final long origId = Binder.clearCallingIdentity();
3679            try {
3680                boolean res;
3681                if (finishTask && r == rootR) {
3682                    // If requested, remove the task that is associated to this activity only if it
3683                    // was the root activity in the task.  The result code and data is ignored because
3684                    // we don't support returning them across task boundaries.
3685                    res = removeTaskByIdLocked(tr.taskId, 0);
3686                } else {
3687                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3688                            resultData, "app-request", true);
3689                }
3690                return res;
3691            } finally {
3692                Binder.restoreCallingIdentity(origId);
3693            }
3694        }
3695    }
3696
3697    @Override
3698    public final void finishHeavyWeightApp() {
3699        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3700                != PackageManager.PERMISSION_GRANTED) {
3701            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3702                    + Binder.getCallingPid()
3703                    + ", uid=" + Binder.getCallingUid()
3704                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3705            Slog.w(TAG, msg);
3706            throw new SecurityException(msg);
3707        }
3708
3709        synchronized(this) {
3710            if (mHeavyWeightProcess == null) {
3711                return;
3712            }
3713
3714            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3715                    mHeavyWeightProcess.activities);
3716            for (int i=0; i<activities.size(); i++) {
3717                ActivityRecord r = activities.get(i);
3718                if (!r.finishing) {
3719                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3720                            null, "finish-heavy", true);
3721                }
3722            }
3723
3724            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3725                    mHeavyWeightProcess.userId, 0));
3726            mHeavyWeightProcess = null;
3727        }
3728    }
3729
3730    @Override
3731    public void crashApplication(int uid, int initialPid, String packageName,
3732            String message) {
3733        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3734                != PackageManager.PERMISSION_GRANTED) {
3735            String msg = "Permission Denial: crashApplication() from pid="
3736                    + Binder.getCallingPid()
3737                    + ", uid=" + Binder.getCallingUid()
3738                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3739            Slog.w(TAG, msg);
3740            throw new SecurityException(msg);
3741        }
3742
3743        synchronized(this) {
3744            ProcessRecord proc = null;
3745
3746            // Figure out which process to kill.  We don't trust that initialPid
3747            // still has any relation to current pids, so must scan through the
3748            // list.
3749            synchronized (mPidsSelfLocked) {
3750                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3751                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3752                    if (p.uid != uid) {
3753                        continue;
3754                    }
3755                    if (p.pid == initialPid) {
3756                        proc = p;
3757                        break;
3758                    }
3759                    if (p.pkgList.containsKey(packageName)) {
3760                        proc = p;
3761                    }
3762                }
3763            }
3764
3765            if (proc == null) {
3766                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3767                        + " initialPid=" + initialPid
3768                        + " packageName=" + packageName);
3769                return;
3770            }
3771
3772            if (proc.thread != null) {
3773                if (proc.pid == Process.myPid()) {
3774                    Log.w(TAG, "crashApplication: trying to crash self!");
3775                    return;
3776                }
3777                long ident = Binder.clearCallingIdentity();
3778                try {
3779                    proc.thread.scheduleCrash(message);
3780                } catch (RemoteException e) {
3781                }
3782                Binder.restoreCallingIdentity(ident);
3783            }
3784        }
3785    }
3786
3787    @Override
3788    public final void finishSubActivity(IBinder token, String resultWho,
3789            int requestCode) {
3790        synchronized(this) {
3791            final long origId = Binder.clearCallingIdentity();
3792            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3793            if (r != null) {
3794                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3795            }
3796            Binder.restoreCallingIdentity(origId);
3797        }
3798    }
3799
3800    @Override
3801    public boolean finishActivityAffinity(IBinder token) {
3802        synchronized(this) {
3803            final long origId = Binder.clearCallingIdentity();
3804            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3805            boolean res = false;
3806            if (r != null) {
3807                res = r.task.stack.finishActivityAffinityLocked(r);
3808            }
3809            Binder.restoreCallingIdentity(origId);
3810            return res;
3811        }
3812    }
3813
3814    @Override
3815    public boolean willActivityBeVisible(IBinder token) {
3816        synchronized(this) {
3817            ActivityStack stack = ActivityRecord.getStackLocked(token);
3818            if (stack != null) {
3819                return stack.willActivityBeVisibleLocked(token);
3820            }
3821            return false;
3822        }
3823    }
3824
3825    @Override
3826    public void overridePendingTransition(IBinder token, String packageName,
3827            int enterAnim, int exitAnim) {
3828        synchronized(this) {
3829            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3830            if (self == null) {
3831                return;
3832            }
3833
3834            final long origId = Binder.clearCallingIdentity();
3835
3836            if (self.state == ActivityState.RESUMED
3837                    || self.state == ActivityState.PAUSING) {
3838                mWindowManager.overridePendingAppTransition(packageName,
3839                        enterAnim, exitAnim, null);
3840            }
3841
3842            Binder.restoreCallingIdentity(origId);
3843        }
3844    }
3845
3846    /**
3847     * Main function for removing an existing process from the activity manager
3848     * as a result of that process going away.  Clears out all connections
3849     * to the process.
3850     */
3851    private final void handleAppDiedLocked(ProcessRecord app,
3852            boolean restarting, boolean allowRestart) {
3853        int pid = app.pid;
3854        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3855        if (!restarting) {
3856            removeLruProcessLocked(app);
3857            if (pid > 0) {
3858                ProcessList.remove(pid);
3859            }
3860        }
3861
3862        if (mProfileProc == app) {
3863            clearProfilerLocked();
3864        }
3865
3866        // Remove this application's activities from active lists.
3867        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3868
3869        app.activities.clear();
3870
3871        if (app.instrumentationClass != null) {
3872            Slog.w(TAG, "Crash of app " + app.processName
3873                  + " running instrumentation " + app.instrumentationClass);
3874            Bundle info = new Bundle();
3875            info.putString("shortMsg", "Process crashed.");
3876            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3877        }
3878
3879        if (!restarting) {
3880            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3881                // If there was nothing to resume, and we are not already
3882                // restarting this process, but there is a visible activity that
3883                // is hosted by the process...  then make sure all visible
3884                // activities are running, taking care of restarting this
3885                // process.
3886                if (hasVisibleActivities) {
3887                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3888                }
3889            }
3890        }
3891    }
3892
3893    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3894        IBinder threadBinder = thread.asBinder();
3895        // Find the application record.
3896        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3897            ProcessRecord rec = mLruProcesses.get(i);
3898            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3899                return i;
3900            }
3901        }
3902        return -1;
3903    }
3904
3905    final ProcessRecord getRecordForAppLocked(
3906            IApplicationThread thread) {
3907        if (thread == null) {
3908            return null;
3909        }
3910
3911        int appIndex = getLRURecordIndexForAppLocked(thread);
3912        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3913    }
3914
3915    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3916        // If there are no longer any background processes running,
3917        // and the app that died was not running instrumentation,
3918        // then tell everyone we are now low on memory.
3919        boolean haveBg = false;
3920        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3921            ProcessRecord rec = mLruProcesses.get(i);
3922            if (rec.thread != null
3923                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3924                haveBg = true;
3925                break;
3926            }
3927        }
3928
3929        if (!haveBg) {
3930            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3931            if (doReport) {
3932                long now = SystemClock.uptimeMillis();
3933                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3934                    doReport = false;
3935                } else {
3936                    mLastMemUsageReportTime = now;
3937                }
3938            }
3939            final ArrayList<ProcessMemInfo> memInfos
3940                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3941            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3942            long now = SystemClock.uptimeMillis();
3943            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3944                ProcessRecord rec = mLruProcesses.get(i);
3945                if (rec == dyingProc || rec.thread == null) {
3946                    continue;
3947                }
3948                if (doReport) {
3949                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3950                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3951                }
3952                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3953                    // The low memory report is overriding any current
3954                    // state for a GC request.  Make sure to do
3955                    // heavy/important/visible/foreground processes first.
3956                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3957                        rec.lastRequestedGc = 0;
3958                    } else {
3959                        rec.lastRequestedGc = rec.lastLowMemory;
3960                    }
3961                    rec.reportLowMemory = true;
3962                    rec.lastLowMemory = now;
3963                    mProcessesToGc.remove(rec);
3964                    addProcessToGcListLocked(rec);
3965                }
3966            }
3967            if (doReport) {
3968                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3969                mHandler.sendMessage(msg);
3970            }
3971            scheduleAppGcsLocked();
3972        }
3973    }
3974
3975    final void appDiedLocked(ProcessRecord app, int pid,
3976            IApplicationThread thread) {
3977
3978        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3979        synchronized (stats) {
3980            stats.noteProcessDiedLocked(app.info.uid, pid);
3981        }
3982
3983        // Clean up already done if the process has been re-started.
3984        if (app.pid == pid && app.thread != null &&
3985                app.thread.asBinder() == thread.asBinder()) {
3986            boolean doLowMem = app.instrumentationClass == null;
3987            boolean doOomAdj = doLowMem;
3988            if (!app.killedByAm) {
3989                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3990                        + ") has died.");
3991                mAllowLowerMemLevel = true;
3992            } else {
3993                // Note that we always want to do oom adj to update our state with the
3994                // new number of procs.
3995                mAllowLowerMemLevel = false;
3996                doLowMem = false;
3997            }
3998            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3999            if (DEBUG_CLEANUP) Slog.v(
4000                TAG, "Dying app: " + app + ", pid: " + pid
4001                + ", thread: " + thread.asBinder());
4002            handleAppDiedLocked(app, false, true);
4003
4004            if (doOomAdj) {
4005                updateOomAdjLocked();
4006            }
4007            if (doLowMem) {
4008                doLowMemReportIfNeededLocked(app);
4009            }
4010        } else if (app.pid != pid) {
4011            // A new process has already been started.
4012            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4013                    + ") has died and restarted (pid " + app.pid + ").");
4014            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4015        } else if (DEBUG_PROCESSES) {
4016            Slog.d(TAG, "Received spurious death notification for thread "
4017                    + thread.asBinder());
4018        }
4019    }
4020
4021    /**
4022     * If a stack trace dump file is configured, dump process stack traces.
4023     * @param clearTraces causes the dump file to be erased prior to the new
4024     *    traces being written, if true; when false, the new traces will be
4025     *    appended to any existing file content.
4026     * @param firstPids of dalvik VM processes to dump stack traces for first
4027     * @param lastPids of dalvik VM processes to dump stack traces for last
4028     * @param nativeProcs optional list of native process names to dump stack crawls
4029     * @return file containing stack traces, or null if no dump file is configured
4030     */
4031    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4032            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4033        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4034        if (tracesPath == null || tracesPath.length() == 0) {
4035            return null;
4036        }
4037
4038        File tracesFile = new File(tracesPath);
4039        try {
4040            File tracesDir = tracesFile.getParentFile();
4041            if (!tracesDir.exists()) {
4042                tracesFile.mkdirs();
4043                if (!SELinux.restorecon(tracesDir)) {
4044                    return null;
4045                }
4046            }
4047            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4048
4049            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4050            tracesFile.createNewFile();
4051            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4052        } catch (IOException e) {
4053            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4054            return null;
4055        }
4056
4057        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4058        return tracesFile;
4059    }
4060
4061    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4062            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4063        // Use a FileObserver to detect when traces finish writing.
4064        // The order of traces is considered important to maintain for legibility.
4065        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4066            @Override
4067            public synchronized void onEvent(int event, String path) { notify(); }
4068        };
4069
4070        try {
4071            observer.startWatching();
4072
4073            // First collect all of the stacks of the most important pids.
4074            if (firstPids != null) {
4075                try {
4076                    int num = firstPids.size();
4077                    for (int i = 0; i < num; i++) {
4078                        synchronized (observer) {
4079                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4080                            observer.wait(200);  // Wait for write-close, give up after 200msec
4081                        }
4082                    }
4083                } catch (InterruptedException e) {
4084                    Log.wtf(TAG, e);
4085                }
4086            }
4087
4088            // Next collect the stacks of the native pids
4089            if (nativeProcs != null) {
4090                int[] pids = Process.getPidsForCommands(nativeProcs);
4091                if (pids != null) {
4092                    for (int pid : pids) {
4093                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4094                    }
4095                }
4096            }
4097
4098            // Lastly, measure CPU usage.
4099            if (processCpuTracker != null) {
4100                processCpuTracker.init();
4101                System.gc();
4102                processCpuTracker.update();
4103                try {
4104                    synchronized (processCpuTracker) {
4105                        processCpuTracker.wait(500); // measure over 1/2 second.
4106                    }
4107                } catch (InterruptedException e) {
4108                }
4109                processCpuTracker.update();
4110
4111                // We'll take the stack crawls of just the top apps using CPU.
4112                final int N = processCpuTracker.countWorkingStats();
4113                int numProcs = 0;
4114                for (int i=0; i<N && numProcs<5; i++) {
4115                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4116                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4117                        numProcs++;
4118                        try {
4119                            synchronized (observer) {
4120                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4121                                observer.wait(200);  // Wait for write-close, give up after 200msec
4122                            }
4123                        } catch (InterruptedException e) {
4124                            Log.wtf(TAG, e);
4125                        }
4126
4127                    }
4128                }
4129            }
4130        } finally {
4131            observer.stopWatching();
4132        }
4133    }
4134
4135    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4136        if (true || IS_USER_BUILD) {
4137            return;
4138        }
4139        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4140        if (tracesPath == null || tracesPath.length() == 0) {
4141            return;
4142        }
4143
4144        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4145        StrictMode.allowThreadDiskWrites();
4146        try {
4147            final File tracesFile = new File(tracesPath);
4148            final File tracesDir = tracesFile.getParentFile();
4149            final File tracesTmp = new File(tracesDir, "__tmp__");
4150            try {
4151                if (!tracesDir.exists()) {
4152                    tracesFile.mkdirs();
4153                    if (!SELinux.restorecon(tracesDir.getPath())) {
4154                        return;
4155                    }
4156                }
4157                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4158
4159                if (tracesFile.exists()) {
4160                    tracesTmp.delete();
4161                    tracesFile.renameTo(tracesTmp);
4162                }
4163                StringBuilder sb = new StringBuilder();
4164                Time tobj = new Time();
4165                tobj.set(System.currentTimeMillis());
4166                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4167                sb.append(": ");
4168                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4169                sb.append(" since ");
4170                sb.append(msg);
4171                FileOutputStream fos = new FileOutputStream(tracesFile);
4172                fos.write(sb.toString().getBytes());
4173                if (app == null) {
4174                    fos.write("\n*** No application process!".getBytes());
4175                }
4176                fos.close();
4177                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4178            } catch (IOException e) {
4179                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4180                return;
4181            }
4182
4183            if (app != null) {
4184                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4185                firstPids.add(app.pid);
4186                dumpStackTraces(tracesPath, firstPids, null, null, null);
4187            }
4188
4189            File lastTracesFile = null;
4190            File curTracesFile = null;
4191            for (int i=9; i>=0; i--) {
4192                String name = String.format(Locale.US, "slow%02d.txt", i);
4193                curTracesFile = new File(tracesDir, name);
4194                if (curTracesFile.exists()) {
4195                    if (lastTracesFile != null) {
4196                        curTracesFile.renameTo(lastTracesFile);
4197                    } else {
4198                        curTracesFile.delete();
4199                    }
4200                }
4201                lastTracesFile = curTracesFile;
4202            }
4203            tracesFile.renameTo(curTracesFile);
4204            if (tracesTmp.exists()) {
4205                tracesTmp.renameTo(tracesFile);
4206            }
4207        } finally {
4208            StrictMode.setThreadPolicy(oldPolicy);
4209        }
4210    }
4211
4212    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4213            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4214        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4215        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4216
4217        if (mController != null) {
4218            try {
4219                // 0 == continue, -1 = kill process immediately
4220                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4221                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4222            } catch (RemoteException e) {
4223                mController = null;
4224                Watchdog.getInstance().setActivityController(null);
4225            }
4226        }
4227
4228        long anrTime = SystemClock.uptimeMillis();
4229        if (MONITOR_CPU_USAGE) {
4230            updateCpuStatsNow();
4231        }
4232
4233        synchronized (this) {
4234            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4235            if (mShuttingDown) {
4236                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4237                return;
4238            } else if (app.notResponding) {
4239                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4240                return;
4241            } else if (app.crashing) {
4242                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4243                return;
4244            }
4245
4246            // In case we come through here for the same app before completing
4247            // this one, mark as anring now so we will bail out.
4248            app.notResponding = true;
4249
4250            // Log the ANR to the event log.
4251            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4252                    app.processName, app.info.flags, annotation);
4253
4254            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4255            firstPids.add(app.pid);
4256
4257            int parentPid = app.pid;
4258            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4259            if (parentPid != app.pid) firstPids.add(parentPid);
4260
4261            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4262
4263            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4264                ProcessRecord r = mLruProcesses.get(i);
4265                if (r != null && r.thread != null) {
4266                    int pid = r.pid;
4267                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4268                        if (r.persistent) {
4269                            firstPids.add(pid);
4270                        } else {
4271                            lastPids.put(pid, Boolean.TRUE);
4272                        }
4273                    }
4274                }
4275            }
4276        }
4277
4278        // Log the ANR to the main log.
4279        StringBuilder info = new StringBuilder();
4280        info.setLength(0);
4281        info.append("ANR in ").append(app.processName);
4282        if (activity != null && activity.shortComponentName != null) {
4283            info.append(" (").append(activity.shortComponentName).append(")");
4284        }
4285        info.append("\n");
4286        info.append("PID: ").append(app.pid).append("\n");
4287        if (annotation != null) {
4288            info.append("Reason: ").append(annotation).append("\n");
4289        }
4290        if (parent != null && parent != activity) {
4291            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4292        }
4293
4294        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4295
4296        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4297                NATIVE_STACKS_OF_INTEREST);
4298
4299        String cpuInfo = null;
4300        if (MONITOR_CPU_USAGE) {
4301            updateCpuStatsNow();
4302            synchronized (mProcessCpuThread) {
4303                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4304            }
4305            info.append(processCpuTracker.printCurrentLoad());
4306            info.append(cpuInfo);
4307        }
4308
4309        info.append(processCpuTracker.printCurrentState(anrTime));
4310
4311        Slog.e(TAG, info.toString());
4312        if (tracesFile == null) {
4313            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4314            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4315        }
4316
4317        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4318                cpuInfo, tracesFile, null);
4319
4320        if (mController != null) {
4321            try {
4322                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4323                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4324                if (res != 0) {
4325                    if (res < 0 && app.pid != MY_PID) {
4326                        Process.killProcess(app.pid);
4327                    } else {
4328                        synchronized (this) {
4329                            mServices.scheduleServiceTimeoutLocked(app);
4330                        }
4331                    }
4332                    return;
4333                }
4334            } catch (RemoteException e) {
4335                mController = null;
4336                Watchdog.getInstance().setActivityController(null);
4337            }
4338        }
4339
4340        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4341        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4342                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4343
4344        synchronized (this) {
4345            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4346                killUnneededProcessLocked(app, "background ANR");
4347                return;
4348            }
4349
4350            // Set the app's notResponding state, and look up the errorReportReceiver
4351            makeAppNotRespondingLocked(app,
4352                    activity != null ? activity.shortComponentName : null,
4353                    annotation != null ? "ANR " + annotation : "ANR",
4354                    info.toString());
4355
4356            // Bring up the infamous App Not Responding dialog
4357            Message msg = Message.obtain();
4358            HashMap<String, Object> map = new HashMap<String, Object>();
4359            msg.what = SHOW_NOT_RESPONDING_MSG;
4360            msg.obj = map;
4361            msg.arg1 = aboveSystem ? 1 : 0;
4362            map.put("app", app);
4363            if (activity != null) {
4364                map.put("activity", activity);
4365            }
4366
4367            mHandler.sendMessage(msg);
4368        }
4369    }
4370
4371    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4372        if (!mLaunchWarningShown) {
4373            mLaunchWarningShown = true;
4374            mHandler.post(new Runnable() {
4375                @Override
4376                public void run() {
4377                    synchronized (ActivityManagerService.this) {
4378                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4379                        d.show();
4380                        mHandler.postDelayed(new Runnable() {
4381                            @Override
4382                            public void run() {
4383                                synchronized (ActivityManagerService.this) {
4384                                    d.dismiss();
4385                                    mLaunchWarningShown = false;
4386                                }
4387                            }
4388                        }, 4000);
4389                    }
4390                }
4391            });
4392        }
4393    }
4394
4395    @Override
4396    public boolean clearApplicationUserData(final String packageName,
4397            final IPackageDataObserver observer, int userId) {
4398        enforceNotIsolatedCaller("clearApplicationUserData");
4399        int uid = Binder.getCallingUid();
4400        int pid = Binder.getCallingPid();
4401        userId = handleIncomingUser(pid, uid,
4402                userId, false, true, "clearApplicationUserData", null);
4403        long callingId = Binder.clearCallingIdentity();
4404        try {
4405            IPackageManager pm = AppGlobals.getPackageManager();
4406            int pkgUid = -1;
4407            synchronized(this) {
4408                try {
4409                    pkgUid = pm.getPackageUid(packageName, userId);
4410                } catch (RemoteException e) {
4411                }
4412                if (pkgUid == -1) {
4413                    Slog.w(TAG, "Invalid packageName: " + packageName);
4414                    if (observer != null) {
4415                        try {
4416                            observer.onRemoveCompleted(packageName, false);
4417                        } catch (RemoteException e) {
4418                            Slog.i(TAG, "Observer no longer exists.");
4419                        }
4420                    }
4421                    return false;
4422                }
4423                if (uid == pkgUid || checkComponentPermission(
4424                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4425                        pid, uid, -1, true)
4426                        == PackageManager.PERMISSION_GRANTED) {
4427                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4428                } else {
4429                    throw new SecurityException("PID " + pid + " does not have permission "
4430                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4431                                    + " of package " + packageName);
4432                }
4433            }
4434
4435            try {
4436                // Clear application user data
4437                pm.clearApplicationUserData(packageName, observer, userId);
4438
4439                // Remove all permissions granted from/to this package
4440                removeUriPermissionsForPackageLocked(packageName, userId, true);
4441
4442                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4443                        Uri.fromParts("package", packageName, null));
4444                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4445                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4446                        null, null, 0, null, null, null, false, false, userId);
4447            } catch (RemoteException e) {
4448            }
4449        } finally {
4450            Binder.restoreCallingIdentity(callingId);
4451        }
4452        return true;
4453    }
4454
4455    @Override
4456    public void killBackgroundProcesses(final String packageName, int userId) {
4457        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4458                != PackageManager.PERMISSION_GRANTED &&
4459                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4460                        != PackageManager.PERMISSION_GRANTED) {
4461            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4462                    + Binder.getCallingPid()
4463                    + ", uid=" + Binder.getCallingUid()
4464                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4465            Slog.w(TAG, msg);
4466            throw new SecurityException(msg);
4467        }
4468
4469        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4470                userId, true, true, "killBackgroundProcesses", null);
4471        long callingId = Binder.clearCallingIdentity();
4472        try {
4473            IPackageManager pm = AppGlobals.getPackageManager();
4474            synchronized(this) {
4475                int appId = -1;
4476                try {
4477                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4478                } catch (RemoteException e) {
4479                }
4480                if (appId == -1) {
4481                    Slog.w(TAG, "Invalid packageName: " + packageName);
4482                    return;
4483                }
4484                killPackageProcessesLocked(packageName, appId, userId,
4485                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4486            }
4487        } finally {
4488            Binder.restoreCallingIdentity(callingId);
4489        }
4490    }
4491
4492    @Override
4493    public void killAllBackgroundProcesses() {
4494        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4495                != PackageManager.PERMISSION_GRANTED) {
4496            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4497                    + Binder.getCallingPid()
4498                    + ", uid=" + Binder.getCallingUid()
4499                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4500            Slog.w(TAG, msg);
4501            throw new SecurityException(msg);
4502        }
4503
4504        long callingId = Binder.clearCallingIdentity();
4505        try {
4506            synchronized(this) {
4507                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4508                final int NP = mProcessNames.getMap().size();
4509                for (int ip=0; ip<NP; ip++) {
4510                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4511                    final int NA = apps.size();
4512                    for (int ia=0; ia<NA; ia++) {
4513                        ProcessRecord app = apps.valueAt(ia);
4514                        if (app.persistent) {
4515                            // we don't kill persistent processes
4516                            continue;
4517                        }
4518                        if (app.removed) {
4519                            procs.add(app);
4520                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4521                            app.removed = true;
4522                            procs.add(app);
4523                        }
4524                    }
4525                }
4526
4527                int N = procs.size();
4528                for (int i=0; i<N; i++) {
4529                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4530                }
4531                mAllowLowerMemLevel = true;
4532                updateOomAdjLocked();
4533                doLowMemReportIfNeededLocked(null);
4534            }
4535        } finally {
4536            Binder.restoreCallingIdentity(callingId);
4537        }
4538    }
4539
4540    @Override
4541    public void forceStopPackage(final String packageName, int userId) {
4542        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4543                != PackageManager.PERMISSION_GRANTED) {
4544            String msg = "Permission Denial: forceStopPackage() from pid="
4545                    + Binder.getCallingPid()
4546                    + ", uid=" + Binder.getCallingUid()
4547                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4548            Slog.w(TAG, msg);
4549            throw new SecurityException(msg);
4550        }
4551        final int callingPid = Binder.getCallingPid();
4552        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4553                userId, true, true, "forceStopPackage", null);
4554        long callingId = Binder.clearCallingIdentity();
4555        try {
4556            IPackageManager pm = AppGlobals.getPackageManager();
4557            synchronized(this) {
4558                int[] users = userId == UserHandle.USER_ALL
4559                        ? getUsersLocked() : new int[] { userId };
4560                for (int user : users) {
4561                    int pkgUid = -1;
4562                    try {
4563                        pkgUid = pm.getPackageUid(packageName, user);
4564                    } catch (RemoteException e) {
4565                    }
4566                    if (pkgUid == -1) {
4567                        Slog.w(TAG, "Invalid packageName: " + packageName);
4568                        continue;
4569                    }
4570                    try {
4571                        pm.setPackageStoppedState(packageName, true, user);
4572                    } catch (RemoteException e) {
4573                    } catch (IllegalArgumentException e) {
4574                        Slog.w(TAG, "Failed trying to unstop package "
4575                                + packageName + ": " + e);
4576                    }
4577                    if (isUserRunningLocked(user, false)) {
4578                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4579                    }
4580                }
4581            }
4582        } finally {
4583            Binder.restoreCallingIdentity(callingId);
4584        }
4585    }
4586
4587    /*
4588     * The pkg name and app id have to be specified.
4589     */
4590    @Override
4591    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4592        if (pkg == null) {
4593            return;
4594        }
4595        // Make sure the uid is valid.
4596        if (appid < 0) {
4597            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4598            return;
4599        }
4600        int callerUid = Binder.getCallingUid();
4601        // Only the system server can kill an application
4602        if (callerUid == Process.SYSTEM_UID) {
4603            // Post an aysnc message to kill the application
4604            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4605            msg.arg1 = appid;
4606            msg.arg2 = 0;
4607            Bundle bundle = new Bundle();
4608            bundle.putString("pkg", pkg);
4609            bundle.putString("reason", reason);
4610            msg.obj = bundle;
4611            mHandler.sendMessage(msg);
4612        } else {
4613            throw new SecurityException(callerUid + " cannot kill pkg: " +
4614                    pkg);
4615        }
4616    }
4617
4618    @Override
4619    public void closeSystemDialogs(String reason) {
4620        enforceNotIsolatedCaller("closeSystemDialogs");
4621
4622        final int pid = Binder.getCallingPid();
4623        final int uid = Binder.getCallingUid();
4624        final long origId = Binder.clearCallingIdentity();
4625        try {
4626            synchronized (this) {
4627                // Only allow this from foreground processes, so that background
4628                // applications can't abuse it to prevent system UI from being shown.
4629                if (uid >= Process.FIRST_APPLICATION_UID) {
4630                    ProcessRecord proc;
4631                    synchronized (mPidsSelfLocked) {
4632                        proc = mPidsSelfLocked.get(pid);
4633                    }
4634                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4635                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4636                                + " from background process " + proc);
4637                        return;
4638                    }
4639                }
4640                closeSystemDialogsLocked(reason);
4641            }
4642        } finally {
4643            Binder.restoreCallingIdentity(origId);
4644        }
4645    }
4646
4647    void closeSystemDialogsLocked(String reason) {
4648        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4649        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4650                | Intent.FLAG_RECEIVER_FOREGROUND);
4651        if (reason != null) {
4652            intent.putExtra("reason", reason);
4653        }
4654        mWindowManager.closeSystemDialogs(reason);
4655
4656        mStackSupervisor.closeSystemDialogsLocked();
4657
4658        broadcastIntentLocked(null, null, intent, null,
4659                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4660                Process.SYSTEM_UID, UserHandle.USER_ALL);
4661    }
4662
4663    @Override
4664    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4665        enforceNotIsolatedCaller("getProcessMemoryInfo");
4666        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4667        for (int i=pids.length-1; i>=0; i--) {
4668            ProcessRecord proc;
4669            int oomAdj;
4670            synchronized (this) {
4671                synchronized (mPidsSelfLocked) {
4672                    proc = mPidsSelfLocked.get(pids[i]);
4673                    oomAdj = proc != null ? proc.setAdj : 0;
4674                }
4675            }
4676            infos[i] = new Debug.MemoryInfo();
4677            Debug.getMemoryInfo(pids[i], infos[i]);
4678            if (proc != null) {
4679                synchronized (this) {
4680                    if (proc.thread != null && proc.setAdj == oomAdj) {
4681                        // Record this for posterity if the process has been stable.
4682                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4683                                infos[i].getTotalUss(), false, proc.pkgList);
4684                    }
4685                }
4686            }
4687        }
4688        return infos;
4689    }
4690
4691    @Override
4692    public long[] getProcessPss(int[] pids) {
4693        enforceNotIsolatedCaller("getProcessPss");
4694        long[] pss = new long[pids.length];
4695        for (int i=pids.length-1; i>=0; i--) {
4696            ProcessRecord proc;
4697            int oomAdj;
4698            synchronized (this) {
4699                synchronized (mPidsSelfLocked) {
4700                    proc = mPidsSelfLocked.get(pids[i]);
4701                    oomAdj = proc != null ? proc.setAdj : 0;
4702                }
4703            }
4704            long[] tmpUss = new long[1];
4705            pss[i] = Debug.getPss(pids[i], tmpUss);
4706            if (proc != null) {
4707                synchronized (this) {
4708                    if (proc.thread != null && proc.setAdj == oomAdj) {
4709                        // Record this for posterity if the process has been stable.
4710                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4711                    }
4712                }
4713            }
4714        }
4715        return pss;
4716    }
4717
4718    @Override
4719    public void killApplicationProcess(String processName, int uid) {
4720        if (processName == null) {
4721            return;
4722        }
4723
4724        int callerUid = Binder.getCallingUid();
4725        // Only the system server can kill an application
4726        if (callerUid == Process.SYSTEM_UID) {
4727            synchronized (this) {
4728                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4729                if (app != null && app.thread != null) {
4730                    try {
4731                        app.thread.scheduleSuicide();
4732                    } catch (RemoteException e) {
4733                        // If the other end already died, then our work here is done.
4734                    }
4735                } else {
4736                    Slog.w(TAG, "Process/uid not found attempting kill of "
4737                            + processName + " / " + uid);
4738                }
4739            }
4740        } else {
4741            throw new SecurityException(callerUid + " cannot kill app process: " +
4742                    processName);
4743        }
4744    }
4745
4746    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4747        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4748                false, true, false, false, UserHandle.getUserId(uid), reason);
4749        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4750                Uri.fromParts("package", packageName, null));
4751        if (!mProcessesReady) {
4752            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4753                    | Intent.FLAG_RECEIVER_FOREGROUND);
4754        }
4755        intent.putExtra(Intent.EXTRA_UID, uid);
4756        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4757        broadcastIntentLocked(null, null, intent,
4758                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4759                false, false,
4760                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4761    }
4762
4763    private void forceStopUserLocked(int userId, String reason) {
4764        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4765        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4766        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4767                | Intent.FLAG_RECEIVER_FOREGROUND);
4768        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4769        broadcastIntentLocked(null, null, intent,
4770                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4771                false, false,
4772                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4773    }
4774
4775    private final boolean killPackageProcessesLocked(String packageName, int appId,
4776            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4777            boolean doit, boolean evenPersistent, String reason) {
4778        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4779
4780        // Remove all processes this package may have touched: all with the
4781        // same UID (except for the system or root user), and all whose name
4782        // matches the package name.
4783        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4784        final int NP = mProcessNames.getMap().size();
4785        for (int ip=0; ip<NP; ip++) {
4786            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4787            final int NA = apps.size();
4788            for (int ia=0; ia<NA; ia++) {
4789                ProcessRecord app = apps.valueAt(ia);
4790                if (app.persistent && !evenPersistent) {
4791                    // we don't kill persistent processes
4792                    continue;
4793                }
4794                if (app.removed) {
4795                    if (doit) {
4796                        procs.add(app);
4797                    }
4798                    continue;
4799                }
4800
4801                // Skip process if it doesn't meet our oom adj requirement.
4802                if (app.setAdj < minOomAdj) {
4803                    continue;
4804                }
4805
4806                // If no package is specified, we call all processes under the
4807                // give user id.
4808                if (packageName == null) {
4809                    if (app.userId != userId) {
4810                        continue;
4811                    }
4812                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4813                        continue;
4814                    }
4815                // Package has been specified, we want to hit all processes
4816                // that match it.  We need to qualify this by the processes
4817                // that are running under the specified app and user ID.
4818                } else {
4819                    if (UserHandle.getAppId(app.uid) != appId) {
4820                        continue;
4821                    }
4822                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4823                        continue;
4824                    }
4825                    if (!app.pkgList.containsKey(packageName)) {
4826                        continue;
4827                    }
4828                }
4829
4830                // Process has passed all conditions, kill it!
4831                if (!doit) {
4832                    return true;
4833                }
4834                app.removed = true;
4835                procs.add(app);
4836            }
4837        }
4838
4839        int N = procs.size();
4840        for (int i=0; i<N; i++) {
4841            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4842        }
4843        updateOomAdjLocked();
4844        return N > 0;
4845    }
4846
4847    private final boolean forceStopPackageLocked(String name, int appId,
4848            boolean callerWillRestart, boolean purgeCache, boolean doit,
4849            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4850        int i;
4851        int N;
4852
4853        if (userId == UserHandle.USER_ALL && name == null) {
4854            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4855        }
4856
4857        if (appId < 0 && name != null) {
4858            try {
4859                appId = UserHandle.getAppId(
4860                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4861            } catch (RemoteException e) {
4862            }
4863        }
4864
4865        if (doit) {
4866            if (name != null) {
4867                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4868                        + " user=" + userId + ": " + reason);
4869            } else {
4870                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4871            }
4872
4873            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4874            for (int ip=pmap.size()-1; ip>=0; ip--) {
4875                SparseArray<Long> ba = pmap.valueAt(ip);
4876                for (i=ba.size()-1; i>=0; i--) {
4877                    boolean remove = false;
4878                    final int entUid = ba.keyAt(i);
4879                    if (name != null) {
4880                        if (userId == UserHandle.USER_ALL) {
4881                            if (UserHandle.getAppId(entUid) == appId) {
4882                                remove = true;
4883                            }
4884                        } else {
4885                            if (entUid == UserHandle.getUid(userId, appId)) {
4886                                remove = true;
4887                            }
4888                        }
4889                    } else if (UserHandle.getUserId(entUid) == userId) {
4890                        remove = true;
4891                    }
4892                    if (remove) {
4893                        ba.removeAt(i);
4894                    }
4895                }
4896                if (ba.size() == 0) {
4897                    pmap.removeAt(ip);
4898                }
4899            }
4900        }
4901
4902        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4903                -100, callerWillRestart, true, doit, evenPersistent,
4904                name == null ? ("stop user " + userId) : ("stop " + name));
4905
4906        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4907            if (!doit) {
4908                return true;
4909            }
4910            didSomething = true;
4911        }
4912
4913        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4914            if (!doit) {
4915                return true;
4916            }
4917            didSomething = true;
4918        }
4919
4920        if (name == null) {
4921            // Remove all sticky broadcasts from this user.
4922            mStickyBroadcasts.remove(userId);
4923        }
4924
4925        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4926        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4927                userId, providers)) {
4928            if (!doit) {
4929                return true;
4930            }
4931            didSomething = true;
4932        }
4933        N = providers.size();
4934        for (i=0; i<N; i++) {
4935            removeDyingProviderLocked(null, providers.get(i), true);
4936        }
4937
4938        // Remove transient permissions granted from/to this package/user
4939        removeUriPermissionsForPackageLocked(name, userId, false);
4940
4941        if (name == null || uninstalling) {
4942            // Remove pending intents.  For now we only do this when force
4943            // stopping users, because we have some problems when doing this
4944            // for packages -- app widgets are not currently cleaned up for
4945            // such packages, so they can be left with bad pending intents.
4946            if (mIntentSenderRecords.size() > 0) {
4947                Iterator<WeakReference<PendingIntentRecord>> it
4948                        = mIntentSenderRecords.values().iterator();
4949                while (it.hasNext()) {
4950                    WeakReference<PendingIntentRecord> wpir = it.next();
4951                    if (wpir == null) {
4952                        it.remove();
4953                        continue;
4954                    }
4955                    PendingIntentRecord pir = wpir.get();
4956                    if (pir == null) {
4957                        it.remove();
4958                        continue;
4959                    }
4960                    if (name == null) {
4961                        // Stopping user, remove all objects for the user.
4962                        if (pir.key.userId != userId) {
4963                            // Not the same user, skip it.
4964                            continue;
4965                        }
4966                    } else {
4967                        if (UserHandle.getAppId(pir.uid) != appId) {
4968                            // Different app id, skip it.
4969                            continue;
4970                        }
4971                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4972                            // Different user, skip it.
4973                            continue;
4974                        }
4975                        if (!pir.key.packageName.equals(name)) {
4976                            // Different package, skip it.
4977                            continue;
4978                        }
4979                    }
4980                    if (!doit) {
4981                        return true;
4982                    }
4983                    didSomething = true;
4984                    it.remove();
4985                    pir.canceled = true;
4986                    if (pir.key.activity != null) {
4987                        pir.key.activity.pendingResults.remove(pir.ref);
4988                    }
4989                }
4990            }
4991        }
4992
4993        if (doit) {
4994            if (purgeCache && name != null) {
4995                AttributeCache ac = AttributeCache.instance();
4996                if (ac != null) {
4997                    ac.removePackage(name);
4998                }
4999            }
5000            if (mBooted) {
5001                mStackSupervisor.resumeTopActivitiesLocked();
5002                mStackSupervisor.scheduleIdleLocked();
5003            }
5004        }
5005
5006        return didSomething;
5007    }
5008
5009    private final boolean removeProcessLocked(ProcessRecord app,
5010            boolean callerWillRestart, boolean allowRestart, String reason) {
5011        final String name = app.processName;
5012        final int uid = app.uid;
5013        if (DEBUG_PROCESSES) Slog.d(
5014            TAG, "Force removing proc " + app.toShortString() + " (" + name
5015            + "/" + uid + ")");
5016
5017        mProcessNames.remove(name, uid);
5018        mIsolatedProcesses.remove(app.uid);
5019        if (mHeavyWeightProcess == app) {
5020            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5021                    mHeavyWeightProcess.userId, 0));
5022            mHeavyWeightProcess = null;
5023        }
5024        boolean needRestart = false;
5025        if (app.pid > 0 && app.pid != MY_PID) {
5026            int pid = app.pid;
5027            synchronized (mPidsSelfLocked) {
5028                mPidsSelfLocked.remove(pid);
5029                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5030            }
5031            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5032                    app.processName, app.info.uid);
5033            if (app.isolated) {
5034                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5035            }
5036            killUnneededProcessLocked(app, reason);
5037            handleAppDiedLocked(app, true, allowRestart);
5038            removeLruProcessLocked(app);
5039
5040            if (app.persistent && !app.isolated) {
5041                if (!callerWillRestart) {
5042                    addAppLocked(app.info, false, null /* ABI override */);
5043                } else {
5044                    needRestart = true;
5045                }
5046            }
5047        } else {
5048            mRemovedProcesses.add(app);
5049        }
5050
5051        return needRestart;
5052    }
5053
5054    private final void processStartTimedOutLocked(ProcessRecord app) {
5055        final int pid = app.pid;
5056        boolean gone = false;
5057        synchronized (mPidsSelfLocked) {
5058            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5059            if (knownApp != null && knownApp.thread == null) {
5060                mPidsSelfLocked.remove(pid);
5061                gone = true;
5062            }
5063        }
5064
5065        if (gone) {
5066            Slog.w(TAG, "Process " + app + " failed to attach");
5067            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5068                    pid, app.uid, app.processName);
5069            mProcessNames.remove(app.processName, app.uid);
5070            mIsolatedProcesses.remove(app.uid);
5071            if (mHeavyWeightProcess == app) {
5072                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5073                        mHeavyWeightProcess.userId, 0));
5074                mHeavyWeightProcess = null;
5075            }
5076            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5077                    app.processName, app.info.uid);
5078            if (app.isolated) {
5079                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5080            }
5081            // Take care of any launching providers waiting for this process.
5082            checkAppInLaunchingProvidersLocked(app, true);
5083            // Take care of any services that are waiting for the process.
5084            mServices.processStartTimedOutLocked(app);
5085            killUnneededProcessLocked(app, "start timeout");
5086            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5087                Slog.w(TAG, "Unattached app died before backup, skipping");
5088                try {
5089                    IBackupManager bm = IBackupManager.Stub.asInterface(
5090                            ServiceManager.getService(Context.BACKUP_SERVICE));
5091                    bm.agentDisconnected(app.info.packageName);
5092                } catch (RemoteException e) {
5093                    // Can't happen; the backup manager is local
5094                }
5095            }
5096            if (isPendingBroadcastProcessLocked(pid)) {
5097                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5098                skipPendingBroadcastLocked(pid);
5099            }
5100        } else {
5101            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5102        }
5103    }
5104
5105    private final boolean attachApplicationLocked(IApplicationThread thread,
5106            int pid) {
5107
5108        // Find the application record that is being attached...  either via
5109        // the pid if we are running in multiple processes, or just pull the
5110        // next app record if we are emulating process with anonymous threads.
5111        ProcessRecord app;
5112        if (pid != MY_PID && pid >= 0) {
5113            synchronized (mPidsSelfLocked) {
5114                app = mPidsSelfLocked.get(pid);
5115            }
5116        } else {
5117            app = null;
5118        }
5119
5120        if (app == null) {
5121            Slog.w(TAG, "No pending application record for pid " + pid
5122                    + " (IApplicationThread " + thread + "); dropping process");
5123            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5124            if (pid > 0 && pid != MY_PID) {
5125                Process.killProcessQuiet(pid);
5126            } else {
5127                try {
5128                    thread.scheduleExit();
5129                } catch (Exception e) {
5130                    // Ignore exceptions.
5131                }
5132            }
5133            return false;
5134        }
5135
5136        // If this application record is still attached to a previous
5137        // process, clean it up now.
5138        if (app.thread != null) {
5139            handleAppDiedLocked(app, true, true);
5140        }
5141
5142        // Tell the process all about itself.
5143
5144        if (localLOGV) Slog.v(
5145                TAG, "Binding process pid " + pid + " to record " + app);
5146
5147        final String processName = app.processName;
5148        try {
5149            AppDeathRecipient adr = new AppDeathRecipient(
5150                    app, pid, thread);
5151            thread.asBinder().linkToDeath(adr, 0);
5152            app.deathRecipient = adr;
5153        } catch (RemoteException e) {
5154            app.resetPackageList(mProcessStats);
5155            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5156            return false;
5157        }
5158
5159        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5160
5161        app.makeActive(thread, mProcessStats);
5162        app.curAdj = app.setAdj = -100;
5163        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5164        app.forcingToForeground = null;
5165        updateProcessForegroundLocked(app, false, false);
5166        app.hasShownUi = false;
5167        app.debugging = false;
5168        app.cached = false;
5169
5170        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5171
5172        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5173        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5174
5175        if (!normalMode) {
5176            Slog.i(TAG, "Launching preboot mode app: " + app);
5177        }
5178
5179        if (localLOGV) Slog.v(
5180            TAG, "New app record " + app
5181            + " thread=" + thread.asBinder() + " pid=" + pid);
5182        try {
5183            int testMode = IApplicationThread.DEBUG_OFF;
5184            if (mDebugApp != null && mDebugApp.equals(processName)) {
5185                testMode = mWaitForDebugger
5186                    ? IApplicationThread.DEBUG_WAIT
5187                    : IApplicationThread.DEBUG_ON;
5188                app.debugging = true;
5189                if (mDebugTransient) {
5190                    mDebugApp = mOrigDebugApp;
5191                    mWaitForDebugger = mOrigWaitForDebugger;
5192                }
5193            }
5194            String profileFile = app.instrumentationProfileFile;
5195            ParcelFileDescriptor profileFd = null;
5196            boolean profileAutoStop = false;
5197            if (mProfileApp != null && mProfileApp.equals(processName)) {
5198                mProfileProc = app;
5199                profileFile = mProfileFile;
5200                profileFd = mProfileFd;
5201                profileAutoStop = mAutoStopProfiler;
5202            }
5203            boolean enableOpenGlTrace = false;
5204            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5205                enableOpenGlTrace = true;
5206                mOpenGlTraceApp = null;
5207            }
5208
5209            // If the app is being launched for restore or full backup, set it up specially
5210            boolean isRestrictedBackupMode = false;
5211            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5212                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5213                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5214                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5215            }
5216
5217            ensurePackageDexOpt(app.instrumentationInfo != null
5218                    ? app.instrumentationInfo.packageName
5219                    : app.info.packageName);
5220            if (app.instrumentationClass != null) {
5221                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5222            }
5223            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5224                    + processName + " with config " + mConfiguration);
5225            ApplicationInfo appInfo = app.instrumentationInfo != null
5226                    ? app.instrumentationInfo : app.info;
5227            app.compat = compatibilityInfoForPackageLocked(appInfo);
5228            if (profileFd != null) {
5229                profileFd = profileFd.dup();
5230            }
5231            thread.bindApplication(processName, appInfo, providers,
5232                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5233                    app.instrumentationArguments, app.instrumentationWatcher,
5234                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5235                    isRestrictedBackupMode || !normalMode, app.persistent,
5236                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5237                    mCoreSettingsObserver.getCoreSettingsLocked());
5238            updateLruProcessLocked(app, false, null);
5239            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5240        } catch (Exception e) {
5241            // todo: Yikes!  What should we do?  For now we will try to
5242            // start another process, but that could easily get us in
5243            // an infinite loop of restarting processes...
5244            Slog.w(TAG, "Exception thrown during bind!", e);
5245
5246            app.resetPackageList(mProcessStats);
5247            app.unlinkDeathRecipient();
5248            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5249            return false;
5250        }
5251
5252        // Remove this record from the list of starting applications.
5253        mPersistentStartingProcesses.remove(app);
5254        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5255                "Attach application locked removing on hold: " + app);
5256        mProcessesOnHold.remove(app);
5257
5258        boolean badApp = false;
5259        boolean didSomething = false;
5260
5261        // See if the top visible activity is waiting to run in this process...
5262        if (normalMode) {
5263            try {
5264                if (mStackSupervisor.attachApplicationLocked(app)) {
5265                    didSomething = true;
5266                }
5267            } catch (Exception e) {
5268                badApp = true;
5269            }
5270        }
5271
5272        // Find any services that should be running in this process...
5273        if (!badApp) {
5274            try {
5275                didSomething |= mServices.attachApplicationLocked(app, processName);
5276            } catch (Exception e) {
5277                badApp = true;
5278            }
5279        }
5280
5281        // Check if a next-broadcast receiver is in this process...
5282        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5283            try {
5284                didSomething |= sendPendingBroadcastsLocked(app);
5285            } catch (Exception e) {
5286                // If the app died trying to launch the receiver we declare it 'bad'
5287                badApp = true;
5288            }
5289        }
5290
5291        // Check whether the next backup agent is in this process...
5292        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5293            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5294            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5295            try {
5296                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5297                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5298                        mBackupTarget.backupMode);
5299            } catch (Exception e) {
5300                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5301                e.printStackTrace();
5302            }
5303        }
5304
5305        if (badApp) {
5306            // todo: Also need to kill application to deal with all
5307            // kinds of exceptions.
5308            handleAppDiedLocked(app, false, true);
5309            return false;
5310        }
5311
5312        if (!didSomething) {
5313            updateOomAdjLocked();
5314        }
5315
5316        return true;
5317    }
5318
5319    @Override
5320    public final void attachApplication(IApplicationThread thread) {
5321        synchronized (this) {
5322            int callingPid = Binder.getCallingPid();
5323            final long origId = Binder.clearCallingIdentity();
5324            attachApplicationLocked(thread, callingPid);
5325            Binder.restoreCallingIdentity(origId);
5326        }
5327    }
5328
5329    @Override
5330    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5331        final long origId = Binder.clearCallingIdentity();
5332        synchronized (this) {
5333            ActivityStack stack = ActivityRecord.getStackLocked(token);
5334            if (stack != null) {
5335                ActivityRecord r =
5336                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5337                if (stopProfiling) {
5338                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5339                        try {
5340                            mProfileFd.close();
5341                        } catch (IOException e) {
5342                        }
5343                        clearProfilerLocked();
5344                    }
5345                }
5346            }
5347        }
5348        Binder.restoreCallingIdentity(origId);
5349    }
5350
5351    void enableScreenAfterBoot() {
5352        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5353                SystemClock.uptimeMillis());
5354        mWindowManager.enableScreenAfterBoot();
5355
5356        synchronized (this) {
5357            updateEventDispatchingLocked();
5358        }
5359    }
5360
5361    @Override
5362    public void showBootMessage(final CharSequence msg, final boolean always) {
5363        enforceNotIsolatedCaller("showBootMessage");
5364        mWindowManager.showBootMessage(msg, always);
5365    }
5366
5367    @Override
5368    public void dismissKeyguardOnNextActivity() {
5369        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5370        final long token = Binder.clearCallingIdentity();
5371        try {
5372            synchronized (this) {
5373                if (DEBUG_LOCKSCREEN) logLockScreen("");
5374                if (mLockScreenShown) {
5375                    mLockScreenShown = false;
5376                    comeOutOfSleepIfNeededLocked();
5377                }
5378                mStackSupervisor.setDismissKeyguard(true);
5379            }
5380        } finally {
5381            Binder.restoreCallingIdentity(token);
5382        }
5383    }
5384
5385    final void finishBooting() {
5386        // Register receivers to handle package update events
5387        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5388
5389        synchronized (this) {
5390            // Ensure that any processes we had put on hold are now started
5391            // up.
5392            final int NP = mProcessesOnHold.size();
5393            if (NP > 0) {
5394                ArrayList<ProcessRecord> procs =
5395                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5396                for (int ip=0; ip<NP; ip++) {
5397                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5398                            + procs.get(ip));
5399                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5400                }
5401            }
5402
5403            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5404                // Start looking for apps that are abusing wake locks.
5405                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5406                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5407                // Tell anyone interested that we are done booting!
5408                SystemProperties.set("sys.boot_completed", "1");
5409                SystemProperties.set("dev.bootcomplete", "1");
5410                for (int i=0; i<mStartedUsers.size(); i++) {
5411                    UserStartedState uss = mStartedUsers.valueAt(i);
5412                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5413                        uss.mState = UserStartedState.STATE_RUNNING;
5414                        final int userId = mStartedUsers.keyAt(i);
5415                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5416                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5417                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5418                        broadcastIntentLocked(null, null, intent, null,
5419                                new IIntentReceiver.Stub() {
5420                                    @Override
5421                                    public void performReceive(Intent intent, int resultCode,
5422                                            String data, Bundle extras, boolean ordered,
5423                                            boolean sticky, int sendingUser) {
5424                                        synchronized (ActivityManagerService.this) {
5425                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5426                                                    true, false);
5427                                        }
5428                                    }
5429                                },
5430                                0, null, null,
5431                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5432                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5433                                userId);
5434                    }
5435                }
5436                scheduleStartProfilesLocked();
5437            }
5438        }
5439    }
5440
5441    final void ensureBootCompleted() {
5442        boolean booting;
5443        boolean enableScreen;
5444        synchronized (this) {
5445            booting = mBooting;
5446            mBooting = false;
5447            enableScreen = !mBooted;
5448            mBooted = true;
5449        }
5450
5451        if (booting) {
5452            finishBooting();
5453        }
5454
5455        if (enableScreen) {
5456            enableScreenAfterBoot();
5457        }
5458    }
5459
5460    @Override
5461    public final void activityResumed(IBinder token) {
5462        final long origId = Binder.clearCallingIdentity();
5463        synchronized(this) {
5464            ActivityStack stack = ActivityRecord.getStackLocked(token);
5465            if (stack != null) {
5466                ActivityRecord.activityResumedLocked(token);
5467            }
5468        }
5469        Binder.restoreCallingIdentity(origId);
5470    }
5471
5472    @Override
5473    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5474        final long origId = Binder.clearCallingIdentity();
5475        synchronized(this) {
5476            ActivityStack stack = ActivityRecord.getStackLocked(token);
5477            if (stack != null) {
5478                stack.activityPausedLocked(token, false, persistentState);
5479            }
5480        }
5481        Binder.restoreCallingIdentity(origId);
5482    }
5483
5484    @Override
5485    public final void activityStopped(IBinder token, Bundle icicle,
5486            PersistableBundle persistentState, CharSequence description) {
5487        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5488
5489        // Refuse possible leaked file descriptors
5490        if (icicle != null && icicle.hasFileDescriptors()) {
5491            throw new IllegalArgumentException("File descriptors passed in Bundle");
5492        }
5493
5494        final long origId = Binder.clearCallingIdentity();
5495
5496        synchronized (this) {
5497            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5498            if (r != null) {
5499                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5500            }
5501        }
5502
5503        trimApplications();
5504
5505        Binder.restoreCallingIdentity(origId);
5506    }
5507
5508    @Override
5509    public final void activityDestroyed(IBinder token) {
5510        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5511        synchronized (this) {
5512            ActivityStack stack = ActivityRecord.getStackLocked(token);
5513            if (stack != null) {
5514                stack.activityDestroyedLocked(token);
5515            }
5516        }
5517    }
5518
5519    @Override
5520    public String getCallingPackage(IBinder token) {
5521        synchronized (this) {
5522            ActivityRecord r = getCallingRecordLocked(token);
5523            return r != null ? r.info.packageName : null;
5524        }
5525    }
5526
5527    @Override
5528    public ComponentName getCallingActivity(IBinder token) {
5529        synchronized (this) {
5530            ActivityRecord r = getCallingRecordLocked(token);
5531            return r != null ? r.intent.getComponent() : null;
5532        }
5533    }
5534
5535    private ActivityRecord getCallingRecordLocked(IBinder token) {
5536        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5537        if (r == null) {
5538            return null;
5539        }
5540        return r.resultTo;
5541    }
5542
5543    @Override
5544    public ComponentName getActivityClassForToken(IBinder token) {
5545        synchronized(this) {
5546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5547            if (r == null) {
5548                return null;
5549            }
5550            return r.intent.getComponent();
5551        }
5552    }
5553
5554    @Override
5555    public String getPackageForToken(IBinder token) {
5556        synchronized(this) {
5557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5558            if (r == null) {
5559                return null;
5560            }
5561            return r.packageName;
5562        }
5563    }
5564
5565    @Override
5566    public IIntentSender getIntentSender(int type,
5567            String packageName, IBinder token, String resultWho,
5568            int requestCode, Intent[] intents, String[] resolvedTypes,
5569            int flags, Bundle options, int userId) {
5570        enforceNotIsolatedCaller("getIntentSender");
5571        // Refuse possible leaked file descriptors
5572        if (intents != null) {
5573            if (intents.length < 1) {
5574                throw new IllegalArgumentException("Intents array length must be >= 1");
5575            }
5576            for (int i=0; i<intents.length; i++) {
5577                Intent intent = intents[i];
5578                if (intent != null) {
5579                    if (intent.hasFileDescriptors()) {
5580                        throw new IllegalArgumentException("File descriptors passed in Intent");
5581                    }
5582                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5583                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5584                        throw new IllegalArgumentException(
5585                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5586                    }
5587                    intents[i] = new Intent(intent);
5588                }
5589            }
5590            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5591                throw new IllegalArgumentException(
5592                        "Intent array length does not match resolvedTypes length");
5593            }
5594        }
5595        if (options != null) {
5596            if (options.hasFileDescriptors()) {
5597                throw new IllegalArgumentException("File descriptors passed in options");
5598            }
5599        }
5600
5601        synchronized(this) {
5602            int callingUid = Binder.getCallingUid();
5603            int origUserId = userId;
5604            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5605                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5606                    "getIntentSender", null);
5607            if (origUserId == UserHandle.USER_CURRENT) {
5608                // We don't want to evaluate this until the pending intent is
5609                // actually executed.  However, we do want to always do the
5610                // security checking for it above.
5611                userId = UserHandle.USER_CURRENT;
5612            }
5613            try {
5614                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5615                    int uid = AppGlobals.getPackageManager()
5616                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5617                    if (!UserHandle.isSameApp(callingUid, uid)) {
5618                        String msg = "Permission Denial: getIntentSender() from pid="
5619                            + Binder.getCallingPid()
5620                            + ", uid=" + Binder.getCallingUid()
5621                            + ", (need uid=" + uid + ")"
5622                            + " is not allowed to send as package " + packageName;
5623                        Slog.w(TAG, msg);
5624                        throw new SecurityException(msg);
5625                    }
5626                }
5627
5628                return getIntentSenderLocked(type, packageName, callingUid, userId,
5629                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5630
5631            } catch (RemoteException e) {
5632                throw new SecurityException(e);
5633            }
5634        }
5635    }
5636
5637    IIntentSender getIntentSenderLocked(int type, String packageName,
5638            int callingUid, int userId, IBinder token, String resultWho,
5639            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5640            Bundle options) {
5641        if (DEBUG_MU)
5642            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5643        ActivityRecord activity = null;
5644        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5645            activity = ActivityRecord.isInStackLocked(token);
5646            if (activity == null) {
5647                return null;
5648            }
5649            if (activity.finishing) {
5650                return null;
5651            }
5652        }
5653
5654        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5655        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5656        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5657        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5658                |PendingIntent.FLAG_UPDATE_CURRENT);
5659
5660        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5661                type, packageName, activity, resultWho,
5662                requestCode, intents, resolvedTypes, flags, options, userId);
5663        WeakReference<PendingIntentRecord> ref;
5664        ref = mIntentSenderRecords.get(key);
5665        PendingIntentRecord rec = ref != null ? ref.get() : null;
5666        if (rec != null) {
5667            if (!cancelCurrent) {
5668                if (updateCurrent) {
5669                    if (rec.key.requestIntent != null) {
5670                        rec.key.requestIntent.replaceExtras(intents != null ?
5671                                intents[intents.length - 1] : null);
5672                    }
5673                    if (intents != null) {
5674                        intents[intents.length-1] = rec.key.requestIntent;
5675                        rec.key.allIntents = intents;
5676                        rec.key.allResolvedTypes = resolvedTypes;
5677                    } else {
5678                        rec.key.allIntents = null;
5679                        rec.key.allResolvedTypes = null;
5680                    }
5681                }
5682                return rec;
5683            }
5684            rec.canceled = true;
5685            mIntentSenderRecords.remove(key);
5686        }
5687        if (noCreate) {
5688            return rec;
5689        }
5690        rec = new PendingIntentRecord(this, key, callingUid);
5691        mIntentSenderRecords.put(key, rec.ref);
5692        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5693            if (activity.pendingResults == null) {
5694                activity.pendingResults
5695                        = new HashSet<WeakReference<PendingIntentRecord>>();
5696            }
5697            activity.pendingResults.add(rec.ref);
5698        }
5699        return rec;
5700    }
5701
5702    @Override
5703    public void cancelIntentSender(IIntentSender sender) {
5704        if (!(sender instanceof PendingIntentRecord)) {
5705            return;
5706        }
5707        synchronized(this) {
5708            PendingIntentRecord rec = (PendingIntentRecord)sender;
5709            try {
5710                int uid = AppGlobals.getPackageManager()
5711                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5712                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5713                    String msg = "Permission Denial: cancelIntentSender() from pid="
5714                        + Binder.getCallingPid()
5715                        + ", uid=" + Binder.getCallingUid()
5716                        + " is not allowed to cancel packges "
5717                        + rec.key.packageName;
5718                    Slog.w(TAG, msg);
5719                    throw new SecurityException(msg);
5720                }
5721            } catch (RemoteException e) {
5722                throw new SecurityException(e);
5723            }
5724            cancelIntentSenderLocked(rec, true);
5725        }
5726    }
5727
5728    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5729        rec.canceled = true;
5730        mIntentSenderRecords.remove(rec.key);
5731        if (cleanActivity && rec.key.activity != null) {
5732            rec.key.activity.pendingResults.remove(rec.ref);
5733        }
5734    }
5735
5736    @Override
5737    public String getPackageForIntentSender(IIntentSender pendingResult) {
5738        if (!(pendingResult instanceof PendingIntentRecord)) {
5739            return null;
5740        }
5741        try {
5742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5743            return res.key.packageName;
5744        } catch (ClassCastException e) {
5745        }
5746        return null;
5747    }
5748
5749    @Override
5750    public int getUidForIntentSender(IIntentSender sender) {
5751        if (sender instanceof PendingIntentRecord) {
5752            try {
5753                PendingIntentRecord res = (PendingIntentRecord)sender;
5754                return res.uid;
5755            } catch (ClassCastException e) {
5756            }
5757        }
5758        return -1;
5759    }
5760
5761    @Override
5762    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5763        if (!(pendingResult instanceof PendingIntentRecord)) {
5764            return false;
5765        }
5766        try {
5767            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5768            if (res.key.allIntents == null) {
5769                return false;
5770            }
5771            for (int i=0; i<res.key.allIntents.length; i++) {
5772                Intent intent = res.key.allIntents[i];
5773                if (intent.getPackage() != null && intent.getComponent() != null) {
5774                    return false;
5775                }
5776            }
5777            return true;
5778        } catch (ClassCastException e) {
5779        }
5780        return false;
5781    }
5782
5783    @Override
5784    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5785        if (!(pendingResult instanceof PendingIntentRecord)) {
5786            return false;
5787        }
5788        try {
5789            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5790            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5791                return true;
5792            }
5793            return false;
5794        } catch (ClassCastException e) {
5795        }
5796        return false;
5797    }
5798
5799    @Override
5800    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5801        if (!(pendingResult instanceof PendingIntentRecord)) {
5802            return null;
5803        }
5804        try {
5805            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5806            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5807        } catch (ClassCastException e) {
5808        }
5809        return null;
5810    }
5811
5812    @Override
5813    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5814        if (!(pendingResult instanceof PendingIntentRecord)) {
5815            return null;
5816        }
5817        try {
5818            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5819            Intent intent = res.key.requestIntent;
5820            if (intent != null) {
5821                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5822                        || res.lastTagPrefix.equals(prefix))) {
5823                    return res.lastTag;
5824                }
5825                res.lastTagPrefix = prefix;
5826                StringBuilder sb = new StringBuilder(128);
5827                if (prefix != null) {
5828                    sb.append(prefix);
5829                }
5830                if (intent.getAction() != null) {
5831                    sb.append(intent.getAction());
5832                } else if (intent.getComponent() != null) {
5833                    intent.getComponent().appendShortString(sb);
5834                } else {
5835                    sb.append("?");
5836                }
5837                return res.lastTag = sb.toString();
5838            }
5839        } catch (ClassCastException e) {
5840        }
5841        return null;
5842    }
5843
5844    @Override
5845    public void setProcessLimit(int max) {
5846        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5847                "setProcessLimit()");
5848        synchronized (this) {
5849            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5850            mProcessLimitOverride = max;
5851        }
5852        trimApplications();
5853    }
5854
5855    @Override
5856    public int getProcessLimit() {
5857        synchronized (this) {
5858            return mProcessLimitOverride;
5859        }
5860    }
5861
5862    void foregroundTokenDied(ForegroundToken token) {
5863        synchronized (ActivityManagerService.this) {
5864            synchronized (mPidsSelfLocked) {
5865                ForegroundToken cur
5866                    = mForegroundProcesses.get(token.pid);
5867                if (cur != token) {
5868                    return;
5869                }
5870                mForegroundProcesses.remove(token.pid);
5871                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5872                if (pr == null) {
5873                    return;
5874                }
5875                pr.forcingToForeground = null;
5876                updateProcessForegroundLocked(pr, false, false);
5877            }
5878            updateOomAdjLocked();
5879        }
5880    }
5881
5882    @Override
5883    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5884        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5885                "setProcessForeground()");
5886        synchronized(this) {
5887            boolean changed = false;
5888
5889            synchronized (mPidsSelfLocked) {
5890                ProcessRecord pr = mPidsSelfLocked.get(pid);
5891                if (pr == null && isForeground) {
5892                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5893                    return;
5894                }
5895                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5896                if (oldToken != null) {
5897                    oldToken.token.unlinkToDeath(oldToken, 0);
5898                    mForegroundProcesses.remove(pid);
5899                    if (pr != null) {
5900                        pr.forcingToForeground = null;
5901                    }
5902                    changed = true;
5903                }
5904                if (isForeground && token != null) {
5905                    ForegroundToken newToken = new ForegroundToken() {
5906                        @Override
5907                        public void binderDied() {
5908                            foregroundTokenDied(this);
5909                        }
5910                    };
5911                    newToken.pid = pid;
5912                    newToken.token = token;
5913                    try {
5914                        token.linkToDeath(newToken, 0);
5915                        mForegroundProcesses.put(pid, newToken);
5916                        pr.forcingToForeground = token;
5917                        changed = true;
5918                    } catch (RemoteException e) {
5919                        // If the process died while doing this, we will later
5920                        // do the cleanup with the process death link.
5921                    }
5922                }
5923            }
5924
5925            if (changed) {
5926                updateOomAdjLocked();
5927            }
5928        }
5929    }
5930
5931    // =========================================================
5932    // PERMISSIONS
5933    // =========================================================
5934
5935    static class PermissionController extends IPermissionController.Stub {
5936        ActivityManagerService mActivityManagerService;
5937        PermissionController(ActivityManagerService activityManagerService) {
5938            mActivityManagerService = activityManagerService;
5939        }
5940
5941        @Override
5942        public boolean checkPermission(String permission, int pid, int uid) {
5943            return mActivityManagerService.checkPermission(permission, pid,
5944                    uid) == PackageManager.PERMISSION_GRANTED;
5945        }
5946    }
5947
5948    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5949        @Override
5950        public int checkComponentPermission(String permission, int pid, int uid,
5951                int owningUid, boolean exported) {
5952            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5953                    owningUid, exported);
5954        }
5955
5956        @Override
5957        public Object getAMSLock() {
5958            return ActivityManagerService.this;
5959        }
5960    }
5961
5962    /**
5963     * This can be called with or without the global lock held.
5964     */
5965    int checkComponentPermission(String permission, int pid, int uid,
5966            int owningUid, boolean exported) {
5967        // We might be performing an operation on behalf of an indirect binder
5968        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5969        // client identity accordingly before proceeding.
5970        Identity tlsIdentity = sCallerIdentity.get();
5971        if (tlsIdentity != null) {
5972            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5973                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5974            uid = tlsIdentity.uid;
5975            pid = tlsIdentity.pid;
5976        }
5977
5978        if (pid == MY_PID) {
5979            return PackageManager.PERMISSION_GRANTED;
5980        }
5981
5982        return ActivityManager.checkComponentPermission(permission, uid,
5983                owningUid, exported);
5984    }
5985
5986    /**
5987     * As the only public entry point for permissions checking, this method
5988     * can enforce the semantic that requesting a check on a null global
5989     * permission is automatically denied.  (Internally a null permission
5990     * string is used when calling {@link #checkComponentPermission} in cases
5991     * when only uid-based security is needed.)
5992     *
5993     * This can be called with or without the global lock held.
5994     */
5995    @Override
5996    public int checkPermission(String permission, int pid, int uid) {
5997        if (permission == null) {
5998            return PackageManager.PERMISSION_DENIED;
5999        }
6000        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6001    }
6002
6003    /**
6004     * Binder IPC calls go through the public entry point.
6005     * This can be called with or without the global lock held.
6006     */
6007    int checkCallingPermission(String permission) {
6008        return checkPermission(permission,
6009                Binder.getCallingPid(),
6010                UserHandle.getAppId(Binder.getCallingUid()));
6011    }
6012
6013    /**
6014     * This can be called with or without the global lock held.
6015     */
6016    void enforceCallingPermission(String permission, String func) {
6017        if (checkCallingPermission(permission)
6018                == PackageManager.PERMISSION_GRANTED) {
6019            return;
6020        }
6021
6022        String msg = "Permission Denial: " + func + " from pid="
6023                + Binder.getCallingPid()
6024                + ", uid=" + Binder.getCallingUid()
6025                + " requires " + permission;
6026        Slog.w(TAG, msg);
6027        throw new SecurityException(msg);
6028    }
6029
6030    /**
6031     * Determine if UID is holding permissions required to access {@link Uri} in
6032     * the given {@link ProviderInfo}. Final permission checking is always done
6033     * in {@link ContentProvider}.
6034     */
6035    private final boolean checkHoldingPermissionsLocked(
6036            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6037        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6038                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6039        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6040            return false;
6041        }
6042
6043        if (pi.applicationInfo.uid == uid) {
6044            return true;
6045        } else if (!pi.exported) {
6046            return false;
6047        }
6048
6049        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6050        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6051        try {
6052            // check if target holds top-level <provider> permissions
6053            if (!readMet && pi.readPermission != null
6054                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6055                readMet = true;
6056            }
6057            if (!writeMet && pi.writePermission != null
6058                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6059                writeMet = true;
6060            }
6061
6062            // track if unprotected read/write is allowed; any denied
6063            // <path-permission> below removes this ability
6064            boolean allowDefaultRead = pi.readPermission == null;
6065            boolean allowDefaultWrite = pi.writePermission == null;
6066
6067            // check if target holds any <path-permission> that match uri
6068            final PathPermission[] pps = pi.pathPermissions;
6069            if (pps != null) {
6070                final String path = grantUri.uri.getPath();
6071                int i = pps.length;
6072                while (i > 0 && (!readMet || !writeMet)) {
6073                    i--;
6074                    PathPermission pp = pps[i];
6075                    if (pp.match(path)) {
6076                        if (!readMet) {
6077                            final String pprperm = pp.getReadPermission();
6078                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6079                                    + pprperm + " for " + pp.getPath()
6080                                    + ": match=" + pp.match(path)
6081                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6082                            if (pprperm != null) {
6083                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6084                                    readMet = true;
6085                                } else {
6086                                    allowDefaultRead = false;
6087                                }
6088                            }
6089                        }
6090                        if (!writeMet) {
6091                            final String ppwperm = pp.getWritePermission();
6092                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6093                                    + ppwperm + " for " + pp.getPath()
6094                                    + ": match=" + pp.match(path)
6095                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6096                            if (ppwperm != null) {
6097                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6098                                    writeMet = true;
6099                                } else {
6100                                    allowDefaultWrite = false;
6101                                }
6102                            }
6103                        }
6104                    }
6105                }
6106            }
6107
6108            // grant unprotected <provider> read/write, if not blocked by
6109            // <path-permission> above
6110            if (allowDefaultRead) readMet = true;
6111            if (allowDefaultWrite) writeMet = true;
6112
6113        } catch (RemoteException e) {
6114            return false;
6115        }
6116
6117        return readMet && writeMet;
6118    }
6119
6120    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6121        ProviderInfo pi = null;
6122        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6123        if (cpr != null) {
6124            pi = cpr.info;
6125        } else {
6126            try {
6127                pi = AppGlobals.getPackageManager().resolveContentProvider(
6128                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6129            } catch (RemoteException ex) {
6130            }
6131        }
6132        return pi;
6133    }
6134
6135    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6136        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6137        if (targetUris != null) {
6138            return targetUris.get(grantUri);
6139        }
6140        return null;
6141    }
6142
6143    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6144            String targetPkg, int targetUid, GrantUri grantUri) {
6145        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6146        if (targetUris == null) {
6147            targetUris = Maps.newArrayMap();
6148            mGrantedUriPermissions.put(targetUid, targetUris);
6149        }
6150
6151        UriPermission perm = targetUris.get(grantUri);
6152        if (perm == null) {
6153            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6154            targetUris.put(grantUri, perm);
6155        }
6156
6157        return perm;
6158    }
6159
6160    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6161            final int modeFlags) {
6162        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6163        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6164                : UriPermission.STRENGTH_OWNED;
6165
6166        // Root gets to do everything.
6167        if (uid == 0) {
6168            return true;
6169        }
6170
6171        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6172        if (perms == null) return false;
6173
6174        // First look for exact match
6175        final UriPermission exactPerm = perms.get(grantUri);
6176        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6177            return true;
6178        }
6179
6180        // No exact match, look for prefixes
6181        final int N = perms.size();
6182        for (int i = 0; i < N; i++) {
6183            final UriPermission perm = perms.valueAt(i);
6184            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6185                    && perm.getStrength(modeFlags) >= minStrength) {
6186                return true;
6187            }
6188        }
6189
6190        return false;
6191    }
6192
6193    @Override
6194    public int checkUriPermission(Uri uri, int pid, int uid,
6195            final int modeFlags, int userId) {
6196        enforceNotIsolatedCaller("checkUriPermission");
6197
6198        // Another redirected-binder-call permissions check as in
6199        // {@link checkComponentPermission}.
6200        Identity tlsIdentity = sCallerIdentity.get();
6201        if (tlsIdentity != null) {
6202            uid = tlsIdentity.uid;
6203            pid = tlsIdentity.pid;
6204        }
6205
6206        // Our own process gets to do everything.
6207        if (pid == MY_PID) {
6208            return PackageManager.PERMISSION_GRANTED;
6209        }
6210        synchronized (this) {
6211            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6212                    ? PackageManager.PERMISSION_GRANTED
6213                    : PackageManager.PERMISSION_DENIED;
6214        }
6215    }
6216
6217    /**
6218     * Check if the targetPkg can be granted permission to access uri by
6219     * the callingUid using the given modeFlags.  Throws a security exception
6220     * if callingUid is not allowed to do this.  Returns the uid of the target
6221     * if the URI permission grant should be performed; returns -1 if it is not
6222     * needed (for example targetPkg already has permission to access the URI).
6223     * If you already know the uid of the target, you can supply it in
6224     * lastTargetUid else set that to -1.
6225     */
6226    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6227            final int modeFlags, int lastTargetUid) {
6228        if (!Intent.isAccessUriMode(modeFlags)) {
6229            return -1;
6230        }
6231
6232        if (targetPkg != null) {
6233            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6234                    "Checking grant " + targetPkg + " permission to " + grantUri);
6235        }
6236
6237        final IPackageManager pm = AppGlobals.getPackageManager();
6238
6239        // If this is not a content: uri, we can't do anything with it.
6240        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6241            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6242                    "Can't grant URI permission for non-content URI: " + grantUri);
6243            return -1;
6244        }
6245
6246        final String authority = grantUri.uri.getAuthority();
6247        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6248        if (pi == null) {
6249            Slog.w(TAG, "No content provider found for permission check: " +
6250                    grantUri.uri.toSafeString());
6251            return -1;
6252        }
6253
6254        int targetUid = lastTargetUid;
6255        if (targetUid < 0 && targetPkg != null) {
6256            try {
6257                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6258                if (targetUid < 0) {
6259                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6260                            "Can't grant URI permission no uid for: " + targetPkg);
6261                    return -1;
6262                }
6263            } catch (RemoteException ex) {
6264                return -1;
6265            }
6266        }
6267
6268        if (targetUid >= 0) {
6269            // First...  does the target actually need this permission?
6270            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6271                // No need to grant the target this permission.
6272                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6273                        "Target " + targetPkg + " already has full permission to " + grantUri);
6274                return -1;
6275            }
6276        } else {
6277            // First...  there is no target package, so can anyone access it?
6278            boolean allowed = pi.exported;
6279            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6280                if (pi.readPermission != null) {
6281                    allowed = false;
6282                }
6283            }
6284            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6285                if (pi.writePermission != null) {
6286                    allowed = false;
6287                }
6288            }
6289            if (allowed) {
6290                return -1;
6291            }
6292        }
6293
6294        // Second...  is the provider allowing granting of URI permissions?
6295        if (!pi.grantUriPermissions) {
6296            throw new SecurityException("Provider " + pi.packageName
6297                    + "/" + pi.name
6298                    + " does not allow granting of Uri permissions (uri "
6299                    + grantUri + ")");
6300        }
6301        if (pi.uriPermissionPatterns != null) {
6302            final int N = pi.uriPermissionPatterns.length;
6303            boolean allowed = false;
6304            for (int i=0; i<N; i++) {
6305                if (pi.uriPermissionPatterns[i] != null
6306                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6307                    allowed = true;
6308                    break;
6309                }
6310            }
6311            if (!allowed) {
6312                throw new SecurityException("Provider " + pi.packageName
6313                        + "/" + pi.name
6314                        + " does not allow granting of permission to path of Uri "
6315                        + grantUri);
6316            }
6317        }
6318
6319        // Third...  does the caller itself have permission to access
6320        // this uri?
6321        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6322            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6323                // Require they hold a strong enough Uri permission
6324                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6325                    throw new SecurityException("Uid " + callingUid
6326                            + " does not have permission to uri " + grantUri);
6327                }
6328            }
6329        }
6330        return targetUid;
6331    }
6332
6333    @Override
6334    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6335            final int modeFlags, int userId) {
6336        enforceNotIsolatedCaller("checkGrantUriPermission");
6337        synchronized(this) {
6338            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6339                    new GrantUri(userId, uri, false), modeFlags, -1);
6340        }
6341    }
6342
6343    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6344            final int modeFlags, UriPermissionOwner owner) {
6345        if (!Intent.isAccessUriMode(modeFlags)) {
6346            return;
6347        }
6348
6349        // So here we are: the caller has the assumed permission
6350        // to the uri, and the target doesn't.  Let's now give this to
6351        // the target.
6352
6353        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6354                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6355
6356        final String authority = grantUri.uri.getAuthority();
6357        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6358        if (pi == null) {
6359            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6360            return;
6361        }
6362
6363        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6364            grantUri.prefix = true;
6365        }
6366        final UriPermission perm = findOrCreateUriPermissionLocked(
6367                pi.packageName, targetPkg, targetUid, grantUri);
6368        perm.grantModes(modeFlags, owner);
6369    }
6370
6371    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6372            final int modeFlags, UriPermissionOwner owner) {
6373        if (targetPkg == null) {
6374            throw new NullPointerException("targetPkg");
6375        }
6376
6377        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6378                -1);
6379        if (targetUid < 0) {
6380            return;
6381        }
6382
6383        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6384                owner);
6385    }
6386
6387    static class NeededUriGrants extends ArrayList<GrantUri> {
6388        final String targetPkg;
6389        final int targetUid;
6390        final int flags;
6391
6392        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6393            this.targetPkg = targetPkg;
6394            this.targetUid = targetUid;
6395            this.flags = flags;
6396        }
6397    }
6398
6399    /**
6400     * Like checkGrantUriPermissionLocked, but takes an Intent.
6401     */
6402    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6403            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6404        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6405                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6406                + " clip=" + (intent != null ? intent.getClipData() : null)
6407                + " from " + intent + "; flags=0x"
6408                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6409
6410        if (targetPkg == null) {
6411            throw new NullPointerException("targetPkg");
6412        }
6413
6414        if (intent == null) {
6415            return null;
6416        }
6417        Uri data = intent.getData();
6418        ClipData clip = intent.getClipData();
6419        if (data == null && clip == null) {
6420            return null;
6421        }
6422        final IPackageManager pm = AppGlobals.getPackageManager();
6423        int targetUid;
6424        if (needed != null) {
6425            targetUid = needed.targetUid;
6426        } else {
6427            try {
6428                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6429            } catch (RemoteException ex) {
6430                return null;
6431            }
6432            if (targetUid < 0) {
6433                if (DEBUG_URI_PERMISSION) {
6434                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6435                            + " on user " + targetUserId);
6436                }
6437                return null;
6438            }
6439        }
6440        if (data != null) {
6441            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6442            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6443                    targetUid);
6444            if (targetUid > 0) {
6445                if (needed == null) {
6446                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6447                }
6448                needed.add(grantUri);
6449            }
6450        }
6451        if (clip != null) {
6452            for (int i=0; i<clip.getItemCount(); i++) {
6453                Uri uri = clip.getItemAt(i).getUri();
6454                if (uri != null) {
6455                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6456                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6457                            targetUid);
6458                    if (targetUid > 0) {
6459                        if (needed == null) {
6460                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6461                        }
6462                        needed.add(grantUri);
6463                    }
6464                } else {
6465                    Intent clipIntent = clip.getItemAt(i).getIntent();
6466                    if (clipIntent != null) {
6467                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6468                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6469                        if (newNeeded != null) {
6470                            needed = newNeeded;
6471                        }
6472                    }
6473                }
6474            }
6475        }
6476
6477        return needed;
6478    }
6479
6480    /**
6481     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6482     */
6483    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6484            UriPermissionOwner owner) {
6485        if (needed != null) {
6486            for (int i=0; i<needed.size(); i++) {
6487                GrantUri grantUri = needed.get(i);
6488                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6489                        grantUri, needed.flags, owner);
6490            }
6491        }
6492    }
6493
6494    void grantUriPermissionFromIntentLocked(int callingUid,
6495            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6496        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6497                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6498        if (needed == null) {
6499            return;
6500        }
6501
6502        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6503    }
6504
6505    @Override
6506    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6507            final int modeFlags, int userId) {
6508        enforceNotIsolatedCaller("grantUriPermission");
6509        GrantUri grantUri = new GrantUri(userId, uri, false);
6510        synchronized(this) {
6511            final ProcessRecord r = getRecordForAppLocked(caller);
6512            if (r == null) {
6513                throw new SecurityException("Unable to find app for caller "
6514                        + caller
6515                        + " when granting permission to uri " + grantUri);
6516            }
6517            if (targetPkg == null) {
6518                throw new IllegalArgumentException("null target");
6519            }
6520            if (grantUri == null) {
6521                throw new IllegalArgumentException("null uri");
6522            }
6523
6524            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6525                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6526                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6527                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6528
6529            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6530        }
6531    }
6532
6533    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6534        if (perm.modeFlags == 0) {
6535            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6536                    perm.targetUid);
6537            if (perms != null) {
6538                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6539                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6540
6541                perms.remove(perm.uri);
6542                if (perms.isEmpty()) {
6543                    mGrantedUriPermissions.remove(perm.targetUid);
6544                }
6545            }
6546        }
6547    }
6548
6549    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6550        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6551
6552        final IPackageManager pm = AppGlobals.getPackageManager();
6553        final String authority = grantUri.uri.getAuthority();
6554        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6555        if (pi == null) {
6556            Slog.w(TAG, "No content provider found for permission revoke: "
6557                    + grantUri.toSafeString());
6558            return;
6559        }
6560
6561        // Does the caller have this permission on the URI?
6562        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6563            // Right now, if you are not the original owner of the permission,
6564            // you are not allowed to revoke it.
6565            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6566                throw new SecurityException("Uid " + callingUid
6567                        + " does not have permission to uri " + grantUri);
6568            //}
6569        }
6570
6571        boolean persistChanged = false;
6572
6573        // Go through all of the permissions and remove any that match.
6574        int N = mGrantedUriPermissions.size();
6575        for (int i = 0; i < N; i++) {
6576            final int targetUid = mGrantedUriPermissions.keyAt(i);
6577            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6578
6579            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6580                final UriPermission perm = it.next();
6581                if (perm.uri.sourceUserId == grantUri.sourceUserId
6582                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6583                    if (DEBUG_URI_PERMISSION)
6584                        Slog.v(TAG,
6585                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6586                    persistChanged |= perm.revokeModes(
6587                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6588                    if (perm.modeFlags == 0) {
6589                        it.remove();
6590                    }
6591                }
6592            }
6593
6594            if (perms.isEmpty()) {
6595                mGrantedUriPermissions.remove(targetUid);
6596                N--;
6597                i--;
6598            }
6599        }
6600
6601        if (persistChanged) {
6602            schedulePersistUriGrants();
6603        }
6604    }
6605
6606    @Override
6607    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6608            int userId) {
6609        enforceNotIsolatedCaller("revokeUriPermission");
6610        synchronized(this) {
6611            final ProcessRecord r = getRecordForAppLocked(caller);
6612            if (r == null) {
6613                throw new SecurityException("Unable to find app for caller "
6614                        + caller
6615                        + " when revoking permission to uri " + uri);
6616            }
6617            if (uri == null) {
6618                Slog.w(TAG, "revokeUriPermission: null uri");
6619                return;
6620            }
6621
6622            if (!Intent.isAccessUriMode(modeFlags)) {
6623                return;
6624            }
6625
6626            final IPackageManager pm = AppGlobals.getPackageManager();
6627            final String authority = uri.getAuthority();
6628            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6629            if (pi == null) {
6630                Slog.w(TAG, "No content provider found for permission revoke: "
6631                        + uri.toSafeString());
6632                return;
6633            }
6634
6635            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6636        }
6637    }
6638
6639    /**
6640     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6641     * given package.
6642     *
6643     * @param packageName Package name to match, or {@code null} to apply to all
6644     *            packages.
6645     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6646     *            to all users.
6647     * @param persistable If persistable grants should be removed.
6648     */
6649    private void removeUriPermissionsForPackageLocked(
6650            String packageName, int userHandle, boolean persistable) {
6651        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6652            throw new IllegalArgumentException("Must narrow by either package or user");
6653        }
6654
6655        boolean persistChanged = false;
6656
6657        int N = mGrantedUriPermissions.size();
6658        for (int i = 0; i < N; i++) {
6659            final int targetUid = mGrantedUriPermissions.keyAt(i);
6660            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6661
6662            // Only inspect grants matching user
6663            if (userHandle == UserHandle.USER_ALL
6664                    || userHandle == UserHandle.getUserId(targetUid)) {
6665                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6666                    final UriPermission perm = it.next();
6667
6668                    // Only inspect grants matching package
6669                    if (packageName == null || perm.sourcePkg.equals(packageName)
6670                            || perm.targetPkg.equals(packageName)) {
6671                        persistChanged |= perm.revokeModes(
6672                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6673
6674                        // Only remove when no modes remain; any persisted grants
6675                        // will keep this alive.
6676                        if (perm.modeFlags == 0) {
6677                            it.remove();
6678                        }
6679                    }
6680                }
6681
6682                if (perms.isEmpty()) {
6683                    mGrantedUriPermissions.remove(targetUid);
6684                    N--;
6685                    i--;
6686                }
6687            }
6688        }
6689
6690        if (persistChanged) {
6691            schedulePersistUriGrants();
6692        }
6693    }
6694
6695    @Override
6696    public IBinder newUriPermissionOwner(String name) {
6697        enforceNotIsolatedCaller("newUriPermissionOwner");
6698        synchronized(this) {
6699            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6700            return owner.getExternalTokenLocked();
6701        }
6702    }
6703
6704    @Override
6705    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6706            final int modeFlags, int userId) {
6707        synchronized(this) {
6708            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6709            if (owner == null) {
6710                throw new IllegalArgumentException("Unknown owner: " + token);
6711            }
6712            if (fromUid != Binder.getCallingUid()) {
6713                if (Binder.getCallingUid() != Process.myUid()) {
6714                    // Only system code can grant URI permissions on behalf
6715                    // of other users.
6716                    throw new SecurityException("nice try");
6717                }
6718            }
6719            if (targetPkg == null) {
6720                throw new IllegalArgumentException("null target");
6721            }
6722            if (uri == null) {
6723                throw new IllegalArgumentException("null uri");
6724            }
6725
6726            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6727                    modeFlags, owner);
6728        }
6729    }
6730
6731    @Override
6732    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6733        synchronized(this) {
6734            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6735            if (owner == null) {
6736                throw new IllegalArgumentException("Unknown owner: " + token);
6737            }
6738
6739            if (uri == null) {
6740                owner.removeUriPermissionsLocked(mode);
6741            } else {
6742                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6743            }
6744        }
6745    }
6746
6747    private void schedulePersistUriGrants() {
6748        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6749            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6750                    10 * DateUtils.SECOND_IN_MILLIS);
6751        }
6752    }
6753
6754    private void writeGrantedUriPermissions() {
6755        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6756
6757        // Snapshot permissions so we can persist without lock
6758        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6759        synchronized (this) {
6760            final int size = mGrantedUriPermissions.size();
6761            for (int i = 0; i < size; i++) {
6762                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6763                for (UriPermission perm : perms.values()) {
6764                    if (perm.persistedModeFlags != 0) {
6765                        persist.add(perm.snapshot());
6766                    }
6767                }
6768            }
6769        }
6770
6771        FileOutputStream fos = null;
6772        try {
6773            fos = mGrantFile.startWrite();
6774
6775            XmlSerializer out = new FastXmlSerializer();
6776            out.setOutput(fos, "utf-8");
6777            out.startDocument(null, true);
6778            out.startTag(null, TAG_URI_GRANTS);
6779            for (UriPermission.Snapshot perm : persist) {
6780                out.startTag(null, TAG_URI_GRANT);
6781                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6782                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6783                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6784                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6785                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6786                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6787                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6788                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6789                out.endTag(null, TAG_URI_GRANT);
6790            }
6791            out.endTag(null, TAG_URI_GRANTS);
6792            out.endDocument();
6793
6794            mGrantFile.finishWrite(fos);
6795        } catch (IOException e) {
6796            if (fos != null) {
6797                mGrantFile.failWrite(fos);
6798            }
6799        }
6800    }
6801
6802    private void readGrantedUriPermissionsLocked() {
6803        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6804
6805        final long now = System.currentTimeMillis();
6806
6807        FileInputStream fis = null;
6808        try {
6809            fis = mGrantFile.openRead();
6810            final XmlPullParser in = Xml.newPullParser();
6811            in.setInput(fis, null);
6812
6813            int type;
6814            while ((type = in.next()) != END_DOCUMENT) {
6815                final String tag = in.getName();
6816                if (type == START_TAG) {
6817                    if (TAG_URI_GRANT.equals(tag)) {
6818                        final int sourceUserId;
6819                        final int targetUserId;
6820                        final int userHandle = readIntAttribute(in,
6821                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6822                        if (userHandle != UserHandle.USER_NULL) {
6823                            // For backwards compatibility.
6824                            sourceUserId = userHandle;
6825                            targetUserId = userHandle;
6826                        } else {
6827                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6828                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6829                        }
6830                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6831                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6832                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6833                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6834                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6835                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6836
6837                        // Sanity check that provider still belongs to source package
6838                        final ProviderInfo pi = getProviderInfoLocked(
6839                                uri.getAuthority(), sourceUserId);
6840                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6841                            int targetUid = -1;
6842                            try {
6843                                targetUid = AppGlobals.getPackageManager()
6844                                        .getPackageUid(targetPkg, targetUserId);
6845                            } catch (RemoteException e) {
6846                            }
6847                            if (targetUid != -1) {
6848                                final UriPermission perm = findOrCreateUriPermissionLocked(
6849                                        sourcePkg, targetPkg, targetUid,
6850                                        new GrantUri(sourceUserId, uri, prefix));
6851                                perm.initPersistedModes(modeFlags, createdTime);
6852                            }
6853                        } else {
6854                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6855                                    + " but instead found " + pi);
6856                        }
6857                    }
6858                }
6859            }
6860        } catch (FileNotFoundException e) {
6861            // Missing grants is okay
6862        } catch (IOException e) {
6863            Log.wtf(TAG, "Failed reading Uri grants", e);
6864        } catch (XmlPullParserException e) {
6865            Log.wtf(TAG, "Failed reading Uri grants", e);
6866        } finally {
6867            IoUtils.closeQuietly(fis);
6868        }
6869    }
6870
6871    @Override
6872    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6873        enforceNotIsolatedCaller("takePersistableUriPermission");
6874
6875        Preconditions.checkFlagsArgument(modeFlags,
6876                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6877
6878        synchronized (this) {
6879            final int callingUid = Binder.getCallingUid();
6880            boolean persistChanged = false;
6881            GrantUri grantUri = new GrantUri(userId, uri, false);
6882
6883            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6884                    new GrantUri(userId, uri, false));
6885            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6886                    new GrantUri(userId, uri, true));
6887
6888            final boolean exactValid = (exactPerm != null)
6889                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6890            final boolean prefixValid = (prefixPerm != null)
6891                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6892
6893            if (!(exactValid || prefixValid)) {
6894                throw new SecurityException("No persistable permission grants found for UID "
6895                        + callingUid + " and Uri " + grantUri.toSafeString());
6896            }
6897
6898            if (exactValid) {
6899                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6900            }
6901            if (prefixValid) {
6902                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6903            }
6904
6905            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6906
6907            if (persistChanged) {
6908                schedulePersistUriGrants();
6909            }
6910        }
6911    }
6912
6913    @Override
6914    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6915        enforceNotIsolatedCaller("releasePersistableUriPermission");
6916
6917        Preconditions.checkFlagsArgument(modeFlags,
6918                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6919
6920        synchronized (this) {
6921            final int callingUid = Binder.getCallingUid();
6922            boolean persistChanged = false;
6923
6924            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6925                    new GrantUri(userId, uri, false));
6926            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6927                    new GrantUri(userId, uri, true));
6928            if (exactPerm == null && prefixPerm == null) {
6929                throw new SecurityException("No permission grants found for UID " + callingUid
6930                        + " and Uri " + uri.toSafeString());
6931            }
6932
6933            if (exactPerm != null) {
6934                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6935                removeUriPermissionIfNeededLocked(exactPerm);
6936            }
6937            if (prefixPerm != null) {
6938                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6939                removeUriPermissionIfNeededLocked(prefixPerm);
6940            }
6941
6942            if (persistChanged) {
6943                schedulePersistUriGrants();
6944            }
6945        }
6946    }
6947
6948    /**
6949     * Prune any older {@link UriPermission} for the given UID until outstanding
6950     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6951     *
6952     * @return if any mutations occured that require persisting.
6953     */
6954    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6955        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6956        if (perms == null) return false;
6957        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6958
6959        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6960        for (UriPermission perm : perms.values()) {
6961            if (perm.persistedModeFlags != 0) {
6962                persisted.add(perm);
6963            }
6964        }
6965
6966        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6967        if (trimCount <= 0) return false;
6968
6969        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6970        for (int i = 0; i < trimCount; i++) {
6971            final UriPermission perm = persisted.get(i);
6972
6973            if (DEBUG_URI_PERMISSION) {
6974                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6975            }
6976
6977            perm.releasePersistableModes(~0);
6978            removeUriPermissionIfNeededLocked(perm);
6979        }
6980
6981        return true;
6982    }
6983
6984    @Override
6985    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6986            String packageName, boolean incoming) {
6987        enforceNotIsolatedCaller("getPersistedUriPermissions");
6988        Preconditions.checkNotNull(packageName, "packageName");
6989
6990        final int callingUid = Binder.getCallingUid();
6991        final IPackageManager pm = AppGlobals.getPackageManager();
6992        try {
6993            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6994            if (packageUid != callingUid) {
6995                throw new SecurityException(
6996                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6997            }
6998        } catch (RemoteException e) {
6999            throw new SecurityException("Failed to verify package name ownership");
7000        }
7001
7002        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7003        synchronized (this) {
7004            if (incoming) {
7005                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7006                        callingUid);
7007                if (perms == null) {
7008                    Slog.w(TAG, "No permission grants found for " + packageName);
7009                } else {
7010                    for (UriPermission perm : perms.values()) {
7011                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7012                            result.add(perm.buildPersistedPublicApiObject());
7013                        }
7014                    }
7015                }
7016            } else {
7017                final int size = mGrantedUriPermissions.size();
7018                for (int i = 0; i < size; i++) {
7019                    final ArrayMap<GrantUri, UriPermission> perms =
7020                            mGrantedUriPermissions.valueAt(i);
7021                    for (UriPermission perm : perms.values()) {
7022                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7023                            result.add(perm.buildPersistedPublicApiObject());
7024                        }
7025                    }
7026                }
7027            }
7028        }
7029        return new ParceledListSlice<android.content.UriPermission>(result);
7030    }
7031
7032    @Override
7033    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7034        synchronized (this) {
7035            ProcessRecord app =
7036                who != null ? getRecordForAppLocked(who) : null;
7037            if (app == null) return;
7038
7039            Message msg = Message.obtain();
7040            msg.what = WAIT_FOR_DEBUGGER_MSG;
7041            msg.obj = app;
7042            msg.arg1 = waiting ? 1 : 0;
7043            mHandler.sendMessage(msg);
7044        }
7045    }
7046
7047    @Override
7048    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7049        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7050        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7051        outInfo.availMem = Process.getFreeMemory();
7052        outInfo.totalMem = Process.getTotalMemory();
7053        outInfo.threshold = homeAppMem;
7054        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7055        outInfo.hiddenAppThreshold = cachedAppMem;
7056        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7057                ProcessList.SERVICE_ADJ);
7058        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7059                ProcessList.VISIBLE_APP_ADJ);
7060        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7061                ProcessList.FOREGROUND_APP_ADJ);
7062    }
7063
7064    // =========================================================
7065    // TASK MANAGEMENT
7066    // =========================================================
7067
7068    @Override
7069    public List<IAppTask> getAppTasks() {
7070        int callingUid = Binder.getCallingUid();
7071        long ident = Binder.clearCallingIdentity();
7072        synchronized(this) {
7073            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7074            try {
7075                if (localLOGV) Slog.v(TAG, "getAppTasks");
7076
7077                final int N = mRecentTasks.size();
7078                for (int i = 0; i < N; i++) {
7079                    TaskRecord tr = mRecentTasks.get(i);
7080                    // Skip tasks that are not created by the caller
7081                    if (tr.creatorUid == callingUid) {
7082                        ActivityManager.RecentTaskInfo taskInfo =
7083                                createRecentTaskInfoFromTaskRecord(tr);
7084                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7085                        list.add(taskImpl);
7086                    }
7087                }
7088            } finally {
7089                Binder.restoreCallingIdentity(ident);
7090            }
7091            return list;
7092        }
7093    }
7094
7095    @Override
7096    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7097        final int callingUid = Binder.getCallingUid();
7098        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7099
7100        synchronized(this) {
7101            if (localLOGV) Slog.v(
7102                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7103
7104            final boolean allowed = checkCallingPermission(
7105                    android.Manifest.permission.GET_TASKS)
7106                    == PackageManager.PERMISSION_GRANTED;
7107            if (!allowed) {
7108                Slog.w(TAG, "getTasks: caller " + callingUid
7109                        + " does not hold GET_TASKS; limiting output");
7110            }
7111
7112            // TODO: Improve with MRU list from all ActivityStacks.
7113            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7114        }
7115
7116        return list;
7117    }
7118
7119    TaskRecord getMostRecentTask() {
7120        return mRecentTasks.get(0);
7121    }
7122
7123    /**
7124     * Creates a new RecentTaskInfo from a TaskRecord.
7125     */
7126    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7127        // Update the task description to reflect any changes in the task stack
7128        tr.updateTaskDescription();
7129
7130        // Compose the recent task info
7131        ActivityManager.RecentTaskInfo rti
7132                = new ActivityManager.RecentTaskInfo();
7133        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7134        rti.persistentId = tr.taskId;
7135        rti.baseIntent = new Intent(tr.getBaseIntent());
7136        rti.origActivity = tr.origActivity;
7137        rti.description = tr.lastDescription;
7138        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7139        rti.userId = tr.userId;
7140        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7141        return rti;
7142    }
7143
7144    @Override
7145    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7146            int flags, int userId) {
7147        final int callingUid = Binder.getCallingUid();
7148        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7149                false, true, "getRecentTasks", null);
7150
7151        synchronized (this) {
7152            final boolean allowed = checkCallingPermission(
7153                    android.Manifest.permission.GET_TASKS)
7154                    == PackageManager.PERMISSION_GRANTED;
7155            if (!allowed) {
7156                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7157                        + " does not hold GET_TASKS; limiting output");
7158            }
7159            final boolean detailed = checkCallingPermission(
7160                    android.Manifest.permission.GET_DETAILED_TASKS)
7161                    == PackageManager.PERMISSION_GRANTED;
7162
7163            IPackageManager pm = AppGlobals.getPackageManager();
7164
7165            final int N = mRecentTasks.size();
7166            ArrayList<ActivityManager.RecentTaskInfo> res
7167                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7168                            maxNum < N ? maxNum : N);
7169
7170            final Set<Integer> includedUsers;
7171            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7172                includedUsers = getProfileIdsLocked(userId);
7173            } else {
7174                includedUsers = new HashSet<Integer>();
7175            }
7176            includedUsers.add(Integer.valueOf(userId));
7177            for (int i=0; i<N && maxNum > 0; i++) {
7178                TaskRecord tr = mRecentTasks.get(i);
7179                // Only add calling user or related users recent tasks
7180                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7181
7182                // Return the entry if desired by the caller.  We always return
7183                // the first entry, because callers always expect this to be the
7184                // foreground app.  We may filter others if the caller has
7185                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7186                // we should exclude the entry.
7187
7188                if (i == 0
7189                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7190                        || (tr.intent == null)
7191                        || ((tr.intent.getFlags()
7192                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7193                    if (!allowed) {
7194                        // If the caller doesn't have the GET_TASKS permission, then only
7195                        // allow them to see a small subset of tasks -- their own and home.
7196                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7197                            continue;
7198                        }
7199                    }
7200
7201                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7202                    if (!detailed) {
7203                        rti.baseIntent.replaceExtras((Bundle)null);
7204                    }
7205
7206                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7207                        // Check whether this activity is currently available.
7208                        try {
7209                            if (rti.origActivity != null) {
7210                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7211                                        == null) {
7212                                    continue;
7213                                }
7214                            } else if (rti.baseIntent != null) {
7215                                if (pm.queryIntentActivities(rti.baseIntent,
7216                                        null, 0, userId) == null) {
7217                                    continue;
7218                                }
7219                            }
7220                        } catch (RemoteException e) {
7221                            // Will never happen.
7222                        }
7223                    }
7224
7225                    res.add(rti);
7226                    maxNum--;
7227                }
7228            }
7229            return res;
7230        }
7231    }
7232
7233    private TaskRecord recentTaskForIdLocked(int id) {
7234        final int N = mRecentTasks.size();
7235            for (int i=0; i<N; i++) {
7236                TaskRecord tr = mRecentTasks.get(i);
7237                if (tr.taskId == id) {
7238                    return tr;
7239                }
7240            }
7241            return null;
7242    }
7243
7244    @Override
7245    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7246        synchronized (this) {
7247            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7248                    "getTaskThumbnails()");
7249            TaskRecord tr = recentTaskForIdLocked(id);
7250            if (tr != null) {
7251                return tr.getTaskThumbnailsLocked();
7252            }
7253        }
7254        return null;
7255    }
7256
7257    @Override
7258    public Bitmap getTaskTopThumbnail(int id) {
7259        synchronized (this) {
7260            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7261                    "getTaskTopThumbnail()");
7262            TaskRecord tr = recentTaskForIdLocked(id);
7263            if (tr != null) {
7264                return tr.getTaskTopThumbnailLocked();
7265            }
7266        }
7267        return null;
7268    }
7269
7270    @Override
7271    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7272        synchronized (this) {
7273            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7274            if (r != null) {
7275                r.taskDescription = td;
7276                r.task.updateTaskDescription();
7277            }
7278        }
7279    }
7280
7281    @Override
7282    public boolean removeSubTask(int taskId, int subTaskIndex) {
7283        synchronized (this) {
7284            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7285                    "removeSubTask()");
7286            long ident = Binder.clearCallingIdentity();
7287            try {
7288                TaskRecord tr = recentTaskForIdLocked(taskId);
7289                if (tr != null) {
7290                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7291                }
7292                return false;
7293            } finally {
7294                Binder.restoreCallingIdentity(ident);
7295            }
7296        }
7297    }
7298
7299    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7300        if (!pr.killedByAm) {
7301            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7302            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7303                    pr.processName, pr.setAdj, reason);
7304            pr.killedByAm = true;
7305            Process.killProcessQuiet(pr.pid);
7306        }
7307    }
7308
7309    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7310        tr.disposeThumbnail();
7311        mRecentTasks.remove(tr);
7312        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7313        Intent baseIntent = new Intent(
7314                tr.intent != null ? tr.intent : tr.affinityIntent);
7315        ComponentName component = baseIntent.getComponent();
7316        if (component == null) {
7317            Slog.w(TAG, "Now component for base intent of task: " + tr);
7318            return;
7319        }
7320
7321        // Find any running services associated with this app.
7322        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7323
7324        if (killProcesses) {
7325            // Find any running processes associated with this app.
7326            final String pkg = component.getPackageName();
7327            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7328            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7329            for (int i=0; i<pmap.size(); i++) {
7330                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7331                for (int j=0; j<uids.size(); j++) {
7332                    ProcessRecord proc = uids.valueAt(j);
7333                    if (proc.userId != tr.userId) {
7334                        continue;
7335                    }
7336                    if (!proc.pkgList.containsKey(pkg)) {
7337                        continue;
7338                    }
7339                    procs.add(proc);
7340                }
7341            }
7342
7343            // Kill the running processes.
7344            for (int i=0; i<procs.size(); i++) {
7345                ProcessRecord pr = procs.get(i);
7346                if (pr == mHomeProcess) {
7347                    // Don't kill the home process along with tasks from the same package.
7348                    continue;
7349                }
7350                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7351                    killUnneededProcessLocked(pr, "remove task");
7352                } else {
7353                    pr.waitingToKill = "remove task";
7354                }
7355            }
7356        }
7357    }
7358
7359    /**
7360     * Removes the task with the specified task id.
7361     *
7362     * @param taskId Identifier of the task to be removed.
7363     * @param flags Additional operational flags.  May be 0 or
7364     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7365     * @return Returns true if the given task was found and removed.
7366     */
7367    private boolean removeTaskByIdLocked(int taskId, int flags) {
7368        TaskRecord tr = recentTaskForIdLocked(taskId);
7369        if (tr != null) {
7370            tr.removeTaskActivitiesLocked(-1, false);
7371            cleanUpRemovedTaskLocked(tr, flags);
7372            if (tr.isPersistable) {
7373                notifyTaskPersisterLocked(tr, true);
7374            }
7375            return true;
7376        }
7377        return false;
7378    }
7379
7380    @Override
7381    public boolean removeTask(int taskId, int flags) {
7382        synchronized (this) {
7383            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7384                    "removeTask()");
7385            long ident = Binder.clearCallingIdentity();
7386            try {
7387                return removeTaskByIdLocked(taskId, flags);
7388            } finally {
7389                Binder.restoreCallingIdentity(ident);
7390            }
7391        }
7392    }
7393
7394    /**
7395     * TODO: Add mController hook
7396     */
7397    @Override
7398    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7399        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7400                "moveTaskToFront()");
7401
7402        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7403        synchronized(this) {
7404            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7405                    Binder.getCallingUid(), "Task to front")) {
7406                ActivityOptions.abort(options);
7407                return;
7408            }
7409            final long origId = Binder.clearCallingIdentity();
7410            try {
7411                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7412                if (task == null) {
7413                    return;
7414                }
7415                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7416                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7417                    return;
7418                }
7419                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7420            } finally {
7421                Binder.restoreCallingIdentity(origId);
7422            }
7423            ActivityOptions.abort(options);
7424        }
7425    }
7426
7427    @Override
7428    public void moveTaskToBack(int taskId) {
7429        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7430                "moveTaskToBack()");
7431
7432        synchronized(this) {
7433            TaskRecord tr = recentTaskForIdLocked(taskId);
7434            if (tr != null) {
7435                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7436                ActivityStack stack = tr.stack;
7437                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7438                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7439                            Binder.getCallingUid(), "Task to back")) {
7440                        return;
7441                    }
7442                }
7443                final long origId = Binder.clearCallingIdentity();
7444                try {
7445                    stack.moveTaskToBackLocked(taskId, null);
7446                } finally {
7447                    Binder.restoreCallingIdentity(origId);
7448                }
7449            }
7450        }
7451    }
7452
7453    /**
7454     * Moves an activity, and all of the other activities within the same task, to the bottom
7455     * of the history stack.  The activity's order within the task is unchanged.
7456     *
7457     * @param token A reference to the activity we wish to move
7458     * @param nonRoot If false then this only works if the activity is the root
7459     *                of a task; if true it will work for any activity in a task.
7460     * @return Returns true if the move completed, false if not.
7461     */
7462    @Override
7463    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7464        enforceNotIsolatedCaller("moveActivityTaskToBack");
7465        synchronized(this) {
7466            final long origId = Binder.clearCallingIdentity();
7467            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7468            if (taskId >= 0) {
7469                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7470            }
7471            Binder.restoreCallingIdentity(origId);
7472        }
7473        return false;
7474    }
7475
7476    @Override
7477    public void moveTaskBackwards(int task) {
7478        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7479                "moveTaskBackwards()");
7480
7481        synchronized(this) {
7482            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7483                    Binder.getCallingUid(), "Task backwards")) {
7484                return;
7485            }
7486            final long origId = Binder.clearCallingIdentity();
7487            moveTaskBackwardsLocked(task);
7488            Binder.restoreCallingIdentity(origId);
7489        }
7490    }
7491
7492    private final void moveTaskBackwardsLocked(int task) {
7493        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7494    }
7495
7496    @Override
7497    public IBinder getHomeActivityToken() throws RemoteException {
7498        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7499                "getHomeActivityToken()");
7500        synchronized (this) {
7501            return mStackSupervisor.getHomeActivityToken();
7502        }
7503    }
7504
7505    @Override
7506    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7507            IActivityContainerCallback callback) throws RemoteException {
7508        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7509                "createActivityContainer()");
7510        synchronized (this) {
7511            if (parentActivityToken == null) {
7512                throw new IllegalArgumentException("parent token must not be null");
7513            }
7514            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7515            if (r == null) {
7516                return null;
7517            }
7518            if (callback == null) {
7519                throw new IllegalArgumentException("callback must not be null");
7520            }
7521            return mStackSupervisor.createActivityContainer(r, callback);
7522        }
7523    }
7524
7525    @Override
7526    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7527        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7528                "deleteActivityContainer()");
7529        synchronized (this) {
7530            mStackSupervisor.deleteActivityContainer(container);
7531        }
7532    }
7533
7534    @Override
7535    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7536            throws RemoteException {
7537        synchronized (this) {
7538            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7539            if (stack != null) {
7540                return stack.mActivityContainer;
7541            }
7542            return null;
7543        }
7544    }
7545
7546    @Override
7547    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7548        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7549                "moveTaskToStack()");
7550        if (stackId == HOME_STACK_ID) {
7551            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7552                    new RuntimeException("here").fillInStackTrace());
7553        }
7554        synchronized (this) {
7555            long ident = Binder.clearCallingIdentity();
7556            try {
7557                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7558                        + stackId + " toTop=" + toTop);
7559                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7560            } finally {
7561                Binder.restoreCallingIdentity(ident);
7562            }
7563        }
7564    }
7565
7566    @Override
7567    public void resizeStack(int stackBoxId, Rect bounds) {
7568        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7569                "resizeStackBox()");
7570        long ident = Binder.clearCallingIdentity();
7571        try {
7572            mWindowManager.resizeStack(stackBoxId, bounds);
7573        } finally {
7574            Binder.restoreCallingIdentity(ident);
7575        }
7576    }
7577
7578    @Override
7579    public List<StackInfo> getAllStackInfos() {
7580        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7581                "getAllStackInfos()");
7582        long ident = Binder.clearCallingIdentity();
7583        try {
7584            synchronized (this) {
7585                return mStackSupervisor.getAllStackInfosLocked();
7586            }
7587        } finally {
7588            Binder.restoreCallingIdentity(ident);
7589        }
7590    }
7591
7592    @Override
7593    public StackInfo getStackInfo(int stackId) {
7594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7595                "getStackInfo()");
7596        long ident = Binder.clearCallingIdentity();
7597        try {
7598            synchronized (this) {
7599                return mStackSupervisor.getStackInfoLocked(stackId);
7600            }
7601        } finally {
7602            Binder.restoreCallingIdentity(ident);
7603        }
7604    }
7605
7606    @Override
7607    public boolean isInHomeStack(int taskId) {
7608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7609                "getStackInfo()");
7610        long ident = Binder.clearCallingIdentity();
7611        try {
7612            synchronized (this) {
7613                TaskRecord tr = recentTaskForIdLocked(taskId);
7614                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7615            }
7616        } finally {
7617            Binder.restoreCallingIdentity(ident);
7618        }
7619    }
7620
7621    @Override
7622    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7623        synchronized(this) {
7624            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7625        }
7626    }
7627
7628    private boolean isLockTaskAuthorized(String pkg) {
7629        final DevicePolicyManager dpm = (DevicePolicyManager)
7630                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7631        try {
7632            int uid = mContext.getPackageManager().getPackageUid(pkg,
7633                    Binder.getCallingUserHandle().getIdentifier());
7634            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7635        } catch (NameNotFoundException e) {
7636            return false;
7637        }
7638    }
7639
7640    private void startLockTaskMode(TaskRecord task) {
7641        final String pkg;
7642        synchronized (this) {
7643            pkg = task.intent.getComponent().getPackageName();
7644        }
7645        if (!isLockTaskAuthorized(pkg)) {
7646            return;
7647        }
7648        long ident = Binder.clearCallingIdentity();
7649        try {
7650            synchronized (this) {
7651                // Since we lost lock on task, make sure it is still there.
7652                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7653                if (task != null) {
7654                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7655                        throw new IllegalArgumentException("Invalid task, not in foreground");
7656                    }
7657                    mStackSupervisor.setLockTaskModeLocked(task);
7658                }
7659            }
7660        } finally {
7661            Binder.restoreCallingIdentity(ident);
7662        }
7663    }
7664
7665    @Override
7666    public void startLockTaskMode(int taskId) {
7667        final TaskRecord task;
7668        long ident = Binder.clearCallingIdentity();
7669        try {
7670            synchronized (this) {
7671                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7672            }
7673        } finally {
7674            Binder.restoreCallingIdentity(ident);
7675        }
7676        if (task != null) {
7677            startLockTaskMode(task);
7678        }
7679    }
7680
7681    @Override
7682    public void startLockTaskMode(IBinder token) {
7683        final TaskRecord task;
7684        long ident = Binder.clearCallingIdentity();
7685        try {
7686            synchronized (this) {
7687                final ActivityRecord r = ActivityRecord.forToken(token);
7688                if (r == null) {
7689                    return;
7690                }
7691                task = r.task;
7692            }
7693        } finally {
7694            Binder.restoreCallingIdentity(ident);
7695        }
7696        if (task != null) {
7697            startLockTaskMode(task);
7698        }
7699    }
7700
7701    @Override
7702    public void stopLockTaskMode() {
7703        // Verify that the user matches the package of the intent for the TaskRecord
7704        // we are locked to.  This will ensure the same caller for startLockTaskMode and
7705        // stopLockTaskMode.
7706        try {
7707            String pkg = mStackSupervisor.mLockTaskModeTask.intent.getPackage();
7708            int uid = mContext.getPackageManager().getPackageUid(pkg,
7709                    Binder.getCallingUserHandle().getIdentifier());
7710            if (uid != Binder.getCallingUid()) {
7711                throw new SecurityException("Invalid uid, expected " + uid);
7712            }
7713        } catch (NameNotFoundException e) {
7714            Log.d(TAG, "stopLockTaskMode " + e);
7715            return;
7716        }
7717        // Stop lock task
7718        synchronized (this) {
7719            mStackSupervisor.setLockTaskModeLocked(null);
7720        }
7721    }
7722
7723    @Override
7724    public boolean isInLockTaskMode() {
7725        synchronized (this) {
7726            return mStackSupervisor.isInLockTaskMode();
7727        }
7728    }
7729
7730    // =========================================================
7731    // CONTENT PROVIDERS
7732    // =========================================================
7733
7734    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7735        List<ProviderInfo> providers = null;
7736        try {
7737            providers = AppGlobals.getPackageManager().
7738                queryContentProviders(app.processName, app.uid,
7739                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7740        } catch (RemoteException ex) {
7741        }
7742        if (DEBUG_MU)
7743            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7744        int userId = app.userId;
7745        if (providers != null) {
7746            int N = providers.size();
7747            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7748            for (int i=0; i<N; i++) {
7749                ProviderInfo cpi =
7750                    (ProviderInfo)providers.get(i);
7751                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7752                        cpi.name, cpi.flags);
7753                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7754                    // This is a singleton provider, but a user besides the
7755                    // default user is asking to initialize a process it runs
7756                    // in...  well, no, it doesn't actually run in this process,
7757                    // it runs in the process of the default user.  Get rid of it.
7758                    providers.remove(i);
7759                    N--;
7760                    i--;
7761                    continue;
7762                }
7763
7764                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7765                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7766                if (cpr == null) {
7767                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7768                    mProviderMap.putProviderByClass(comp, cpr);
7769                }
7770                if (DEBUG_MU)
7771                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7772                app.pubProviders.put(cpi.name, cpr);
7773                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7774                    // Don't add this if it is a platform component that is marked
7775                    // to run in multiple processes, because this is actually
7776                    // part of the framework so doesn't make sense to track as a
7777                    // separate apk in the process.
7778                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7779                }
7780                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7781            }
7782        }
7783        return providers;
7784    }
7785
7786    /**
7787     * Check if {@link ProcessRecord} has a possible chance at accessing the
7788     * given {@link ProviderInfo}. Final permission checking is always done
7789     * in {@link ContentProvider}.
7790     */
7791    private final String checkContentProviderPermissionLocked(
7792            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7793        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7794        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7795        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7796        // Looking for cross-user grants before to enforce the typical cross-users permissions
7797        if (userId != UserHandle.getUserId(callingUid)) {
7798            if (perms != null) {
7799                for (GrantUri grantUri : perms.keySet()) {
7800                    if (grantUri.sourceUserId == userId) {
7801                        String authority = grantUri.uri.getAuthority();
7802                        if (authority.equals(cpi.authority)) {
7803                            return null;
7804                        }
7805                    }
7806                }
7807            }
7808        }
7809        if (checkUser) {
7810            userId = handleIncomingUser(callingPid, callingUid, userId,
7811                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7812        }
7813        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7814                cpi.applicationInfo.uid, cpi.exported)
7815                == PackageManager.PERMISSION_GRANTED) {
7816            return null;
7817        }
7818        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7819                cpi.applicationInfo.uid, cpi.exported)
7820                == PackageManager.PERMISSION_GRANTED) {
7821            return null;
7822        }
7823
7824        PathPermission[] pps = cpi.pathPermissions;
7825        if (pps != null) {
7826            int i = pps.length;
7827            while (i > 0) {
7828                i--;
7829                PathPermission pp = pps[i];
7830                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7831                        cpi.applicationInfo.uid, cpi.exported)
7832                        == PackageManager.PERMISSION_GRANTED) {
7833                    return null;
7834                }
7835                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7836                        cpi.applicationInfo.uid, cpi.exported)
7837                        == PackageManager.PERMISSION_GRANTED) {
7838                    return null;
7839                }
7840            }
7841        }
7842
7843        if (perms != null) {
7844            for (GrantUri grantUri : perms.keySet()) {
7845                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7846                    return null;
7847                }
7848            }
7849        }
7850
7851        String msg;
7852        if (!cpi.exported) {
7853            msg = "Permission Denial: opening provider " + cpi.name
7854                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7855                    + ", uid=" + callingUid + ") that is not exported from uid "
7856                    + cpi.applicationInfo.uid;
7857        } else {
7858            msg = "Permission Denial: opening provider " + cpi.name
7859                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7860                    + ", uid=" + callingUid + ") requires "
7861                    + cpi.readPermission + " or " + cpi.writePermission;
7862        }
7863        Slog.w(TAG, msg);
7864        return msg;
7865    }
7866
7867    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7868            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7869        if (r != null) {
7870            for (int i=0; i<r.conProviders.size(); i++) {
7871                ContentProviderConnection conn = r.conProviders.get(i);
7872                if (conn.provider == cpr) {
7873                    if (DEBUG_PROVIDER) Slog.v(TAG,
7874                            "Adding provider requested by "
7875                            + r.processName + " from process "
7876                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7877                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7878                    if (stable) {
7879                        conn.stableCount++;
7880                        conn.numStableIncs++;
7881                    } else {
7882                        conn.unstableCount++;
7883                        conn.numUnstableIncs++;
7884                    }
7885                    return conn;
7886                }
7887            }
7888            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7889            if (stable) {
7890                conn.stableCount = 1;
7891                conn.numStableIncs = 1;
7892            } else {
7893                conn.unstableCount = 1;
7894                conn.numUnstableIncs = 1;
7895            }
7896            cpr.connections.add(conn);
7897            r.conProviders.add(conn);
7898            return conn;
7899        }
7900        cpr.addExternalProcessHandleLocked(externalProcessToken);
7901        return null;
7902    }
7903
7904    boolean decProviderCountLocked(ContentProviderConnection conn,
7905            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7906        if (conn != null) {
7907            cpr = conn.provider;
7908            if (DEBUG_PROVIDER) Slog.v(TAG,
7909                    "Removing provider requested by "
7910                    + conn.client.processName + " from process "
7911                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7912                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7913            if (stable) {
7914                conn.stableCount--;
7915            } else {
7916                conn.unstableCount--;
7917            }
7918            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7919                cpr.connections.remove(conn);
7920                conn.client.conProviders.remove(conn);
7921                return true;
7922            }
7923            return false;
7924        }
7925        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7926        return false;
7927    }
7928
7929    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7930            String name, IBinder token, boolean stable, int userId) {
7931        ContentProviderRecord cpr;
7932        ContentProviderConnection conn = null;
7933        ProviderInfo cpi = null;
7934
7935        synchronized(this) {
7936            ProcessRecord r = null;
7937            if (caller != null) {
7938                r = getRecordForAppLocked(caller);
7939                if (r == null) {
7940                    throw new SecurityException(
7941                            "Unable to find app for caller " + caller
7942                          + " (pid=" + Binder.getCallingPid()
7943                          + ") when getting content provider " + name);
7944                }
7945            }
7946
7947            boolean checkCrossUser = true;
7948
7949            // First check if this content provider has been published...
7950            cpr = mProviderMap.getProviderByName(name, userId);
7951            // If that didn't work, check if it exists for user 0 and then
7952            // verify that it's a singleton provider before using it.
7953            if (cpr == null && userId != UserHandle.USER_OWNER) {
7954                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
7955                if (cpr != null) {
7956                    cpi = cpr.info;
7957                    if (isSingleton(cpi.processName, cpi.applicationInfo,
7958                            cpi.name, cpi.flags)
7959                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
7960                        userId = UserHandle.USER_OWNER;
7961                        checkCrossUser = false;
7962                    } else {
7963                        cpr = null;
7964                        cpi = null;
7965                    }
7966                }
7967            }
7968
7969            boolean providerRunning = cpr != null;
7970            if (providerRunning) {
7971                cpi = cpr.info;
7972                String msg;
7973                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
7974                        != null) {
7975                    throw new SecurityException(msg);
7976                }
7977
7978                if (r != null && cpr.canRunHere(r)) {
7979                    // This provider has been published or is in the process
7980                    // of being published...  but it is also allowed to run
7981                    // in the caller's process, so don't make a connection
7982                    // and just let the caller instantiate its own instance.
7983                    ContentProviderHolder holder = cpr.newHolder(null);
7984                    // don't give caller the provider object, it needs
7985                    // to make its own.
7986                    holder.provider = null;
7987                    return holder;
7988                }
7989
7990                final long origId = Binder.clearCallingIdentity();
7991
7992                // In this case the provider instance already exists, so we can
7993                // return it right away.
7994                conn = incProviderCountLocked(r, cpr, token, stable);
7995                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7996                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7997                        // If this is a perceptible app accessing the provider,
7998                        // make sure to count it as being accessed and thus
7999                        // back up on the LRU list.  This is good because
8000                        // content providers are often expensive to start.
8001                        updateLruProcessLocked(cpr.proc, false, null);
8002                    }
8003                }
8004
8005                if (cpr.proc != null) {
8006                    if (false) {
8007                        if (cpr.name.flattenToShortString().equals(
8008                                "com.android.providers.calendar/.CalendarProvider2")) {
8009                            Slog.v(TAG, "****************** KILLING "
8010                                + cpr.name.flattenToShortString());
8011                            Process.killProcess(cpr.proc.pid);
8012                        }
8013                    }
8014                    boolean success = updateOomAdjLocked(cpr.proc);
8015                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8016                    // NOTE: there is still a race here where a signal could be
8017                    // pending on the process even though we managed to update its
8018                    // adj level.  Not sure what to do about this, but at least
8019                    // the race is now smaller.
8020                    if (!success) {
8021                        // Uh oh...  it looks like the provider's process
8022                        // has been killed on us.  We need to wait for a new
8023                        // process to be started, and make sure its death
8024                        // doesn't kill our process.
8025                        Slog.i(TAG,
8026                                "Existing provider " + cpr.name.flattenToShortString()
8027                                + " is crashing; detaching " + r);
8028                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8029                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8030                        if (!lastRef) {
8031                            // This wasn't the last ref our process had on
8032                            // the provider...  we have now been killed, bail.
8033                            return null;
8034                        }
8035                        providerRunning = false;
8036                        conn = null;
8037                    }
8038                }
8039
8040                Binder.restoreCallingIdentity(origId);
8041            }
8042
8043            boolean singleton;
8044            if (!providerRunning) {
8045                try {
8046                    cpi = AppGlobals.getPackageManager().
8047                        resolveContentProvider(name,
8048                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8049                } catch (RemoteException ex) {
8050                }
8051                if (cpi == null) {
8052                    return null;
8053                }
8054                // If the provider is a singleton AND
8055                // (it's a call within the same user || the provider is a
8056                // privileged app)
8057                // Then allow connecting to the singleton provider
8058                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8059                        cpi.name, cpi.flags)
8060                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8061                if (singleton) {
8062                    userId = UserHandle.USER_OWNER;
8063                }
8064                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8065
8066                String msg;
8067                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8068                        != null) {
8069                    throw new SecurityException(msg);
8070                }
8071
8072                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8073                        && !cpi.processName.equals("system")) {
8074                    // If this content provider does not run in the system
8075                    // process, and the system is not yet ready to run other
8076                    // processes, then fail fast instead of hanging.
8077                    throw new IllegalArgumentException(
8078                            "Attempt to launch content provider before system ready");
8079                }
8080
8081                // Make sure that the user who owns this provider is started.  If not,
8082                // we don't want to allow it to run.
8083                if (mStartedUsers.get(userId) == null) {
8084                    Slog.w(TAG, "Unable to launch app "
8085                            + cpi.applicationInfo.packageName + "/"
8086                            + cpi.applicationInfo.uid + " for provider "
8087                            + name + ": user " + userId + " is stopped");
8088                    return null;
8089                }
8090
8091                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8092                cpr = mProviderMap.getProviderByClass(comp, userId);
8093                final boolean firstClass = cpr == null;
8094                if (firstClass) {
8095                    try {
8096                        ApplicationInfo ai =
8097                            AppGlobals.getPackageManager().
8098                                getApplicationInfo(
8099                                        cpi.applicationInfo.packageName,
8100                                        STOCK_PM_FLAGS, userId);
8101                        if (ai == null) {
8102                            Slog.w(TAG, "No package info for content provider "
8103                                    + cpi.name);
8104                            return null;
8105                        }
8106                        ai = getAppInfoForUser(ai, userId);
8107                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8108                    } catch (RemoteException ex) {
8109                        // pm is in same process, this will never happen.
8110                    }
8111                }
8112
8113                if (r != null && cpr.canRunHere(r)) {
8114                    // If this is a multiprocess provider, then just return its
8115                    // info and allow the caller to instantiate it.  Only do
8116                    // this if the provider is the same user as the caller's
8117                    // process, or can run as root (so can be in any process).
8118                    return cpr.newHolder(null);
8119                }
8120
8121                if (DEBUG_PROVIDER) {
8122                    RuntimeException e = new RuntimeException("here");
8123                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8124                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8125                }
8126
8127                // This is single process, and our app is now connecting to it.
8128                // See if we are already in the process of launching this
8129                // provider.
8130                final int N = mLaunchingProviders.size();
8131                int i;
8132                for (i=0; i<N; i++) {
8133                    if (mLaunchingProviders.get(i) == cpr) {
8134                        break;
8135                    }
8136                }
8137
8138                // If the provider is not already being launched, then get it
8139                // started.
8140                if (i >= N) {
8141                    final long origId = Binder.clearCallingIdentity();
8142
8143                    try {
8144                        // Content provider is now in use, its package can't be stopped.
8145                        try {
8146                            AppGlobals.getPackageManager().setPackageStoppedState(
8147                                    cpr.appInfo.packageName, false, userId);
8148                        } catch (RemoteException e) {
8149                        } catch (IllegalArgumentException e) {
8150                            Slog.w(TAG, "Failed trying to unstop package "
8151                                    + cpr.appInfo.packageName + ": " + e);
8152                        }
8153
8154                        // Use existing process if already started
8155                        ProcessRecord proc = getProcessRecordLocked(
8156                                cpi.processName, cpr.appInfo.uid, false);
8157                        if (proc != null && proc.thread != null) {
8158                            if (DEBUG_PROVIDER) {
8159                                Slog.d(TAG, "Installing in existing process " + proc);
8160                            }
8161                            proc.pubProviders.put(cpi.name, cpr);
8162                            try {
8163                                proc.thread.scheduleInstallProvider(cpi);
8164                            } catch (RemoteException e) {
8165                            }
8166                        } else {
8167                            proc = startProcessLocked(cpi.processName,
8168                                    cpr.appInfo, false, 0, "content provider",
8169                                    new ComponentName(cpi.applicationInfo.packageName,
8170                                            cpi.name), false, false, false);
8171                            if (proc == null) {
8172                                Slog.w(TAG, "Unable to launch app "
8173                                        + cpi.applicationInfo.packageName + "/"
8174                                        + cpi.applicationInfo.uid + " for provider "
8175                                        + name + ": process is bad");
8176                                return null;
8177                            }
8178                        }
8179                        cpr.launchingApp = proc;
8180                        mLaunchingProviders.add(cpr);
8181                    } finally {
8182                        Binder.restoreCallingIdentity(origId);
8183                    }
8184                }
8185
8186                // Make sure the provider is published (the same provider class
8187                // may be published under multiple names).
8188                if (firstClass) {
8189                    mProviderMap.putProviderByClass(comp, cpr);
8190                }
8191
8192                mProviderMap.putProviderByName(name, cpr);
8193                conn = incProviderCountLocked(r, cpr, token, stable);
8194                if (conn != null) {
8195                    conn.waiting = true;
8196                }
8197            }
8198        }
8199
8200        // Wait for the provider to be published...
8201        synchronized (cpr) {
8202            while (cpr.provider == null) {
8203                if (cpr.launchingApp == null) {
8204                    Slog.w(TAG, "Unable to launch app "
8205                            + cpi.applicationInfo.packageName + "/"
8206                            + cpi.applicationInfo.uid + " for provider "
8207                            + name + ": launching app became null");
8208                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8209                            UserHandle.getUserId(cpi.applicationInfo.uid),
8210                            cpi.applicationInfo.packageName,
8211                            cpi.applicationInfo.uid, name);
8212                    return null;
8213                }
8214                try {
8215                    if (DEBUG_MU) {
8216                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8217                                + cpr.launchingApp);
8218                    }
8219                    if (conn != null) {
8220                        conn.waiting = true;
8221                    }
8222                    cpr.wait();
8223                } catch (InterruptedException ex) {
8224                } finally {
8225                    if (conn != null) {
8226                        conn.waiting = false;
8227                    }
8228                }
8229            }
8230        }
8231        return cpr != null ? cpr.newHolder(conn) : null;
8232    }
8233
8234    @Override
8235    public final ContentProviderHolder getContentProvider(
8236            IApplicationThread caller, String name, int userId, boolean stable) {
8237        enforceNotIsolatedCaller("getContentProvider");
8238        if (caller == null) {
8239            String msg = "null IApplicationThread when getting content provider "
8240                    + name;
8241            Slog.w(TAG, msg);
8242            throw new SecurityException(msg);
8243        }
8244        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8245        // with cross-user grant.
8246        return getContentProviderImpl(caller, name, null, stable, userId);
8247    }
8248
8249    public ContentProviderHolder getContentProviderExternal(
8250            String name, int userId, IBinder token) {
8251        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8252            "Do not have permission in call getContentProviderExternal()");
8253        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8254                false, true, "getContentProvider", null);
8255        return getContentProviderExternalUnchecked(name, token, userId);
8256    }
8257
8258    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8259            IBinder token, int userId) {
8260        return getContentProviderImpl(null, name, token, true, userId);
8261    }
8262
8263    /**
8264     * Drop a content provider from a ProcessRecord's bookkeeping
8265     */
8266    public void removeContentProvider(IBinder connection, boolean stable) {
8267        enforceNotIsolatedCaller("removeContentProvider");
8268        long ident = Binder.clearCallingIdentity();
8269        try {
8270            synchronized (this) {
8271                ContentProviderConnection conn;
8272                try {
8273                    conn = (ContentProviderConnection)connection;
8274                } catch (ClassCastException e) {
8275                    String msg ="removeContentProvider: " + connection
8276                            + " not a ContentProviderConnection";
8277                    Slog.w(TAG, msg);
8278                    throw new IllegalArgumentException(msg);
8279                }
8280                if (conn == null) {
8281                    throw new NullPointerException("connection is null");
8282                }
8283                if (decProviderCountLocked(conn, null, null, stable)) {
8284                    updateOomAdjLocked();
8285                }
8286            }
8287        } finally {
8288            Binder.restoreCallingIdentity(ident);
8289        }
8290    }
8291
8292    public void removeContentProviderExternal(String name, IBinder token) {
8293        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8294            "Do not have permission in call removeContentProviderExternal()");
8295        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8296    }
8297
8298    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8299        synchronized (this) {
8300            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8301            if(cpr == null) {
8302                //remove from mProvidersByClass
8303                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8304                return;
8305            }
8306
8307            //update content provider record entry info
8308            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8309            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8310            if (localCpr.hasExternalProcessHandles()) {
8311                if (localCpr.removeExternalProcessHandleLocked(token)) {
8312                    updateOomAdjLocked();
8313                } else {
8314                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8315                            + " with no external reference for token: "
8316                            + token + ".");
8317                }
8318            } else {
8319                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8320                        + " with no external references.");
8321            }
8322        }
8323    }
8324
8325    public final void publishContentProviders(IApplicationThread caller,
8326            List<ContentProviderHolder> providers) {
8327        if (providers == null) {
8328            return;
8329        }
8330
8331        enforceNotIsolatedCaller("publishContentProviders");
8332        synchronized (this) {
8333            final ProcessRecord r = getRecordForAppLocked(caller);
8334            if (DEBUG_MU)
8335                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8336            if (r == null) {
8337                throw new SecurityException(
8338                        "Unable to find app for caller " + caller
8339                      + " (pid=" + Binder.getCallingPid()
8340                      + ") when publishing content providers");
8341            }
8342
8343            final long origId = Binder.clearCallingIdentity();
8344
8345            final int N = providers.size();
8346            for (int i=0; i<N; i++) {
8347                ContentProviderHolder src = providers.get(i);
8348                if (src == null || src.info == null || src.provider == null) {
8349                    continue;
8350                }
8351                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8352                if (DEBUG_MU)
8353                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8354                if (dst != null) {
8355                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8356                    mProviderMap.putProviderByClass(comp, dst);
8357                    String names[] = dst.info.authority.split(";");
8358                    for (int j = 0; j < names.length; j++) {
8359                        mProviderMap.putProviderByName(names[j], dst);
8360                    }
8361
8362                    int NL = mLaunchingProviders.size();
8363                    int j;
8364                    for (j=0; j<NL; j++) {
8365                        if (mLaunchingProviders.get(j) == dst) {
8366                            mLaunchingProviders.remove(j);
8367                            j--;
8368                            NL--;
8369                        }
8370                    }
8371                    synchronized (dst) {
8372                        dst.provider = src.provider;
8373                        dst.proc = r;
8374                        dst.notifyAll();
8375                    }
8376                    updateOomAdjLocked(r);
8377                }
8378            }
8379
8380            Binder.restoreCallingIdentity(origId);
8381        }
8382    }
8383
8384    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8385        ContentProviderConnection conn;
8386        try {
8387            conn = (ContentProviderConnection)connection;
8388        } catch (ClassCastException e) {
8389            String msg ="refContentProvider: " + connection
8390                    + " not a ContentProviderConnection";
8391            Slog.w(TAG, msg);
8392            throw new IllegalArgumentException(msg);
8393        }
8394        if (conn == null) {
8395            throw new NullPointerException("connection is null");
8396        }
8397
8398        synchronized (this) {
8399            if (stable > 0) {
8400                conn.numStableIncs += stable;
8401            }
8402            stable = conn.stableCount + stable;
8403            if (stable < 0) {
8404                throw new IllegalStateException("stableCount < 0: " + stable);
8405            }
8406
8407            if (unstable > 0) {
8408                conn.numUnstableIncs += unstable;
8409            }
8410            unstable = conn.unstableCount + unstable;
8411            if (unstable < 0) {
8412                throw new IllegalStateException("unstableCount < 0: " + unstable);
8413            }
8414
8415            if ((stable+unstable) <= 0) {
8416                throw new IllegalStateException("ref counts can't go to zero here: stable="
8417                        + stable + " unstable=" + unstable);
8418            }
8419            conn.stableCount = stable;
8420            conn.unstableCount = unstable;
8421            return !conn.dead;
8422        }
8423    }
8424
8425    public void unstableProviderDied(IBinder connection) {
8426        ContentProviderConnection conn;
8427        try {
8428            conn = (ContentProviderConnection)connection;
8429        } catch (ClassCastException e) {
8430            String msg ="refContentProvider: " + connection
8431                    + " not a ContentProviderConnection";
8432            Slog.w(TAG, msg);
8433            throw new IllegalArgumentException(msg);
8434        }
8435        if (conn == null) {
8436            throw new NullPointerException("connection is null");
8437        }
8438
8439        // Safely retrieve the content provider associated with the connection.
8440        IContentProvider provider;
8441        synchronized (this) {
8442            provider = conn.provider.provider;
8443        }
8444
8445        if (provider == null) {
8446            // Um, yeah, we're way ahead of you.
8447            return;
8448        }
8449
8450        // Make sure the caller is being honest with us.
8451        if (provider.asBinder().pingBinder()) {
8452            // Er, no, still looks good to us.
8453            synchronized (this) {
8454                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8455                        + " says " + conn + " died, but we don't agree");
8456                return;
8457            }
8458        }
8459
8460        // Well look at that!  It's dead!
8461        synchronized (this) {
8462            if (conn.provider.provider != provider) {
8463                // But something changed...  good enough.
8464                return;
8465            }
8466
8467            ProcessRecord proc = conn.provider.proc;
8468            if (proc == null || proc.thread == null) {
8469                // Seems like the process is already cleaned up.
8470                return;
8471            }
8472
8473            // As far as we're concerned, this is just like receiving a
8474            // death notification...  just a bit prematurely.
8475            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8476                    + ") early provider death");
8477            final long ident = Binder.clearCallingIdentity();
8478            try {
8479                appDiedLocked(proc, proc.pid, proc.thread);
8480            } finally {
8481                Binder.restoreCallingIdentity(ident);
8482            }
8483        }
8484    }
8485
8486    @Override
8487    public void appNotRespondingViaProvider(IBinder connection) {
8488        enforceCallingPermission(
8489                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8490
8491        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8492        if (conn == null) {
8493            Slog.w(TAG, "ContentProviderConnection is null");
8494            return;
8495        }
8496
8497        final ProcessRecord host = conn.provider.proc;
8498        if (host == null) {
8499            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8500            return;
8501        }
8502
8503        final long token = Binder.clearCallingIdentity();
8504        try {
8505            appNotResponding(host, null, null, false, "ContentProvider not responding");
8506        } finally {
8507            Binder.restoreCallingIdentity(token);
8508        }
8509    }
8510
8511    public final void installSystemProviders() {
8512        List<ProviderInfo> providers;
8513        synchronized (this) {
8514            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8515            providers = generateApplicationProvidersLocked(app);
8516            if (providers != null) {
8517                for (int i=providers.size()-1; i>=0; i--) {
8518                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8519                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8520                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8521                                + ": not system .apk");
8522                        providers.remove(i);
8523                    }
8524                }
8525            }
8526        }
8527        if (providers != null) {
8528            mSystemThread.installSystemProviders(providers);
8529        }
8530
8531        mCoreSettingsObserver = new CoreSettingsObserver(this);
8532
8533        mUsageStatsService.monitorPackages();
8534    }
8535
8536    /**
8537     * Allows app to retrieve the MIME type of a URI without having permission
8538     * to access its content provider.
8539     *
8540     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8541     *
8542     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8543     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8544     */
8545    public String getProviderMimeType(Uri uri, int userId) {
8546        enforceNotIsolatedCaller("getProviderMimeType");
8547        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8548                userId, false, true, "getProviderMimeType", null);
8549        final String name = uri.getAuthority();
8550        final long ident = Binder.clearCallingIdentity();
8551        ContentProviderHolder holder = null;
8552
8553        try {
8554            holder = getContentProviderExternalUnchecked(name, null, userId);
8555            if (holder != null) {
8556                return holder.provider.getType(uri);
8557            }
8558        } catch (RemoteException e) {
8559            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8560            return null;
8561        } finally {
8562            if (holder != null) {
8563                removeContentProviderExternalUnchecked(name, null, userId);
8564            }
8565            Binder.restoreCallingIdentity(ident);
8566        }
8567
8568        return null;
8569    }
8570
8571    // =========================================================
8572    // GLOBAL MANAGEMENT
8573    // =========================================================
8574
8575    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8576            boolean isolated) {
8577        String proc = customProcess != null ? customProcess : info.processName;
8578        BatteryStatsImpl.Uid.Proc ps = null;
8579        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8580        int uid = info.uid;
8581        if (isolated) {
8582            int userId = UserHandle.getUserId(uid);
8583            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8584            while (true) {
8585                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8586                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8587                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8588                }
8589                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8590                mNextIsolatedProcessUid++;
8591                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8592                    // No process for this uid, use it.
8593                    break;
8594                }
8595                stepsLeft--;
8596                if (stepsLeft <= 0) {
8597                    return null;
8598                }
8599            }
8600        }
8601        return new ProcessRecord(stats, info, proc, uid);
8602    }
8603
8604    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8605            String abiOverride) {
8606        ProcessRecord app;
8607        if (!isolated) {
8608            app = getProcessRecordLocked(info.processName, info.uid, true);
8609        } else {
8610            app = null;
8611        }
8612
8613        if (app == null) {
8614            app = newProcessRecordLocked(info, null, isolated);
8615            mProcessNames.put(info.processName, app.uid, app);
8616            if (isolated) {
8617                mIsolatedProcesses.put(app.uid, app);
8618            }
8619            updateLruProcessLocked(app, false, null);
8620            updateOomAdjLocked();
8621        }
8622
8623        // This package really, really can not be stopped.
8624        try {
8625            AppGlobals.getPackageManager().setPackageStoppedState(
8626                    info.packageName, false, UserHandle.getUserId(app.uid));
8627        } catch (RemoteException e) {
8628        } catch (IllegalArgumentException e) {
8629            Slog.w(TAG, "Failed trying to unstop package "
8630                    + info.packageName + ": " + e);
8631        }
8632
8633        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8634                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8635            app.persistent = true;
8636            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8637        }
8638        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8639            mPersistentStartingProcesses.add(app);
8640            startProcessLocked(app, "added application", app.processName,
8641                    abiOverride);
8642        }
8643
8644        return app;
8645    }
8646
8647    public void unhandledBack() {
8648        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8649                "unhandledBack()");
8650
8651        synchronized(this) {
8652            final long origId = Binder.clearCallingIdentity();
8653            try {
8654                getFocusedStack().unhandledBackLocked();
8655            } finally {
8656                Binder.restoreCallingIdentity(origId);
8657            }
8658        }
8659    }
8660
8661    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8662        enforceNotIsolatedCaller("openContentUri");
8663        final int userId = UserHandle.getCallingUserId();
8664        String name = uri.getAuthority();
8665        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8666        ParcelFileDescriptor pfd = null;
8667        if (cph != null) {
8668            // We record the binder invoker's uid in thread-local storage before
8669            // going to the content provider to open the file.  Later, in the code
8670            // that handles all permissions checks, we look for this uid and use
8671            // that rather than the Activity Manager's own uid.  The effect is that
8672            // we do the check against the caller's permissions even though it looks
8673            // to the content provider like the Activity Manager itself is making
8674            // the request.
8675            sCallerIdentity.set(new Identity(
8676                    Binder.getCallingPid(), Binder.getCallingUid()));
8677            try {
8678                pfd = cph.provider.openFile(null, uri, "r", null);
8679            } catch (FileNotFoundException e) {
8680                // do nothing; pfd will be returned null
8681            } finally {
8682                // Ensure that whatever happens, we clean up the identity state
8683                sCallerIdentity.remove();
8684            }
8685
8686            // We've got the fd now, so we're done with the provider.
8687            removeContentProviderExternalUnchecked(name, null, userId);
8688        } else {
8689            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8690        }
8691        return pfd;
8692    }
8693
8694    // Actually is sleeping or shutting down or whatever else in the future
8695    // is an inactive state.
8696    public boolean isSleepingOrShuttingDown() {
8697        return mSleeping || mShuttingDown;
8698    }
8699
8700    public boolean isSleeping() {
8701        return mSleeping;
8702    }
8703
8704    void goingToSleep() {
8705        synchronized(this) {
8706            mWentToSleep = true;
8707            updateEventDispatchingLocked();
8708            goToSleepIfNeededLocked();
8709        }
8710    }
8711
8712    void finishRunningVoiceLocked() {
8713        if (mRunningVoice) {
8714            mRunningVoice = false;
8715            goToSleepIfNeededLocked();
8716        }
8717    }
8718
8719    void goToSleepIfNeededLocked() {
8720        if (mWentToSleep && !mRunningVoice) {
8721            if (!mSleeping) {
8722                mSleeping = true;
8723                mStackSupervisor.goingToSleepLocked();
8724
8725                // Initialize the wake times of all processes.
8726                checkExcessivePowerUsageLocked(false);
8727                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8728                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8729                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8730            }
8731        }
8732    }
8733
8734    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8735        mTaskPersister.notify(task, flush);
8736    }
8737
8738    @Override
8739    public boolean shutdown(int timeout) {
8740        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8741                != PackageManager.PERMISSION_GRANTED) {
8742            throw new SecurityException("Requires permission "
8743                    + android.Manifest.permission.SHUTDOWN);
8744        }
8745
8746        boolean timedout = false;
8747
8748        synchronized(this) {
8749            mShuttingDown = true;
8750            updateEventDispatchingLocked();
8751            timedout = mStackSupervisor.shutdownLocked(timeout);
8752        }
8753
8754        mAppOpsService.shutdown();
8755        mUsageStatsService.shutdown();
8756        mBatteryStatsService.shutdown();
8757        synchronized (this) {
8758            mProcessStats.shutdownLocked();
8759        }
8760        notifyTaskPersisterLocked(null, true);
8761
8762        return timedout;
8763    }
8764
8765    public final void activitySlept(IBinder token) {
8766        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8767
8768        final long origId = Binder.clearCallingIdentity();
8769
8770        synchronized (this) {
8771            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8772            if (r != null) {
8773                mStackSupervisor.activitySleptLocked(r);
8774            }
8775        }
8776
8777        Binder.restoreCallingIdentity(origId);
8778    }
8779
8780    void logLockScreen(String msg) {
8781        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8782                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8783                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8784                mStackSupervisor.mDismissKeyguardOnNextActivity);
8785    }
8786
8787    private void comeOutOfSleepIfNeededLocked() {
8788        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8789            if (mSleeping) {
8790                mSleeping = false;
8791                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8792            }
8793        }
8794    }
8795
8796    void wakingUp() {
8797        synchronized(this) {
8798            mWentToSleep = false;
8799            updateEventDispatchingLocked();
8800            comeOutOfSleepIfNeededLocked();
8801        }
8802    }
8803
8804    void startRunningVoiceLocked() {
8805        if (!mRunningVoice) {
8806            mRunningVoice = true;
8807            comeOutOfSleepIfNeededLocked();
8808        }
8809    }
8810
8811    private void updateEventDispatchingLocked() {
8812        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8813    }
8814
8815    public void setLockScreenShown(boolean shown) {
8816        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8817                != PackageManager.PERMISSION_GRANTED) {
8818            throw new SecurityException("Requires permission "
8819                    + android.Manifest.permission.DEVICE_POWER);
8820        }
8821
8822        synchronized(this) {
8823            long ident = Binder.clearCallingIdentity();
8824            try {
8825                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8826                mLockScreenShown = shown;
8827                comeOutOfSleepIfNeededLocked();
8828            } finally {
8829                Binder.restoreCallingIdentity(ident);
8830            }
8831        }
8832    }
8833
8834    public void stopAppSwitches() {
8835        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8836                != PackageManager.PERMISSION_GRANTED) {
8837            throw new SecurityException("Requires permission "
8838                    + android.Manifest.permission.STOP_APP_SWITCHES);
8839        }
8840
8841        synchronized(this) {
8842            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8843                    + APP_SWITCH_DELAY_TIME;
8844            mDidAppSwitch = false;
8845            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8846            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8847            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8848        }
8849    }
8850
8851    public void resumeAppSwitches() {
8852        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8853                != PackageManager.PERMISSION_GRANTED) {
8854            throw new SecurityException("Requires permission "
8855                    + android.Manifest.permission.STOP_APP_SWITCHES);
8856        }
8857
8858        synchronized(this) {
8859            // Note that we don't execute any pending app switches... we will
8860            // let those wait until either the timeout, or the next start
8861            // activity request.
8862            mAppSwitchesAllowedTime = 0;
8863        }
8864    }
8865
8866    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8867            String name) {
8868        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8869            return true;
8870        }
8871
8872        final int perm = checkComponentPermission(
8873                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8874                callingUid, -1, true);
8875        if (perm == PackageManager.PERMISSION_GRANTED) {
8876            return true;
8877        }
8878
8879        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8880        return false;
8881    }
8882
8883    public void setDebugApp(String packageName, boolean waitForDebugger,
8884            boolean persistent) {
8885        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8886                "setDebugApp()");
8887
8888        long ident = Binder.clearCallingIdentity();
8889        try {
8890            // Note that this is not really thread safe if there are multiple
8891            // callers into it at the same time, but that's not a situation we
8892            // care about.
8893            if (persistent) {
8894                final ContentResolver resolver = mContext.getContentResolver();
8895                Settings.Global.putString(
8896                    resolver, Settings.Global.DEBUG_APP,
8897                    packageName);
8898                Settings.Global.putInt(
8899                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8900                    waitForDebugger ? 1 : 0);
8901            }
8902
8903            synchronized (this) {
8904                if (!persistent) {
8905                    mOrigDebugApp = mDebugApp;
8906                    mOrigWaitForDebugger = mWaitForDebugger;
8907                }
8908                mDebugApp = packageName;
8909                mWaitForDebugger = waitForDebugger;
8910                mDebugTransient = !persistent;
8911                if (packageName != null) {
8912                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8913                            false, UserHandle.USER_ALL, "set debug app");
8914                }
8915            }
8916        } finally {
8917            Binder.restoreCallingIdentity(ident);
8918        }
8919    }
8920
8921    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8922        synchronized (this) {
8923            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8924            if (!isDebuggable) {
8925                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8926                    throw new SecurityException("Process not debuggable: " + app.packageName);
8927                }
8928            }
8929
8930            mOpenGlTraceApp = processName;
8931        }
8932    }
8933
8934    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8935            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8936        synchronized (this) {
8937            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8938            if (!isDebuggable) {
8939                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8940                    throw new SecurityException("Process not debuggable: " + app.packageName);
8941                }
8942            }
8943            mProfileApp = processName;
8944            mProfileFile = profileFile;
8945            if (mProfileFd != null) {
8946                try {
8947                    mProfileFd.close();
8948                } catch (IOException e) {
8949                }
8950                mProfileFd = null;
8951            }
8952            mProfileFd = profileFd;
8953            mProfileType = 0;
8954            mAutoStopProfiler = autoStopProfiler;
8955        }
8956    }
8957
8958    @Override
8959    public void setAlwaysFinish(boolean enabled) {
8960        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8961                "setAlwaysFinish()");
8962
8963        Settings.Global.putInt(
8964                mContext.getContentResolver(),
8965                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8966
8967        synchronized (this) {
8968            mAlwaysFinishActivities = enabled;
8969        }
8970    }
8971
8972    @Override
8973    public void setActivityController(IActivityController controller) {
8974        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8975                "setActivityController()");
8976        synchronized (this) {
8977            mController = controller;
8978            Watchdog.getInstance().setActivityController(controller);
8979        }
8980    }
8981
8982    @Override
8983    public void setUserIsMonkey(boolean userIsMonkey) {
8984        synchronized (this) {
8985            synchronized (mPidsSelfLocked) {
8986                final int callingPid = Binder.getCallingPid();
8987                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8988                if (precessRecord == null) {
8989                    throw new SecurityException("Unknown process: " + callingPid);
8990                }
8991                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8992                    throw new SecurityException("Only an instrumentation process "
8993                            + "with a UiAutomation can call setUserIsMonkey");
8994                }
8995            }
8996            mUserIsMonkey = userIsMonkey;
8997        }
8998    }
8999
9000    @Override
9001    public boolean isUserAMonkey() {
9002        synchronized (this) {
9003            // If there is a controller also implies the user is a monkey.
9004            return (mUserIsMonkey || mController != null);
9005        }
9006    }
9007
9008    public void requestBugReport() {
9009        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9010        SystemProperties.set("ctl.start", "bugreport");
9011    }
9012
9013    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9014        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9015    }
9016
9017    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9018        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9019            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9020        }
9021        return KEY_DISPATCHING_TIMEOUT;
9022    }
9023
9024    @Override
9025    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9026        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9027                != PackageManager.PERMISSION_GRANTED) {
9028            throw new SecurityException("Requires permission "
9029                    + android.Manifest.permission.FILTER_EVENTS);
9030        }
9031        ProcessRecord proc;
9032        long timeout;
9033        synchronized (this) {
9034            synchronized (mPidsSelfLocked) {
9035                proc = mPidsSelfLocked.get(pid);
9036            }
9037            timeout = getInputDispatchingTimeoutLocked(proc);
9038        }
9039
9040        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9041            return -1;
9042        }
9043
9044        return timeout;
9045    }
9046
9047    /**
9048     * Handle input dispatching timeouts.
9049     * Returns whether input dispatching should be aborted or not.
9050     */
9051    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9052            final ActivityRecord activity, final ActivityRecord parent,
9053            final boolean aboveSystem, String reason) {
9054        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9055                != PackageManager.PERMISSION_GRANTED) {
9056            throw new SecurityException("Requires permission "
9057                    + android.Manifest.permission.FILTER_EVENTS);
9058        }
9059
9060        final String annotation;
9061        if (reason == null) {
9062            annotation = "Input dispatching timed out";
9063        } else {
9064            annotation = "Input dispatching timed out (" + reason + ")";
9065        }
9066
9067        if (proc != null) {
9068            synchronized (this) {
9069                if (proc.debugging) {
9070                    return false;
9071                }
9072
9073                if (mDidDexOpt) {
9074                    // Give more time since we were dexopting.
9075                    mDidDexOpt = false;
9076                    return false;
9077                }
9078
9079                if (proc.instrumentationClass != null) {
9080                    Bundle info = new Bundle();
9081                    info.putString("shortMsg", "keyDispatchingTimedOut");
9082                    info.putString("longMsg", annotation);
9083                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9084                    return true;
9085                }
9086            }
9087            mHandler.post(new Runnable() {
9088                @Override
9089                public void run() {
9090                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9091                }
9092            });
9093        }
9094
9095        return true;
9096    }
9097
9098    public Bundle getAssistContextExtras(int requestType) {
9099        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9100                "getAssistContextExtras()");
9101        PendingAssistExtras pae;
9102        Bundle extras = new Bundle();
9103        synchronized (this) {
9104            ActivityRecord activity = getFocusedStack().mResumedActivity;
9105            if (activity == null) {
9106                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9107                return null;
9108            }
9109            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9110            if (activity.app == null || activity.app.thread == null) {
9111                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9112                return extras;
9113            }
9114            if (activity.app.pid == Binder.getCallingPid()) {
9115                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9116                return extras;
9117            }
9118            pae = new PendingAssistExtras(activity);
9119            try {
9120                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9121                        requestType);
9122                mPendingAssistExtras.add(pae);
9123                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9124            } catch (RemoteException e) {
9125                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9126                return extras;
9127            }
9128        }
9129        synchronized (pae) {
9130            while (!pae.haveResult) {
9131                try {
9132                    pae.wait();
9133                } catch (InterruptedException e) {
9134                }
9135            }
9136            if (pae.result != null) {
9137                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9138            }
9139        }
9140        synchronized (this) {
9141            mPendingAssistExtras.remove(pae);
9142            mHandler.removeCallbacks(pae);
9143        }
9144        return extras;
9145    }
9146
9147    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9148        PendingAssistExtras pae = (PendingAssistExtras)token;
9149        synchronized (pae) {
9150            pae.result = extras;
9151            pae.haveResult = true;
9152            pae.notifyAll();
9153        }
9154    }
9155
9156    public void registerProcessObserver(IProcessObserver observer) {
9157        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9158                "registerProcessObserver()");
9159        synchronized (this) {
9160            mProcessObservers.register(observer);
9161        }
9162    }
9163
9164    @Override
9165    public void unregisterProcessObserver(IProcessObserver observer) {
9166        synchronized (this) {
9167            mProcessObservers.unregister(observer);
9168        }
9169    }
9170
9171    @Override
9172    public boolean convertFromTranslucent(IBinder token) {
9173        final long origId = Binder.clearCallingIdentity();
9174        try {
9175            synchronized (this) {
9176                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9177                if (r == null) {
9178                    return false;
9179                }
9180                if (r.changeWindowTranslucency(true)) {
9181                    mWindowManager.setAppFullscreen(token, true);
9182                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9183                    return true;
9184                }
9185                return false;
9186            }
9187        } finally {
9188            Binder.restoreCallingIdentity(origId);
9189        }
9190    }
9191
9192    @Override
9193    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9194        final long origId = Binder.clearCallingIdentity();
9195        try {
9196            synchronized (this) {
9197                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9198                if (r == null) {
9199                    return false;
9200                }
9201                if (r.changeWindowTranslucency(false)) {
9202                    r.task.stack.convertToTranslucent(r, options);
9203                    mWindowManager.setAppFullscreen(token, false);
9204                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9205                    return true;
9206                }
9207                return false;
9208            }
9209        } finally {
9210            Binder.restoreCallingIdentity(origId);
9211        }
9212    }
9213
9214    @Override
9215    public ActivityOptions getActivityOptions(IBinder token) {
9216        final long origId = Binder.clearCallingIdentity();
9217        try {
9218            synchronized (this) {
9219                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9220                if (r != null) {
9221                    final ActivityOptions activityOptions = r.pendingOptions;
9222                    r.pendingOptions = null;
9223                    return activityOptions;
9224                }
9225                return null;
9226            }
9227        } finally {
9228            Binder.restoreCallingIdentity(origId);
9229        }
9230    }
9231
9232    @Override
9233    public void setImmersive(IBinder token, boolean immersive) {
9234        synchronized(this) {
9235            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9236            if (r == null) {
9237                throw new IllegalArgumentException();
9238            }
9239            r.immersive = immersive;
9240
9241            // update associated state if we're frontmost
9242            if (r == mFocusedActivity) {
9243                if (DEBUG_IMMERSIVE) {
9244                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9245                }
9246                applyUpdateLockStateLocked(r);
9247            }
9248        }
9249    }
9250
9251    @Override
9252    public boolean isImmersive(IBinder token) {
9253        synchronized (this) {
9254            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9255            if (r == null) {
9256                throw new IllegalArgumentException();
9257            }
9258            return r.immersive;
9259        }
9260    }
9261
9262    public boolean isTopActivityImmersive() {
9263        enforceNotIsolatedCaller("startActivity");
9264        synchronized (this) {
9265            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9266            return (r != null) ? r.immersive : false;
9267        }
9268    }
9269
9270    public final void enterSafeMode() {
9271        synchronized(this) {
9272            // It only makes sense to do this before the system is ready
9273            // and started launching other packages.
9274            if (!mSystemReady) {
9275                try {
9276                    AppGlobals.getPackageManager().enterSafeMode();
9277                } catch (RemoteException e) {
9278                }
9279            }
9280
9281            mSafeMode = true;
9282        }
9283    }
9284
9285    public final void showSafeModeOverlay() {
9286        View v = LayoutInflater.from(mContext).inflate(
9287                com.android.internal.R.layout.safe_mode, null);
9288        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9289        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9290        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9291        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9292        lp.gravity = Gravity.BOTTOM | Gravity.START;
9293        lp.format = v.getBackground().getOpacity();
9294        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9295                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9296        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9297        ((WindowManager)mContext.getSystemService(
9298                Context.WINDOW_SERVICE)).addView(v, lp);
9299    }
9300
9301    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9302        if (!(sender instanceof PendingIntentRecord)) {
9303            return;
9304        }
9305        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9306        synchronized (stats) {
9307            if (mBatteryStatsService.isOnBattery()) {
9308                mBatteryStatsService.enforceCallingPermission();
9309                PendingIntentRecord rec = (PendingIntentRecord)sender;
9310                int MY_UID = Binder.getCallingUid();
9311                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9312                BatteryStatsImpl.Uid.Pkg pkg =
9313                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9314                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9315                pkg.incWakeupsLocked();
9316            }
9317        }
9318    }
9319
9320    public boolean killPids(int[] pids, String pReason, boolean secure) {
9321        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9322            throw new SecurityException("killPids only available to the system");
9323        }
9324        String reason = (pReason == null) ? "Unknown" : pReason;
9325        // XXX Note: don't acquire main activity lock here, because the window
9326        // manager calls in with its locks held.
9327
9328        boolean killed = false;
9329        synchronized (mPidsSelfLocked) {
9330            int[] types = new int[pids.length];
9331            int worstType = 0;
9332            for (int i=0; i<pids.length; i++) {
9333                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9334                if (proc != null) {
9335                    int type = proc.setAdj;
9336                    types[i] = type;
9337                    if (type > worstType) {
9338                        worstType = type;
9339                    }
9340                }
9341            }
9342
9343            // If the worst oom_adj is somewhere in the cached proc LRU range,
9344            // then constrain it so we will kill all cached procs.
9345            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9346                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9347                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9348            }
9349
9350            // If this is not a secure call, don't let it kill processes that
9351            // are important.
9352            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9353                worstType = ProcessList.SERVICE_ADJ;
9354            }
9355
9356            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9357            for (int i=0; i<pids.length; i++) {
9358                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9359                if (proc == null) {
9360                    continue;
9361                }
9362                int adj = proc.setAdj;
9363                if (adj >= worstType && !proc.killedByAm) {
9364                    killUnneededProcessLocked(proc, reason);
9365                    killed = true;
9366                }
9367            }
9368        }
9369        return killed;
9370    }
9371
9372    @Override
9373    public void killUid(int uid, String reason) {
9374        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9375            throw new SecurityException("killUid only available to the system");
9376        }
9377        synchronized (this) {
9378            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9379                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9380                    reason != null ? reason : "kill uid");
9381        }
9382    }
9383
9384    @Override
9385    public boolean killProcessesBelowForeground(String reason) {
9386        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9387            throw new SecurityException("killProcessesBelowForeground() only available to system");
9388        }
9389
9390        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9391    }
9392
9393    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9394        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9395            throw new SecurityException("killProcessesBelowAdj() only available to system");
9396        }
9397
9398        boolean killed = false;
9399        synchronized (mPidsSelfLocked) {
9400            final int size = mPidsSelfLocked.size();
9401            for (int i = 0; i < size; i++) {
9402                final int pid = mPidsSelfLocked.keyAt(i);
9403                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9404                if (proc == null) continue;
9405
9406                final int adj = proc.setAdj;
9407                if (adj > belowAdj && !proc.killedByAm) {
9408                    killUnneededProcessLocked(proc, reason);
9409                    killed = true;
9410                }
9411            }
9412        }
9413        return killed;
9414    }
9415
9416    @Override
9417    public void hang(final IBinder who, boolean allowRestart) {
9418        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9419                != PackageManager.PERMISSION_GRANTED) {
9420            throw new SecurityException("Requires permission "
9421                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9422        }
9423
9424        final IBinder.DeathRecipient death = new DeathRecipient() {
9425            @Override
9426            public void binderDied() {
9427                synchronized (this) {
9428                    notifyAll();
9429                }
9430            }
9431        };
9432
9433        try {
9434            who.linkToDeath(death, 0);
9435        } catch (RemoteException e) {
9436            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9437            return;
9438        }
9439
9440        synchronized (this) {
9441            Watchdog.getInstance().setAllowRestart(allowRestart);
9442            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9443            synchronized (death) {
9444                while (who.isBinderAlive()) {
9445                    try {
9446                        death.wait();
9447                    } catch (InterruptedException e) {
9448                    }
9449                }
9450            }
9451            Watchdog.getInstance().setAllowRestart(true);
9452        }
9453    }
9454
9455    @Override
9456    public void restart() {
9457        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9458                != PackageManager.PERMISSION_GRANTED) {
9459            throw new SecurityException("Requires permission "
9460                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9461        }
9462
9463        Log.i(TAG, "Sending shutdown broadcast...");
9464
9465        BroadcastReceiver br = new BroadcastReceiver() {
9466            @Override public void onReceive(Context context, Intent intent) {
9467                // Now the broadcast is done, finish up the low-level shutdown.
9468                Log.i(TAG, "Shutting down activity manager...");
9469                shutdown(10000);
9470                Log.i(TAG, "Shutdown complete, restarting!");
9471                Process.killProcess(Process.myPid());
9472                System.exit(10);
9473            }
9474        };
9475
9476        // First send the high-level shut down broadcast.
9477        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9478        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9479        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9480        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9481        mContext.sendOrderedBroadcastAsUser(intent,
9482                UserHandle.ALL, null, br, mHandler, 0, null, null);
9483        */
9484        br.onReceive(mContext, intent);
9485    }
9486
9487    private long getLowRamTimeSinceIdle(long now) {
9488        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9489    }
9490
9491    @Override
9492    public void performIdleMaintenance() {
9493        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9494                != PackageManager.PERMISSION_GRANTED) {
9495            throw new SecurityException("Requires permission "
9496                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9497        }
9498
9499        synchronized (this) {
9500            final long now = SystemClock.uptimeMillis();
9501            final long timeSinceLastIdle = now - mLastIdleTime;
9502            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9503            mLastIdleTime = now;
9504            mLowRamTimeSinceLastIdle = 0;
9505            if (mLowRamStartTime != 0) {
9506                mLowRamStartTime = now;
9507            }
9508
9509            StringBuilder sb = new StringBuilder(128);
9510            sb.append("Idle maintenance over ");
9511            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9512            sb.append(" low RAM for ");
9513            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9514            Slog.i(TAG, sb.toString());
9515
9516            // If at least 1/3 of our time since the last idle period has been spent
9517            // with RAM low, then we want to kill processes.
9518            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9519
9520            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9521                ProcessRecord proc = mLruProcesses.get(i);
9522                if (proc.notCachedSinceIdle) {
9523                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9524                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9525                        if (doKilling && proc.initialIdlePss != 0
9526                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9527                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9528                                    + " from " + proc.initialIdlePss + ")");
9529                        }
9530                    }
9531                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9532                    proc.notCachedSinceIdle = true;
9533                    proc.initialIdlePss = 0;
9534                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9535                            isSleeping(), now);
9536                }
9537            }
9538
9539            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9540            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9541        }
9542    }
9543
9544    private void retrieveSettings() {
9545        final ContentResolver resolver = mContext.getContentResolver();
9546        String debugApp = Settings.Global.getString(
9547            resolver, Settings.Global.DEBUG_APP);
9548        boolean waitForDebugger = Settings.Global.getInt(
9549            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9550        boolean alwaysFinishActivities = Settings.Global.getInt(
9551            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9552        boolean forceRtl = Settings.Global.getInt(
9553                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9554        // Transfer any global setting for forcing RTL layout, into a System Property
9555        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9556
9557        Configuration configuration = new Configuration();
9558        Settings.System.getConfiguration(resolver, configuration);
9559        if (forceRtl) {
9560            // This will take care of setting the correct layout direction flags
9561            configuration.setLayoutDirection(configuration.locale);
9562        }
9563
9564        synchronized (this) {
9565            mDebugApp = mOrigDebugApp = debugApp;
9566            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9567            mAlwaysFinishActivities = alwaysFinishActivities;
9568            // This happens before any activities are started, so we can
9569            // change mConfiguration in-place.
9570            updateConfigurationLocked(configuration, null, false, true);
9571            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9572        }
9573    }
9574
9575    public boolean testIsSystemReady() {
9576        // no need to synchronize(this) just to read & return the value
9577        return mSystemReady;
9578    }
9579
9580    private static File getCalledPreBootReceiversFile() {
9581        File dataDir = Environment.getDataDirectory();
9582        File systemDir = new File(dataDir, "system");
9583        File fname = new File(systemDir, "called_pre_boots.dat");
9584        return fname;
9585    }
9586
9587    static final int LAST_DONE_VERSION = 10000;
9588
9589    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9590        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9591        File file = getCalledPreBootReceiversFile();
9592        FileInputStream fis = null;
9593        try {
9594            fis = new FileInputStream(file);
9595            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9596            int fvers = dis.readInt();
9597            if (fvers == LAST_DONE_VERSION) {
9598                String vers = dis.readUTF();
9599                String codename = dis.readUTF();
9600                String build = dis.readUTF();
9601                if (android.os.Build.VERSION.RELEASE.equals(vers)
9602                        && android.os.Build.VERSION.CODENAME.equals(codename)
9603                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9604                    int num = dis.readInt();
9605                    while (num > 0) {
9606                        num--;
9607                        String pkg = dis.readUTF();
9608                        String cls = dis.readUTF();
9609                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9610                    }
9611                }
9612            }
9613        } catch (FileNotFoundException e) {
9614        } catch (IOException e) {
9615            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9616        } finally {
9617            if (fis != null) {
9618                try {
9619                    fis.close();
9620                } catch (IOException e) {
9621                }
9622            }
9623        }
9624        return lastDoneReceivers;
9625    }
9626
9627    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9628        File file = getCalledPreBootReceiversFile();
9629        FileOutputStream fos = null;
9630        DataOutputStream dos = null;
9631        try {
9632            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9633            fos = new FileOutputStream(file);
9634            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9635            dos.writeInt(LAST_DONE_VERSION);
9636            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9637            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9638            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9639            dos.writeInt(list.size());
9640            for (int i=0; i<list.size(); i++) {
9641                dos.writeUTF(list.get(i).getPackageName());
9642                dos.writeUTF(list.get(i).getClassName());
9643            }
9644        } catch (IOException e) {
9645            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9646            file.delete();
9647        } finally {
9648            FileUtils.sync(fos);
9649            if (dos != null) {
9650                try {
9651                    dos.close();
9652                } catch (IOException e) {
9653                    // TODO Auto-generated catch block
9654                    e.printStackTrace();
9655                }
9656            }
9657        }
9658    }
9659
9660    public void systemReady(final Runnable goingCallback) {
9661        synchronized(this) {
9662            if (mSystemReady) {
9663                if (goingCallback != null) goingCallback.run();
9664                return;
9665            }
9666
9667            if (mRecentTasks == null) {
9668                mRecentTasks = mTaskPersister.restoreTasksLocked();
9669                if (!mRecentTasks.isEmpty()) {
9670                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9671                }
9672                mTaskPersister.startPersisting();
9673            }
9674
9675            // Check to see if there are any update receivers to run.
9676            if (!mDidUpdate) {
9677                if (mWaitingUpdate) {
9678                    return;
9679                }
9680                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9681                List<ResolveInfo> ris = null;
9682                try {
9683                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9684                            intent, null, 0, 0);
9685                } catch (RemoteException e) {
9686                }
9687                if (ris != null) {
9688                    for (int i=ris.size()-1; i>=0; i--) {
9689                        if ((ris.get(i).activityInfo.applicationInfo.flags
9690                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9691                            ris.remove(i);
9692                        }
9693                    }
9694                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9695
9696                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9697
9698                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9699                    for (int i=0; i<ris.size(); i++) {
9700                        ActivityInfo ai = ris.get(i).activityInfo;
9701                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9702                        if (lastDoneReceivers.contains(comp)) {
9703                            // We already did the pre boot receiver for this app with the current
9704                            // platform version, so don't do it again...
9705                            ris.remove(i);
9706                            i--;
9707                            // ...however, do keep it as one that has been done, so we don't
9708                            // forget about it when rewriting the file of last done receivers.
9709                            doneReceivers.add(comp);
9710                        }
9711                    }
9712
9713                    final int[] users = getUsersLocked();
9714                    for (int i=0; i<ris.size(); i++) {
9715                        ActivityInfo ai = ris.get(i).activityInfo;
9716                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9717                        doneReceivers.add(comp);
9718                        intent.setComponent(comp);
9719                        for (int j=0; j<users.length; j++) {
9720                            IIntentReceiver finisher = null;
9721                            if (i == ris.size()-1 && j == users.length-1) {
9722                                finisher = new IIntentReceiver.Stub() {
9723                                    public void performReceive(Intent intent, int resultCode,
9724                                            String data, Bundle extras, boolean ordered,
9725                                            boolean sticky, int sendingUser) {
9726                                        // The raw IIntentReceiver interface is called
9727                                        // with the AM lock held, so redispatch to
9728                                        // execute our code without the lock.
9729                                        mHandler.post(new Runnable() {
9730                                            public void run() {
9731                                                synchronized (ActivityManagerService.this) {
9732                                                    mDidUpdate = true;
9733                                                }
9734                                                writeLastDonePreBootReceivers(doneReceivers);
9735                                                showBootMessage(mContext.getText(
9736                                                        R.string.android_upgrading_complete),
9737                                                        false);
9738                                                systemReady(goingCallback);
9739                                            }
9740                                        });
9741                                    }
9742                                };
9743                            }
9744                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9745                                    + " for user " + users[j]);
9746                            broadcastIntentLocked(null, null, intent, null, finisher,
9747                                    0, null, null, null, AppOpsManager.OP_NONE,
9748                                    true, false, MY_PID, Process.SYSTEM_UID,
9749                                    users[j]);
9750                            if (finisher != null) {
9751                                mWaitingUpdate = true;
9752                            }
9753                        }
9754                    }
9755                }
9756                if (mWaitingUpdate) {
9757                    return;
9758                }
9759                mDidUpdate = true;
9760            }
9761
9762            mAppOpsService.systemReady();
9763            mUsageStatsService.systemReady();
9764            mSystemReady = true;
9765        }
9766
9767        ArrayList<ProcessRecord> procsToKill = null;
9768        synchronized(mPidsSelfLocked) {
9769            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9770                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9771                if (!isAllowedWhileBooting(proc.info)){
9772                    if (procsToKill == null) {
9773                        procsToKill = new ArrayList<ProcessRecord>();
9774                    }
9775                    procsToKill.add(proc);
9776                }
9777            }
9778        }
9779
9780        synchronized(this) {
9781            if (procsToKill != null) {
9782                for (int i=procsToKill.size()-1; i>=0; i--) {
9783                    ProcessRecord proc = procsToKill.get(i);
9784                    Slog.i(TAG, "Removing system update proc: " + proc);
9785                    removeProcessLocked(proc, true, false, "system update done");
9786                }
9787            }
9788
9789            // Now that we have cleaned up any update processes, we
9790            // are ready to start launching real processes and know that
9791            // we won't trample on them any more.
9792            mProcessesReady = true;
9793        }
9794
9795        Slog.i(TAG, "System now ready");
9796        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9797            SystemClock.uptimeMillis());
9798
9799        synchronized(this) {
9800            // Make sure we have no pre-ready processes sitting around.
9801
9802            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9803                ResolveInfo ri = mContext.getPackageManager()
9804                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9805                                STOCK_PM_FLAGS);
9806                CharSequence errorMsg = null;
9807                if (ri != null) {
9808                    ActivityInfo ai = ri.activityInfo;
9809                    ApplicationInfo app = ai.applicationInfo;
9810                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9811                        mTopAction = Intent.ACTION_FACTORY_TEST;
9812                        mTopData = null;
9813                        mTopComponent = new ComponentName(app.packageName,
9814                                ai.name);
9815                    } else {
9816                        errorMsg = mContext.getResources().getText(
9817                                com.android.internal.R.string.factorytest_not_system);
9818                    }
9819                } else {
9820                    errorMsg = mContext.getResources().getText(
9821                            com.android.internal.R.string.factorytest_no_action);
9822                }
9823                if (errorMsg != null) {
9824                    mTopAction = null;
9825                    mTopData = null;
9826                    mTopComponent = null;
9827                    Message msg = Message.obtain();
9828                    msg.what = SHOW_FACTORY_ERROR_MSG;
9829                    msg.getData().putCharSequence("msg", errorMsg);
9830                    mHandler.sendMessage(msg);
9831                }
9832            }
9833        }
9834
9835        retrieveSettings();
9836
9837        synchronized (this) {
9838            readGrantedUriPermissionsLocked();
9839        }
9840
9841        if (goingCallback != null) goingCallback.run();
9842
9843        mSystemServiceManager.startUser(mCurrentUserId);
9844
9845        synchronized (this) {
9846            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9847                try {
9848                    List apps = AppGlobals.getPackageManager().
9849                        getPersistentApplications(STOCK_PM_FLAGS);
9850                    if (apps != null) {
9851                        int N = apps.size();
9852                        int i;
9853                        for (i=0; i<N; i++) {
9854                            ApplicationInfo info
9855                                = (ApplicationInfo)apps.get(i);
9856                            if (info != null &&
9857                                    !info.packageName.equals("android")) {
9858                                addAppLocked(info, false, null /* ABI override */);
9859                            }
9860                        }
9861                    }
9862                } catch (RemoteException ex) {
9863                    // pm is in same process, this will never happen.
9864                }
9865            }
9866
9867            // Start up initial activity.
9868            mBooting = true;
9869
9870            try {
9871                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9872                    Message msg = Message.obtain();
9873                    msg.what = SHOW_UID_ERROR_MSG;
9874                    mHandler.sendMessage(msg);
9875                }
9876            } catch (RemoteException e) {
9877            }
9878
9879            long ident = Binder.clearCallingIdentity();
9880            try {
9881                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9882                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9883                        | Intent.FLAG_RECEIVER_FOREGROUND);
9884                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9885                broadcastIntentLocked(null, null, intent,
9886                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9887                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9888                intent = new Intent(Intent.ACTION_USER_STARTING);
9889                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9890                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9891                broadcastIntentLocked(null, null, intent,
9892                        null, new IIntentReceiver.Stub() {
9893                            @Override
9894                            public void performReceive(Intent intent, int resultCode, String data,
9895                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9896                                    throws RemoteException {
9897                            }
9898                        }, 0, null, null,
9899                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9900                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9901            } catch (Throwable t) {
9902                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9903            } finally {
9904                Binder.restoreCallingIdentity(ident);
9905            }
9906            mStackSupervisor.resumeTopActivitiesLocked();
9907            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9908        }
9909    }
9910
9911    private boolean makeAppCrashingLocked(ProcessRecord app,
9912            String shortMsg, String longMsg, String stackTrace) {
9913        app.crashing = true;
9914        app.crashingReport = generateProcessError(app,
9915                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9916        startAppProblemLocked(app);
9917        app.stopFreezingAllLocked();
9918        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9919    }
9920
9921    private void makeAppNotRespondingLocked(ProcessRecord app,
9922            String activity, String shortMsg, String longMsg) {
9923        app.notResponding = true;
9924        app.notRespondingReport = generateProcessError(app,
9925                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9926                activity, shortMsg, longMsg, null);
9927        startAppProblemLocked(app);
9928        app.stopFreezingAllLocked();
9929    }
9930
9931    /**
9932     * Generate a process error record, suitable for attachment to a ProcessRecord.
9933     *
9934     * @param app The ProcessRecord in which the error occurred.
9935     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9936     *                      ActivityManager.AppErrorStateInfo
9937     * @param activity The activity associated with the crash, if known.
9938     * @param shortMsg Short message describing the crash.
9939     * @param longMsg Long message describing the crash.
9940     * @param stackTrace Full crash stack trace, may be null.
9941     *
9942     * @return Returns a fully-formed AppErrorStateInfo record.
9943     */
9944    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9945            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9946        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9947
9948        report.condition = condition;
9949        report.processName = app.processName;
9950        report.pid = app.pid;
9951        report.uid = app.info.uid;
9952        report.tag = activity;
9953        report.shortMsg = shortMsg;
9954        report.longMsg = longMsg;
9955        report.stackTrace = stackTrace;
9956
9957        return report;
9958    }
9959
9960    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9961        synchronized (this) {
9962            app.crashing = false;
9963            app.crashingReport = null;
9964            app.notResponding = false;
9965            app.notRespondingReport = null;
9966            if (app.anrDialog == fromDialog) {
9967                app.anrDialog = null;
9968            }
9969            if (app.waitDialog == fromDialog) {
9970                app.waitDialog = null;
9971            }
9972            if (app.pid > 0 && app.pid != MY_PID) {
9973                handleAppCrashLocked(app, null, null, null);
9974                killUnneededProcessLocked(app, "user request after error");
9975            }
9976        }
9977    }
9978
9979    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9980            String stackTrace) {
9981        long now = SystemClock.uptimeMillis();
9982
9983        Long crashTime;
9984        if (!app.isolated) {
9985            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9986        } else {
9987            crashTime = null;
9988        }
9989        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9990            // This process loses!
9991            Slog.w(TAG, "Process " + app.info.processName
9992                    + " has crashed too many times: killing!");
9993            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9994                    app.userId, app.info.processName, app.uid);
9995            mStackSupervisor.handleAppCrashLocked(app);
9996            if (!app.persistent) {
9997                // We don't want to start this process again until the user
9998                // explicitly does so...  but for persistent process, we really
9999                // need to keep it running.  If a persistent process is actually
10000                // repeatedly crashing, then badness for everyone.
10001                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10002                        app.info.processName);
10003                if (!app.isolated) {
10004                    // XXX We don't have a way to mark isolated processes
10005                    // as bad, since they don't have a peristent identity.
10006                    mBadProcesses.put(app.info.processName, app.uid,
10007                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10008                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10009                }
10010                app.bad = true;
10011                app.removed = true;
10012                // Don't let services in this process be restarted and potentially
10013                // annoy the user repeatedly.  Unless it is persistent, since those
10014                // processes run critical code.
10015                removeProcessLocked(app, false, false, "crash");
10016                mStackSupervisor.resumeTopActivitiesLocked();
10017                return false;
10018            }
10019            mStackSupervisor.resumeTopActivitiesLocked();
10020        } else {
10021            mStackSupervisor.finishTopRunningActivityLocked(app);
10022        }
10023
10024        // Bump up the crash count of any services currently running in the proc.
10025        for (int i=app.services.size()-1; i>=0; i--) {
10026            // Any services running in the application need to be placed
10027            // back in the pending list.
10028            ServiceRecord sr = app.services.valueAt(i);
10029            sr.crashCount++;
10030        }
10031
10032        // If the crashing process is what we consider to be the "home process" and it has been
10033        // replaced by a third-party app, clear the package preferred activities from packages
10034        // with a home activity running in the process to prevent a repeatedly crashing app
10035        // from blocking the user to manually clear the list.
10036        final ArrayList<ActivityRecord> activities = app.activities;
10037        if (app == mHomeProcess && activities.size() > 0
10038                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10039            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10040                final ActivityRecord r = activities.get(activityNdx);
10041                if (r.isHomeActivity()) {
10042                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10043                    try {
10044                        ActivityThread.getPackageManager()
10045                                .clearPackagePreferredActivities(r.packageName);
10046                    } catch (RemoteException c) {
10047                        // pm is in same process, this will never happen.
10048                    }
10049                }
10050            }
10051        }
10052
10053        if (!app.isolated) {
10054            // XXX Can't keep track of crash times for isolated processes,
10055            // because they don't have a perisistent identity.
10056            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10057        }
10058
10059        return true;
10060    }
10061
10062    void startAppProblemLocked(ProcessRecord app) {
10063        if (app.userId == mCurrentUserId) {
10064            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10065                    mContext, app.info.packageName, app.info.flags);
10066        } else {
10067            // If this app is not running under the current user, then we
10068            // can't give it a report button because that would require
10069            // launching the report UI under a different user.
10070            app.errorReportReceiver = null;
10071        }
10072        skipCurrentReceiverLocked(app);
10073    }
10074
10075    void skipCurrentReceiverLocked(ProcessRecord app) {
10076        for (BroadcastQueue queue : mBroadcastQueues) {
10077            queue.skipCurrentReceiverLocked(app);
10078        }
10079    }
10080
10081    /**
10082     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10083     * The application process will exit immediately after this call returns.
10084     * @param app object of the crashing app, null for the system server
10085     * @param crashInfo describing the exception
10086     */
10087    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10088        ProcessRecord r = findAppProcess(app, "Crash");
10089        final String processName = app == null ? "system_server"
10090                : (r == null ? "unknown" : r.processName);
10091
10092        handleApplicationCrashInner("crash", r, processName, crashInfo);
10093    }
10094
10095    /* Native crash reporting uses this inner version because it needs to be somewhat
10096     * decoupled from the AM-managed cleanup lifecycle
10097     */
10098    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10099            ApplicationErrorReport.CrashInfo crashInfo) {
10100        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10101                UserHandle.getUserId(Binder.getCallingUid()), processName,
10102                r == null ? -1 : r.info.flags,
10103                crashInfo.exceptionClassName,
10104                crashInfo.exceptionMessage,
10105                crashInfo.throwFileName,
10106                crashInfo.throwLineNumber);
10107
10108        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10109
10110        crashApplication(r, crashInfo);
10111    }
10112
10113    public void handleApplicationStrictModeViolation(
10114            IBinder app,
10115            int violationMask,
10116            StrictMode.ViolationInfo info) {
10117        ProcessRecord r = findAppProcess(app, "StrictMode");
10118        if (r == null) {
10119            return;
10120        }
10121
10122        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10123            Integer stackFingerprint = info.hashCode();
10124            boolean logIt = true;
10125            synchronized (mAlreadyLoggedViolatedStacks) {
10126                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10127                    logIt = false;
10128                    // TODO: sub-sample into EventLog for these, with
10129                    // the info.durationMillis?  Then we'd get
10130                    // the relative pain numbers, without logging all
10131                    // the stack traces repeatedly.  We'd want to do
10132                    // likewise in the client code, which also does
10133                    // dup suppression, before the Binder call.
10134                } else {
10135                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10136                        mAlreadyLoggedViolatedStacks.clear();
10137                    }
10138                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10139                }
10140            }
10141            if (logIt) {
10142                logStrictModeViolationToDropBox(r, info);
10143            }
10144        }
10145
10146        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10147            AppErrorResult result = new AppErrorResult();
10148            synchronized (this) {
10149                final long origId = Binder.clearCallingIdentity();
10150
10151                Message msg = Message.obtain();
10152                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10153                HashMap<String, Object> data = new HashMap<String, Object>();
10154                data.put("result", result);
10155                data.put("app", r);
10156                data.put("violationMask", violationMask);
10157                data.put("info", info);
10158                msg.obj = data;
10159                mHandler.sendMessage(msg);
10160
10161                Binder.restoreCallingIdentity(origId);
10162            }
10163            int res = result.get();
10164            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10165        }
10166    }
10167
10168    // Depending on the policy in effect, there could be a bunch of
10169    // these in quick succession so we try to batch these together to
10170    // minimize disk writes, number of dropbox entries, and maximize
10171    // compression, by having more fewer, larger records.
10172    private void logStrictModeViolationToDropBox(
10173            ProcessRecord process,
10174            StrictMode.ViolationInfo info) {
10175        if (info == null) {
10176            return;
10177        }
10178        final boolean isSystemApp = process == null ||
10179                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10180                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10181        final String processName = process == null ? "unknown" : process.processName;
10182        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10183        final DropBoxManager dbox = (DropBoxManager)
10184                mContext.getSystemService(Context.DROPBOX_SERVICE);
10185
10186        // Exit early if the dropbox isn't configured to accept this report type.
10187        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10188
10189        boolean bufferWasEmpty;
10190        boolean needsFlush;
10191        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10192        synchronized (sb) {
10193            bufferWasEmpty = sb.length() == 0;
10194            appendDropBoxProcessHeaders(process, processName, sb);
10195            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10196            sb.append("System-App: ").append(isSystemApp).append("\n");
10197            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10198            if (info.violationNumThisLoop != 0) {
10199                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10200            }
10201            if (info.numAnimationsRunning != 0) {
10202                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10203            }
10204            if (info.broadcastIntentAction != null) {
10205                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10206            }
10207            if (info.durationMillis != -1) {
10208                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10209            }
10210            if (info.numInstances != -1) {
10211                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10212            }
10213            if (info.tags != null) {
10214                for (String tag : info.tags) {
10215                    sb.append("Span-Tag: ").append(tag).append("\n");
10216                }
10217            }
10218            sb.append("\n");
10219            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10220                sb.append(info.crashInfo.stackTrace);
10221            }
10222            sb.append("\n");
10223
10224            // Only buffer up to ~64k.  Various logging bits truncate
10225            // things at 128k.
10226            needsFlush = (sb.length() > 64 * 1024);
10227        }
10228
10229        // Flush immediately if the buffer's grown too large, or this
10230        // is a non-system app.  Non-system apps are isolated with a
10231        // different tag & policy and not batched.
10232        //
10233        // Batching is useful during internal testing with
10234        // StrictMode settings turned up high.  Without batching,
10235        // thousands of separate files could be created on boot.
10236        if (!isSystemApp || needsFlush) {
10237            new Thread("Error dump: " + dropboxTag) {
10238                @Override
10239                public void run() {
10240                    String report;
10241                    synchronized (sb) {
10242                        report = sb.toString();
10243                        sb.delete(0, sb.length());
10244                        sb.trimToSize();
10245                    }
10246                    if (report.length() != 0) {
10247                        dbox.addText(dropboxTag, report);
10248                    }
10249                }
10250            }.start();
10251            return;
10252        }
10253
10254        // System app batching:
10255        if (!bufferWasEmpty) {
10256            // An existing dropbox-writing thread is outstanding, so
10257            // we don't need to start it up.  The existing thread will
10258            // catch the buffer appends we just did.
10259            return;
10260        }
10261
10262        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10263        // (After this point, we shouldn't access AMS internal data structures.)
10264        new Thread("Error dump: " + dropboxTag) {
10265            @Override
10266            public void run() {
10267                // 5 second sleep to let stacks arrive and be batched together
10268                try {
10269                    Thread.sleep(5000);  // 5 seconds
10270                } catch (InterruptedException e) {}
10271
10272                String errorReport;
10273                synchronized (mStrictModeBuffer) {
10274                    errorReport = mStrictModeBuffer.toString();
10275                    if (errorReport.length() == 0) {
10276                        return;
10277                    }
10278                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10279                    mStrictModeBuffer.trimToSize();
10280                }
10281                dbox.addText(dropboxTag, errorReport);
10282            }
10283        }.start();
10284    }
10285
10286    /**
10287     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10288     * @param app object of the crashing app, null for the system server
10289     * @param tag reported by the caller
10290     * @param crashInfo describing the context of the error
10291     * @return true if the process should exit immediately (WTF is fatal)
10292     */
10293    public boolean handleApplicationWtf(IBinder app, String tag,
10294            ApplicationErrorReport.CrashInfo crashInfo) {
10295        ProcessRecord r = findAppProcess(app, "WTF");
10296        final String processName = app == null ? "system_server"
10297                : (r == null ? "unknown" : r.processName);
10298
10299        EventLog.writeEvent(EventLogTags.AM_WTF,
10300                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10301                processName,
10302                r == null ? -1 : r.info.flags,
10303                tag, crashInfo.exceptionMessage);
10304
10305        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10306
10307        if (r != null && r.pid != Process.myPid() &&
10308                Settings.Global.getInt(mContext.getContentResolver(),
10309                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10310            crashApplication(r, crashInfo);
10311            return true;
10312        } else {
10313            return false;
10314        }
10315    }
10316
10317    /**
10318     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10319     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10320     */
10321    private ProcessRecord findAppProcess(IBinder app, String reason) {
10322        if (app == null) {
10323            return null;
10324        }
10325
10326        synchronized (this) {
10327            final int NP = mProcessNames.getMap().size();
10328            for (int ip=0; ip<NP; ip++) {
10329                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10330                final int NA = apps.size();
10331                for (int ia=0; ia<NA; ia++) {
10332                    ProcessRecord p = apps.valueAt(ia);
10333                    if (p.thread != null && p.thread.asBinder() == app) {
10334                        return p;
10335                    }
10336                }
10337            }
10338
10339            Slog.w(TAG, "Can't find mystery application for " + reason
10340                    + " from pid=" + Binder.getCallingPid()
10341                    + " uid=" + Binder.getCallingUid() + ": " + app);
10342            return null;
10343        }
10344    }
10345
10346    /**
10347     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10348     * to append various headers to the dropbox log text.
10349     */
10350    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10351            StringBuilder sb) {
10352        // Watchdog thread ends up invoking this function (with
10353        // a null ProcessRecord) to add the stack file to dropbox.
10354        // Do not acquire a lock on this (am) in such cases, as it
10355        // could cause a potential deadlock, if and when watchdog
10356        // is invoked due to unavailability of lock on am and it
10357        // would prevent watchdog from killing system_server.
10358        if (process == null) {
10359            sb.append("Process: ").append(processName).append("\n");
10360            return;
10361        }
10362        // Note: ProcessRecord 'process' is guarded by the service
10363        // instance.  (notably process.pkgList, which could otherwise change
10364        // concurrently during execution of this method)
10365        synchronized (this) {
10366            sb.append("Process: ").append(processName).append("\n");
10367            int flags = process.info.flags;
10368            IPackageManager pm = AppGlobals.getPackageManager();
10369            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10370            for (int ip=0; ip<process.pkgList.size(); ip++) {
10371                String pkg = process.pkgList.keyAt(ip);
10372                sb.append("Package: ").append(pkg);
10373                try {
10374                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10375                    if (pi != null) {
10376                        sb.append(" v").append(pi.versionCode);
10377                        if (pi.versionName != null) {
10378                            sb.append(" (").append(pi.versionName).append(")");
10379                        }
10380                    }
10381                } catch (RemoteException e) {
10382                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10383                }
10384                sb.append("\n");
10385            }
10386        }
10387    }
10388
10389    private static String processClass(ProcessRecord process) {
10390        if (process == null || process.pid == MY_PID) {
10391            return "system_server";
10392        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10393            return "system_app";
10394        } else {
10395            return "data_app";
10396        }
10397    }
10398
10399    /**
10400     * Write a description of an error (crash, WTF, ANR) to the drop box.
10401     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10402     * @param process which caused the error, null means the system server
10403     * @param activity which triggered the error, null if unknown
10404     * @param parent activity related to the error, null if unknown
10405     * @param subject line related to the error, null if absent
10406     * @param report in long form describing the error, null if absent
10407     * @param logFile to include in the report, null if none
10408     * @param crashInfo giving an application stack trace, null if absent
10409     */
10410    public void addErrorToDropBox(String eventType,
10411            ProcessRecord process, String processName, ActivityRecord activity,
10412            ActivityRecord parent, String subject,
10413            final String report, final File logFile,
10414            final ApplicationErrorReport.CrashInfo crashInfo) {
10415        // NOTE -- this must never acquire the ActivityManagerService lock,
10416        // otherwise the watchdog may be prevented from resetting the system.
10417
10418        final String dropboxTag = processClass(process) + "_" + eventType;
10419        final DropBoxManager dbox = (DropBoxManager)
10420                mContext.getSystemService(Context.DROPBOX_SERVICE);
10421
10422        // Exit early if the dropbox isn't configured to accept this report type.
10423        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10424
10425        final StringBuilder sb = new StringBuilder(1024);
10426        appendDropBoxProcessHeaders(process, processName, sb);
10427        if (activity != null) {
10428            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10429        }
10430        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10431            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10432        }
10433        if (parent != null && parent != activity) {
10434            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10435        }
10436        if (subject != null) {
10437            sb.append("Subject: ").append(subject).append("\n");
10438        }
10439        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10440        if (Debug.isDebuggerConnected()) {
10441            sb.append("Debugger: Connected\n");
10442        }
10443        sb.append("\n");
10444
10445        // Do the rest in a worker thread to avoid blocking the caller on I/O
10446        // (After this point, we shouldn't access AMS internal data structures.)
10447        Thread worker = new Thread("Error dump: " + dropboxTag) {
10448            @Override
10449            public void run() {
10450                if (report != null) {
10451                    sb.append(report);
10452                }
10453                if (logFile != null) {
10454                    try {
10455                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10456                                    "\n\n[[TRUNCATED]]"));
10457                    } catch (IOException e) {
10458                        Slog.e(TAG, "Error reading " + logFile, e);
10459                    }
10460                }
10461                if (crashInfo != null && crashInfo.stackTrace != null) {
10462                    sb.append(crashInfo.stackTrace);
10463                }
10464
10465                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10466                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10467                if (lines > 0) {
10468                    sb.append("\n");
10469
10470                    // Merge several logcat streams, and take the last N lines
10471                    InputStreamReader input = null;
10472                    try {
10473                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10474                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10475                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10476
10477                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10478                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10479                        input = new InputStreamReader(logcat.getInputStream());
10480
10481                        int num;
10482                        char[] buf = new char[8192];
10483                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10484                    } catch (IOException e) {
10485                        Slog.e(TAG, "Error running logcat", e);
10486                    } finally {
10487                        if (input != null) try { input.close(); } catch (IOException e) {}
10488                    }
10489                }
10490
10491                dbox.addText(dropboxTag, sb.toString());
10492            }
10493        };
10494
10495        if (process == null) {
10496            // If process is null, we are being called from some internal code
10497            // and may be about to die -- run this synchronously.
10498            worker.run();
10499        } else {
10500            worker.start();
10501        }
10502    }
10503
10504    /**
10505     * Bring up the "unexpected error" dialog box for a crashing app.
10506     * Deal with edge cases (intercepts from instrumented applications,
10507     * ActivityController, error intent receivers, that sort of thing).
10508     * @param r the application crashing
10509     * @param crashInfo describing the failure
10510     */
10511    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10512        long timeMillis = System.currentTimeMillis();
10513        String shortMsg = crashInfo.exceptionClassName;
10514        String longMsg = crashInfo.exceptionMessage;
10515        String stackTrace = crashInfo.stackTrace;
10516        if (shortMsg != null && longMsg != null) {
10517            longMsg = shortMsg + ": " + longMsg;
10518        } else if (shortMsg != null) {
10519            longMsg = shortMsg;
10520        }
10521
10522        AppErrorResult result = new AppErrorResult();
10523        synchronized (this) {
10524            if (mController != null) {
10525                try {
10526                    String name = r != null ? r.processName : null;
10527                    int pid = r != null ? r.pid : Binder.getCallingPid();
10528                    if (!mController.appCrashed(name, pid,
10529                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10530                        Slog.w(TAG, "Force-killing crashed app " + name
10531                                + " at watcher's request");
10532                        Process.killProcess(pid);
10533                        return;
10534                    }
10535                } catch (RemoteException e) {
10536                    mController = null;
10537                    Watchdog.getInstance().setActivityController(null);
10538                }
10539            }
10540
10541            final long origId = Binder.clearCallingIdentity();
10542
10543            // If this process is running instrumentation, finish it.
10544            if (r != null && r.instrumentationClass != null) {
10545                Slog.w(TAG, "Error in app " + r.processName
10546                      + " running instrumentation " + r.instrumentationClass + ":");
10547                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10548                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10549                Bundle info = new Bundle();
10550                info.putString("shortMsg", shortMsg);
10551                info.putString("longMsg", longMsg);
10552                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10553                Binder.restoreCallingIdentity(origId);
10554                return;
10555            }
10556
10557            // If we can't identify the process or it's already exceeded its crash quota,
10558            // quit right away without showing a crash dialog.
10559            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10560                Binder.restoreCallingIdentity(origId);
10561                return;
10562            }
10563
10564            Message msg = Message.obtain();
10565            msg.what = SHOW_ERROR_MSG;
10566            HashMap data = new HashMap();
10567            data.put("result", result);
10568            data.put("app", r);
10569            msg.obj = data;
10570            mHandler.sendMessage(msg);
10571
10572            Binder.restoreCallingIdentity(origId);
10573        }
10574
10575        int res = result.get();
10576
10577        Intent appErrorIntent = null;
10578        synchronized (this) {
10579            if (r != null && !r.isolated) {
10580                // XXX Can't keep track of crash time for isolated processes,
10581                // since they don't have a persistent identity.
10582                mProcessCrashTimes.put(r.info.processName, r.uid,
10583                        SystemClock.uptimeMillis());
10584            }
10585            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10586                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10587            }
10588        }
10589
10590        if (appErrorIntent != null) {
10591            try {
10592                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10593            } catch (ActivityNotFoundException e) {
10594                Slog.w(TAG, "bug report receiver dissappeared", e);
10595            }
10596        }
10597    }
10598
10599    Intent createAppErrorIntentLocked(ProcessRecord r,
10600            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10601        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10602        if (report == null) {
10603            return null;
10604        }
10605        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10606        result.setComponent(r.errorReportReceiver);
10607        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10608        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10609        return result;
10610    }
10611
10612    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10613            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10614        if (r.errorReportReceiver == null) {
10615            return null;
10616        }
10617
10618        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10619            return null;
10620        }
10621
10622        ApplicationErrorReport report = new ApplicationErrorReport();
10623        report.packageName = r.info.packageName;
10624        report.installerPackageName = r.errorReportReceiver.getPackageName();
10625        report.processName = r.processName;
10626        report.time = timeMillis;
10627        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10628
10629        if (r.crashing || r.forceCrashReport) {
10630            report.type = ApplicationErrorReport.TYPE_CRASH;
10631            report.crashInfo = crashInfo;
10632        } else if (r.notResponding) {
10633            report.type = ApplicationErrorReport.TYPE_ANR;
10634            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10635
10636            report.anrInfo.activity = r.notRespondingReport.tag;
10637            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10638            report.anrInfo.info = r.notRespondingReport.longMsg;
10639        }
10640
10641        return report;
10642    }
10643
10644    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10645        enforceNotIsolatedCaller("getProcessesInErrorState");
10646        // assume our apps are happy - lazy create the list
10647        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10648
10649        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10650                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10651        int userId = UserHandle.getUserId(Binder.getCallingUid());
10652
10653        synchronized (this) {
10654
10655            // iterate across all processes
10656            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10657                ProcessRecord app = mLruProcesses.get(i);
10658                if (!allUsers && app.userId != userId) {
10659                    continue;
10660                }
10661                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10662                    // This one's in trouble, so we'll generate a report for it
10663                    // crashes are higher priority (in case there's a crash *and* an anr)
10664                    ActivityManager.ProcessErrorStateInfo report = null;
10665                    if (app.crashing) {
10666                        report = app.crashingReport;
10667                    } else if (app.notResponding) {
10668                        report = app.notRespondingReport;
10669                    }
10670
10671                    if (report != null) {
10672                        if (errList == null) {
10673                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10674                        }
10675                        errList.add(report);
10676                    } else {
10677                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10678                                " crashing = " + app.crashing +
10679                                " notResponding = " + app.notResponding);
10680                    }
10681                }
10682            }
10683        }
10684
10685        return errList;
10686    }
10687
10688    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10689        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10690            if (currApp != null) {
10691                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10692            }
10693            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10694        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10695            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10696        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10697            if (currApp != null) {
10698                currApp.lru = 0;
10699            }
10700            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10701        } else if (adj >= ProcessList.SERVICE_ADJ) {
10702            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10703        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10704            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10705        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10706            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10707        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10708            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10709        } else {
10710            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10711        }
10712    }
10713
10714    private void fillInProcMemInfo(ProcessRecord app,
10715            ActivityManager.RunningAppProcessInfo outInfo) {
10716        outInfo.pid = app.pid;
10717        outInfo.uid = app.info.uid;
10718        if (mHeavyWeightProcess == app) {
10719            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10720        }
10721        if (app.persistent) {
10722            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10723        }
10724        if (app.activities.size() > 0) {
10725            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10726        }
10727        outInfo.lastTrimLevel = app.trimMemoryLevel;
10728        int adj = app.curAdj;
10729        outInfo.importance = oomAdjToImportance(adj, outInfo);
10730        outInfo.importanceReasonCode = app.adjTypeCode;
10731        outInfo.processState = app.curProcState;
10732    }
10733
10734    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10735        enforceNotIsolatedCaller("getRunningAppProcesses");
10736        // Lazy instantiation of list
10737        List<ActivityManager.RunningAppProcessInfo> runList = null;
10738        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10739                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10740        int userId = UserHandle.getUserId(Binder.getCallingUid());
10741        synchronized (this) {
10742            // Iterate across all processes
10743            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10744                ProcessRecord app = mLruProcesses.get(i);
10745                if (!allUsers && app.userId != userId) {
10746                    continue;
10747                }
10748                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10749                    // Generate process state info for running application
10750                    ActivityManager.RunningAppProcessInfo currApp =
10751                        new ActivityManager.RunningAppProcessInfo(app.processName,
10752                                app.pid, app.getPackageList());
10753                    fillInProcMemInfo(app, currApp);
10754                    if (app.adjSource instanceof ProcessRecord) {
10755                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10756                        currApp.importanceReasonImportance = oomAdjToImportance(
10757                                app.adjSourceOom, null);
10758                    } else if (app.adjSource instanceof ActivityRecord) {
10759                        ActivityRecord r = (ActivityRecord)app.adjSource;
10760                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10761                    }
10762                    if (app.adjTarget instanceof ComponentName) {
10763                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10764                    }
10765                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10766                    //        + " lru=" + currApp.lru);
10767                    if (runList == null) {
10768                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10769                    }
10770                    runList.add(currApp);
10771                }
10772            }
10773        }
10774        return runList;
10775    }
10776
10777    public List<ApplicationInfo> getRunningExternalApplications() {
10778        enforceNotIsolatedCaller("getRunningExternalApplications");
10779        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10780        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10781        if (runningApps != null && runningApps.size() > 0) {
10782            Set<String> extList = new HashSet<String>();
10783            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10784                if (app.pkgList != null) {
10785                    for (String pkg : app.pkgList) {
10786                        extList.add(pkg);
10787                    }
10788                }
10789            }
10790            IPackageManager pm = AppGlobals.getPackageManager();
10791            for (String pkg : extList) {
10792                try {
10793                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10794                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10795                        retList.add(info);
10796                    }
10797                } catch (RemoteException e) {
10798                }
10799            }
10800        }
10801        return retList;
10802    }
10803
10804    @Override
10805    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10806        enforceNotIsolatedCaller("getMyMemoryState");
10807        synchronized (this) {
10808            ProcessRecord proc;
10809            synchronized (mPidsSelfLocked) {
10810                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10811            }
10812            fillInProcMemInfo(proc, outInfo);
10813        }
10814    }
10815
10816    @Override
10817    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10818        if (checkCallingPermission(android.Manifest.permission.DUMP)
10819                != PackageManager.PERMISSION_GRANTED) {
10820            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10821                    + Binder.getCallingPid()
10822                    + ", uid=" + Binder.getCallingUid()
10823                    + " without permission "
10824                    + android.Manifest.permission.DUMP);
10825            return;
10826        }
10827
10828        boolean dumpAll = false;
10829        boolean dumpClient = false;
10830        String dumpPackage = null;
10831
10832        int opti = 0;
10833        while (opti < args.length) {
10834            String opt = args[opti];
10835            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10836                break;
10837            }
10838            opti++;
10839            if ("-a".equals(opt)) {
10840                dumpAll = true;
10841            } else if ("-c".equals(opt)) {
10842                dumpClient = true;
10843            } else if ("-h".equals(opt)) {
10844                pw.println("Activity manager dump options:");
10845                pw.println("  [-a] [-c] [-h] [cmd] ...");
10846                pw.println("  cmd may be one of:");
10847                pw.println("    a[ctivities]: activity stack state");
10848                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10849                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10850                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10851                pw.println("    o[om]: out of memory management");
10852                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10853                pw.println("    provider [COMP_SPEC]: provider client-side state");
10854                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10855                pw.println("    service [COMP_SPEC]: service client-side state");
10856                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10857                pw.println("    all: dump all activities");
10858                pw.println("    top: dump the top activity");
10859                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10860                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10861                pw.println("    a partial substring in a component name, a");
10862                pw.println("    hex object identifier.");
10863                pw.println("  -a: include all available server state.");
10864                pw.println("  -c: include client state.");
10865                return;
10866            } else {
10867                pw.println("Unknown argument: " + opt + "; use -h for help");
10868            }
10869        }
10870
10871        long origId = Binder.clearCallingIdentity();
10872        boolean more = false;
10873        // Is the caller requesting to dump a particular piece of data?
10874        if (opti < args.length) {
10875            String cmd = args[opti];
10876            opti++;
10877            if ("activities".equals(cmd) || "a".equals(cmd)) {
10878                synchronized (this) {
10879                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10880                }
10881            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10882                String[] newArgs;
10883                String name;
10884                if (opti >= args.length) {
10885                    name = null;
10886                    newArgs = EMPTY_STRING_ARRAY;
10887                } else {
10888                    name = args[opti];
10889                    opti++;
10890                    newArgs = new String[args.length - opti];
10891                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10892                            args.length - opti);
10893                }
10894                synchronized (this) {
10895                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10896                }
10897            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10898                String[] newArgs;
10899                String name;
10900                if (opti >= args.length) {
10901                    name = null;
10902                    newArgs = EMPTY_STRING_ARRAY;
10903                } else {
10904                    name = args[opti];
10905                    opti++;
10906                    newArgs = new String[args.length - opti];
10907                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10908                            args.length - opti);
10909                }
10910                synchronized (this) {
10911                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10912                }
10913            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10914                String[] newArgs;
10915                String name;
10916                if (opti >= args.length) {
10917                    name = null;
10918                    newArgs = EMPTY_STRING_ARRAY;
10919                } else {
10920                    name = args[opti];
10921                    opti++;
10922                    newArgs = new String[args.length - opti];
10923                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10924                            args.length - opti);
10925                }
10926                synchronized (this) {
10927                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10928                }
10929            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10930                synchronized (this) {
10931                    dumpOomLocked(fd, pw, args, opti, true);
10932                }
10933            } else if ("provider".equals(cmd)) {
10934                String[] newArgs;
10935                String name;
10936                if (opti >= args.length) {
10937                    name = null;
10938                    newArgs = EMPTY_STRING_ARRAY;
10939                } else {
10940                    name = args[opti];
10941                    opti++;
10942                    newArgs = new String[args.length - opti];
10943                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10944                }
10945                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10946                    pw.println("No providers match: " + name);
10947                    pw.println("Use -h for help.");
10948                }
10949            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10950                synchronized (this) {
10951                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10952                }
10953            } else if ("service".equals(cmd)) {
10954                String[] newArgs;
10955                String name;
10956                if (opti >= args.length) {
10957                    name = null;
10958                    newArgs = EMPTY_STRING_ARRAY;
10959                } else {
10960                    name = args[opti];
10961                    opti++;
10962                    newArgs = new String[args.length - opti];
10963                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10964                            args.length - opti);
10965                }
10966                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10967                    pw.println("No services match: " + name);
10968                    pw.println("Use -h for help.");
10969                }
10970            } else if ("package".equals(cmd)) {
10971                String[] newArgs;
10972                if (opti >= args.length) {
10973                    pw.println("package: no package name specified");
10974                    pw.println("Use -h for help.");
10975                } else {
10976                    dumpPackage = args[opti];
10977                    opti++;
10978                    newArgs = new String[args.length - opti];
10979                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10980                            args.length - opti);
10981                    args = newArgs;
10982                    opti = 0;
10983                    more = true;
10984                }
10985            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10986                synchronized (this) {
10987                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10988                }
10989            } else {
10990                // Dumping a single activity?
10991                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10992                    pw.println("Bad activity command, or no activities match: " + cmd);
10993                    pw.println("Use -h for help.");
10994                }
10995            }
10996            if (!more) {
10997                Binder.restoreCallingIdentity(origId);
10998                return;
10999            }
11000        }
11001
11002        // No piece of data specified, dump everything.
11003        synchronized (this) {
11004            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11005            pw.println();
11006            if (dumpAll) {
11007                pw.println("-------------------------------------------------------------------------------");
11008            }
11009            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11010            pw.println();
11011            if (dumpAll) {
11012                pw.println("-------------------------------------------------------------------------------");
11013            }
11014            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11015            pw.println();
11016            if (dumpAll) {
11017                pw.println("-------------------------------------------------------------------------------");
11018            }
11019            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11020            pw.println();
11021            if (dumpAll) {
11022                pw.println("-------------------------------------------------------------------------------");
11023            }
11024            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11025            pw.println();
11026            if (dumpAll) {
11027                pw.println("-------------------------------------------------------------------------------");
11028            }
11029            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11030        }
11031        Binder.restoreCallingIdentity(origId);
11032    }
11033
11034    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11035            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11036        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11037
11038        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11039                dumpPackage);
11040        boolean needSep = printedAnything;
11041
11042        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11043                dumpPackage, needSep, "  mFocusedActivity: ");
11044        if (printed) {
11045            printedAnything = true;
11046            needSep = false;
11047        }
11048
11049        if (dumpPackage == null) {
11050            if (needSep) {
11051                pw.println();
11052            }
11053            needSep = true;
11054            printedAnything = true;
11055            mStackSupervisor.dump(pw, "  ");
11056        }
11057
11058        if (mRecentTasks.size() > 0) {
11059            boolean printedHeader = false;
11060
11061            final int N = mRecentTasks.size();
11062            for (int i=0; i<N; i++) {
11063                TaskRecord tr = mRecentTasks.get(i);
11064                if (dumpPackage != null) {
11065                    if (tr.realActivity == null ||
11066                            !dumpPackage.equals(tr.realActivity)) {
11067                        continue;
11068                    }
11069                }
11070                if (!printedHeader) {
11071                    if (needSep) {
11072                        pw.println();
11073                    }
11074                    pw.println("  Recent tasks:");
11075                    printedHeader = true;
11076                    printedAnything = true;
11077                }
11078                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11079                        pw.println(tr);
11080                if (dumpAll) {
11081                    mRecentTasks.get(i).dump(pw, "    ");
11082                }
11083            }
11084        }
11085
11086        if (!printedAnything) {
11087            pw.println("  (nothing)");
11088        }
11089    }
11090
11091    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11092            int opti, boolean dumpAll, String dumpPackage) {
11093        boolean needSep = false;
11094        boolean printedAnything = false;
11095        int numPers = 0;
11096
11097        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11098
11099        if (dumpAll) {
11100            final int NP = mProcessNames.getMap().size();
11101            for (int ip=0; ip<NP; ip++) {
11102                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11103                final int NA = procs.size();
11104                for (int ia=0; ia<NA; ia++) {
11105                    ProcessRecord r = procs.valueAt(ia);
11106                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11107                        continue;
11108                    }
11109                    if (!needSep) {
11110                        pw.println("  All known processes:");
11111                        needSep = true;
11112                        printedAnything = true;
11113                    }
11114                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11115                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11116                        pw.print(" "); pw.println(r);
11117                    r.dump(pw, "    ");
11118                    if (r.persistent) {
11119                        numPers++;
11120                    }
11121                }
11122            }
11123        }
11124
11125        if (mIsolatedProcesses.size() > 0) {
11126            boolean printed = false;
11127            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11128                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11129                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11130                    continue;
11131                }
11132                if (!printed) {
11133                    if (needSep) {
11134                        pw.println();
11135                    }
11136                    pw.println("  Isolated process list (sorted by uid):");
11137                    printedAnything = true;
11138                    printed = true;
11139                    needSep = true;
11140                }
11141                pw.println(String.format("%sIsolated #%2d: %s",
11142                        "    ", i, r.toString()));
11143            }
11144        }
11145
11146        if (mLruProcesses.size() > 0) {
11147            if (needSep) {
11148                pw.println();
11149            }
11150            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11151                    pw.print(" total, non-act at ");
11152                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11153                    pw.print(", non-svc at ");
11154                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11155                    pw.println("):");
11156            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11157            needSep = true;
11158            printedAnything = true;
11159        }
11160
11161        if (dumpAll || dumpPackage != null) {
11162            synchronized (mPidsSelfLocked) {
11163                boolean printed = false;
11164                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11165                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11166                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11167                        continue;
11168                    }
11169                    if (!printed) {
11170                        if (needSep) pw.println();
11171                        needSep = true;
11172                        pw.println("  PID mappings:");
11173                        printed = true;
11174                        printedAnything = true;
11175                    }
11176                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11177                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11178                }
11179            }
11180        }
11181
11182        if (mForegroundProcesses.size() > 0) {
11183            synchronized (mPidsSelfLocked) {
11184                boolean printed = false;
11185                for (int i=0; i<mForegroundProcesses.size(); i++) {
11186                    ProcessRecord r = mPidsSelfLocked.get(
11187                            mForegroundProcesses.valueAt(i).pid);
11188                    if (dumpPackage != null && (r == null
11189                            || !r.pkgList.containsKey(dumpPackage))) {
11190                        continue;
11191                    }
11192                    if (!printed) {
11193                        if (needSep) pw.println();
11194                        needSep = true;
11195                        pw.println("  Foreground Processes:");
11196                        printed = true;
11197                        printedAnything = true;
11198                    }
11199                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11200                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11201                }
11202            }
11203        }
11204
11205        if (mPersistentStartingProcesses.size() > 0) {
11206            if (needSep) pw.println();
11207            needSep = true;
11208            printedAnything = true;
11209            pw.println("  Persisent processes that are starting:");
11210            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11211                    "Starting Norm", "Restarting PERS", dumpPackage);
11212        }
11213
11214        if (mRemovedProcesses.size() > 0) {
11215            if (needSep) pw.println();
11216            needSep = true;
11217            printedAnything = true;
11218            pw.println("  Processes that are being removed:");
11219            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11220                    "Removed Norm", "Removed PERS", dumpPackage);
11221        }
11222
11223        if (mProcessesOnHold.size() > 0) {
11224            if (needSep) pw.println();
11225            needSep = true;
11226            printedAnything = true;
11227            pw.println("  Processes that are on old until the system is ready:");
11228            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11229                    "OnHold Norm", "OnHold PERS", dumpPackage);
11230        }
11231
11232        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11233
11234        if (mProcessCrashTimes.getMap().size() > 0) {
11235            boolean printed = false;
11236            long now = SystemClock.uptimeMillis();
11237            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11238            final int NP = pmap.size();
11239            for (int ip=0; ip<NP; ip++) {
11240                String pname = pmap.keyAt(ip);
11241                SparseArray<Long> uids = pmap.valueAt(ip);
11242                final int N = uids.size();
11243                for (int i=0; i<N; i++) {
11244                    int puid = uids.keyAt(i);
11245                    ProcessRecord r = mProcessNames.get(pname, puid);
11246                    if (dumpPackage != null && (r == null
11247                            || !r.pkgList.containsKey(dumpPackage))) {
11248                        continue;
11249                    }
11250                    if (!printed) {
11251                        if (needSep) pw.println();
11252                        needSep = true;
11253                        pw.println("  Time since processes crashed:");
11254                        printed = true;
11255                        printedAnything = true;
11256                    }
11257                    pw.print("    Process "); pw.print(pname);
11258                            pw.print(" uid "); pw.print(puid);
11259                            pw.print(": last crashed ");
11260                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11261                            pw.println(" ago");
11262                }
11263            }
11264        }
11265
11266        if (mBadProcesses.getMap().size() > 0) {
11267            boolean printed = false;
11268            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11269            final int NP = pmap.size();
11270            for (int ip=0; ip<NP; ip++) {
11271                String pname = pmap.keyAt(ip);
11272                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11273                final int N = uids.size();
11274                for (int i=0; i<N; i++) {
11275                    int puid = uids.keyAt(i);
11276                    ProcessRecord r = mProcessNames.get(pname, puid);
11277                    if (dumpPackage != null && (r == null
11278                            || !r.pkgList.containsKey(dumpPackage))) {
11279                        continue;
11280                    }
11281                    if (!printed) {
11282                        if (needSep) pw.println();
11283                        needSep = true;
11284                        pw.println("  Bad processes:");
11285                        printedAnything = true;
11286                    }
11287                    BadProcessInfo info = uids.valueAt(i);
11288                    pw.print("    Bad process "); pw.print(pname);
11289                            pw.print(" uid "); pw.print(puid);
11290                            pw.print(": crashed at time "); pw.println(info.time);
11291                    if (info.shortMsg != null) {
11292                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11293                    }
11294                    if (info.longMsg != null) {
11295                        pw.print("      Long msg: "); pw.println(info.longMsg);
11296                    }
11297                    if (info.stack != null) {
11298                        pw.println("      Stack:");
11299                        int lastPos = 0;
11300                        for (int pos=0; pos<info.stack.length(); pos++) {
11301                            if (info.stack.charAt(pos) == '\n') {
11302                                pw.print("        ");
11303                                pw.write(info.stack, lastPos, pos-lastPos);
11304                                pw.println();
11305                                lastPos = pos+1;
11306                            }
11307                        }
11308                        if (lastPos < info.stack.length()) {
11309                            pw.print("        ");
11310                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11311                            pw.println();
11312                        }
11313                    }
11314                }
11315            }
11316        }
11317
11318        if (dumpPackage == null) {
11319            pw.println();
11320            needSep = false;
11321            pw.println("  mStartedUsers:");
11322            for (int i=0; i<mStartedUsers.size(); i++) {
11323                UserStartedState uss = mStartedUsers.valueAt(i);
11324                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11325                        pw.print(": "); uss.dump("", pw);
11326            }
11327            pw.print("  mStartedUserArray: [");
11328            for (int i=0; i<mStartedUserArray.length; i++) {
11329                if (i > 0) pw.print(", ");
11330                pw.print(mStartedUserArray[i]);
11331            }
11332            pw.println("]");
11333            pw.print("  mUserLru: [");
11334            for (int i=0; i<mUserLru.size(); i++) {
11335                if (i > 0) pw.print(", ");
11336                pw.print(mUserLru.get(i));
11337            }
11338            pw.println("]");
11339            if (dumpAll) {
11340                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11341            }
11342        }
11343        if (mHomeProcess != null && (dumpPackage == null
11344                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11345            if (needSep) {
11346                pw.println();
11347                needSep = false;
11348            }
11349            pw.println("  mHomeProcess: " + mHomeProcess);
11350        }
11351        if (mPreviousProcess != null && (dumpPackage == null
11352                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11353            if (needSep) {
11354                pw.println();
11355                needSep = false;
11356            }
11357            pw.println("  mPreviousProcess: " + mPreviousProcess);
11358        }
11359        if (dumpAll) {
11360            StringBuilder sb = new StringBuilder(128);
11361            sb.append("  mPreviousProcessVisibleTime: ");
11362            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11363            pw.println(sb);
11364        }
11365        if (mHeavyWeightProcess != null && (dumpPackage == null
11366                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11367            if (needSep) {
11368                pw.println();
11369                needSep = false;
11370            }
11371            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11372        }
11373        if (dumpPackage == null) {
11374            pw.println("  mConfiguration: " + mConfiguration);
11375        }
11376        if (dumpAll) {
11377            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11378            if (mCompatModePackages.getPackages().size() > 0) {
11379                boolean printed = false;
11380                for (Map.Entry<String, Integer> entry
11381                        : mCompatModePackages.getPackages().entrySet()) {
11382                    String pkg = entry.getKey();
11383                    int mode = entry.getValue();
11384                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11385                        continue;
11386                    }
11387                    if (!printed) {
11388                        pw.println("  mScreenCompatPackages:");
11389                        printed = true;
11390                    }
11391                    pw.print("    "); pw.print(pkg); pw.print(": ");
11392                            pw.print(mode); pw.println();
11393                }
11394            }
11395        }
11396        if (dumpPackage == null) {
11397            if (mSleeping || mWentToSleep || mLockScreenShown) {
11398                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11399                        + " mLockScreenShown " + mLockScreenShown);
11400            }
11401            if (mShuttingDown || mRunningVoice) {
11402                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11403            }
11404        }
11405        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11406                || mOrigWaitForDebugger) {
11407            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11408                    || dumpPackage.equals(mOrigDebugApp)) {
11409                if (needSep) {
11410                    pw.println();
11411                    needSep = false;
11412                }
11413                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11414                        + " mDebugTransient=" + mDebugTransient
11415                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11416            }
11417        }
11418        if (mOpenGlTraceApp != null) {
11419            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11420                if (needSep) {
11421                    pw.println();
11422                    needSep = false;
11423                }
11424                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11425            }
11426        }
11427        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11428                || mProfileFd != null) {
11429            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11430                if (needSep) {
11431                    pw.println();
11432                    needSep = false;
11433                }
11434                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11435                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11436                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11437                        + mAutoStopProfiler);
11438            }
11439        }
11440        if (dumpPackage == null) {
11441            if (mAlwaysFinishActivities || mController != null) {
11442                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11443                        + " mController=" + mController);
11444            }
11445            if (dumpAll) {
11446                pw.println("  Total persistent processes: " + numPers);
11447                pw.println("  mProcessesReady=" + mProcessesReady
11448                        + " mSystemReady=" + mSystemReady);
11449                pw.println("  mBooting=" + mBooting
11450                        + " mBooted=" + mBooted
11451                        + " mFactoryTest=" + mFactoryTest);
11452                pw.print("  mLastPowerCheckRealtime=");
11453                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11454                        pw.println("");
11455                pw.print("  mLastPowerCheckUptime=");
11456                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11457                        pw.println("");
11458                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11459                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11460                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11461                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11462                        + " (" + mLruProcesses.size() + " total)"
11463                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11464                        + " mNumServiceProcs=" + mNumServiceProcs
11465                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11466                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11467                        + " mLastMemoryLevel" + mLastMemoryLevel
11468                        + " mLastNumProcesses" + mLastNumProcesses);
11469                long now = SystemClock.uptimeMillis();
11470                pw.print("  mLastIdleTime=");
11471                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11472                        pw.print(" mLowRamSinceLastIdle=");
11473                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11474                        pw.println();
11475            }
11476        }
11477
11478        if (!printedAnything) {
11479            pw.println("  (nothing)");
11480        }
11481    }
11482
11483    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11484            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11485        if (mProcessesToGc.size() > 0) {
11486            boolean printed = false;
11487            long now = SystemClock.uptimeMillis();
11488            for (int i=0; i<mProcessesToGc.size(); i++) {
11489                ProcessRecord proc = mProcessesToGc.get(i);
11490                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11491                    continue;
11492                }
11493                if (!printed) {
11494                    if (needSep) pw.println();
11495                    needSep = true;
11496                    pw.println("  Processes that are waiting to GC:");
11497                    printed = true;
11498                }
11499                pw.print("    Process "); pw.println(proc);
11500                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11501                        pw.print(", last gced=");
11502                        pw.print(now-proc.lastRequestedGc);
11503                        pw.print(" ms ago, last lowMem=");
11504                        pw.print(now-proc.lastLowMemory);
11505                        pw.println(" ms ago");
11506
11507            }
11508        }
11509        return needSep;
11510    }
11511
11512    void printOomLevel(PrintWriter pw, String name, int adj) {
11513        pw.print("    ");
11514        if (adj >= 0) {
11515            pw.print(' ');
11516            if (adj < 10) pw.print(' ');
11517        } else {
11518            if (adj > -10) pw.print(' ');
11519        }
11520        pw.print(adj);
11521        pw.print(": ");
11522        pw.print(name);
11523        pw.print(" (");
11524        pw.print(mProcessList.getMemLevel(adj)/1024);
11525        pw.println(" kB)");
11526    }
11527
11528    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11529            int opti, boolean dumpAll) {
11530        boolean needSep = false;
11531
11532        if (mLruProcesses.size() > 0) {
11533            if (needSep) pw.println();
11534            needSep = true;
11535            pw.println("  OOM levels:");
11536            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11537            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11538            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11539            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11540            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11541            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11542            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11543            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11544            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11545            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11546            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11547            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11548            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11549
11550            if (needSep) pw.println();
11551            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11552                    pw.print(" total, non-act at ");
11553                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11554                    pw.print(", non-svc at ");
11555                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11556                    pw.println("):");
11557            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11558            needSep = true;
11559        }
11560
11561        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11562
11563        pw.println();
11564        pw.println("  mHomeProcess: " + mHomeProcess);
11565        pw.println("  mPreviousProcess: " + mPreviousProcess);
11566        if (mHeavyWeightProcess != null) {
11567            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11568        }
11569
11570        return true;
11571    }
11572
11573    /**
11574     * There are three ways to call this:
11575     *  - no provider specified: dump all the providers
11576     *  - a flattened component name that matched an existing provider was specified as the
11577     *    first arg: dump that one provider
11578     *  - the first arg isn't the flattened component name of an existing provider:
11579     *    dump all providers whose component contains the first arg as a substring
11580     */
11581    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11582            int opti, boolean dumpAll) {
11583        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11584    }
11585
11586    static class ItemMatcher {
11587        ArrayList<ComponentName> components;
11588        ArrayList<String> strings;
11589        ArrayList<Integer> objects;
11590        boolean all;
11591
11592        ItemMatcher() {
11593            all = true;
11594        }
11595
11596        void build(String name) {
11597            ComponentName componentName = ComponentName.unflattenFromString(name);
11598            if (componentName != null) {
11599                if (components == null) {
11600                    components = new ArrayList<ComponentName>();
11601                }
11602                components.add(componentName);
11603                all = false;
11604            } else {
11605                int objectId = 0;
11606                // Not a '/' separated full component name; maybe an object ID?
11607                try {
11608                    objectId = Integer.parseInt(name, 16);
11609                    if (objects == null) {
11610                        objects = new ArrayList<Integer>();
11611                    }
11612                    objects.add(objectId);
11613                    all = false;
11614                } catch (RuntimeException e) {
11615                    // Not an integer; just do string match.
11616                    if (strings == null) {
11617                        strings = new ArrayList<String>();
11618                    }
11619                    strings.add(name);
11620                    all = false;
11621                }
11622            }
11623        }
11624
11625        int build(String[] args, int opti) {
11626            for (; opti<args.length; opti++) {
11627                String name = args[opti];
11628                if ("--".equals(name)) {
11629                    return opti+1;
11630                }
11631                build(name);
11632            }
11633            return opti;
11634        }
11635
11636        boolean match(Object object, ComponentName comp) {
11637            if (all) {
11638                return true;
11639            }
11640            if (components != null) {
11641                for (int i=0; i<components.size(); i++) {
11642                    if (components.get(i).equals(comp)) {
11643                        return true;
11644                    }
11645                }
11646            }
11647            if (objects != null) {
11648                for (int i=0; i<objects.size(); i++) {
11649                    if (System.identityHashCode(object) == objects.get(i)) {
11650                        return true;
11651                    }
11652                }
11653            }
11654            if (strings != null) {
11655                String flat = comp.flattenToString();
11656                for (int i=0; i<strings.size(); i++) {
11657                    if (flat.contains(strings.get(i))) {
11658                        return true;
11659                    }
11660                }
11661            }
11662            return false;
11663        }
11664    }
11665
11666    /**
11667     * There are three things that cmd can be:
11668     *  - a flattened component name that matches an existing activity
11669     *  - the cmd arg isn't the flattened component name of an existing activity:
11670     *    dump all activity whose component contains the cmd as a substring
11671     *  - A hex number of the ActivityRecord object instance.
11672     */
11673    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11674            int opti, boolean dumpAll) {
11675        ArrayList<ActivityRecord> activities;
11676
11677        synchronized (this) {
11678            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11679        }
11680
11681        if (activities.size() <= 0) {
11682            return false;
11683        }
11684
11685        String[] newArgs = new String[args.length - opti];
11686        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11687
11688        TaskRecord lastTask = null;
11689        boolean needSep = false;
11690        for (int i=activities.size()-1; i>=0; i--) {
11691            ActivityRecord r = activities.get(i);
11692            if (needSep) {
11693                pw.println();
11694            }
11695            needSep = true;
11696            synchronized (this) {
11697                if (lastTask != r.task) {
11698                    lastTask = r.task;
11699                    pw.print("TASK "); pw.print(lastTask.affinity);
11700                            pw.print(" id="); pw.println(lastTask.taskId);
11701                    if (dumpAll) {
11702                        lastTask.dump(pw, "  ");
11703                    }
11704                }
11705            }
11706            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11707        }
11708        return true;
11709    }
11710
11711    /**
11712     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11713     * there is a thread associated with the activity.
11714     */
11715    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11716            final ActivityRecord r, String[] args, boolean dumpAll) {
11717        String innerPrefix = prefix + "  ";
11718        synchronized (this) {
11719            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11720                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11721                    pw.print(" pid=");
11722                    if (r.app != null) pw.println(r.app.pid);
11723                    else pw.println("(not running)");
11724            if (dumpAll) {
11725                r.dump(pw, innerPrefix);
11726            }
11727        }
11728        if (r.app != null && r.app.thread != null) {
11729            // flush anything that is already in the PrintWriter since the thread is going
11730            // to write to the file descriptor directly
11731            pw.flush();
11732            try {
11733                TransferPipe tp = new TransferPipe();
11734                try {
11735                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11736                            r.appToken, innerPrefix, args);
11737                    tp.go(fd);
11738                } finally {
11739                    tp.kill();
11740                }
11741            } catch (IOException e) {
11742                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11743            } catch (RemoteException e) {
11744                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11745            }
11746        }
11747    }
11748
11749    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11750            int opti, boolean dumpAll, String dumpPackage) {
11751        boolean needSep = false;
11752        boolean onlyHistory = false;
11753        boolean printedAnything = false;
11754
11755        if ("history".equals(dumpPackage)) {
11756            if (opti < args.length && "-s".equals(args[opti])) {
11757                dumpAll = false;
11758            }
11759            onlyHistory = true;
11760            dumpPackage = null;
11761        }
11762
11763        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11764        if (!onlyHistory && dumpAll) {
11765            if (mRegisteredReceivers.size() > 0) {
11766                boolean printed = false;
11767                Iterator it = mRegisteredReceivers.values().iterator();
11768                while (it.hasNext()) {
11769                    ReceiverList r = (ReceiverList)it.next();
11770                    if (dumpPackage != null && (r.app == null ||
11771                            !dumpPackage.equals(r.app.info.packageName))) {
11772                        continue;
11773                    }
11774                    if (!printed) {
11775                        pw.println("  Registered Receivers:");
11776                        needSep = true;
11777                        printed = true;
11778                        printedAnything = true;
11779                    }
11780                    pw.print("  * "); pw.println(r);
11781                    r.dump(pw, "    ");
11782                }
11783            }
11784
11785            if (mReceiverResolver.dump(pw, needSep ?
11786                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11787                    "    ", dumpPackage, false)) {
11788                needSep = true;
11789                printedAnything = true;
11790            }
11791        }
11792
11793        for (BroadcastQueue q : mBroadcastQueues) {
11794            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11795            printedAnything |= needSep;
11796        }
11797
11798        needSep = true;
11799
11800        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11801            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11802                if (needSep) {
11803                    pw.println();
11804                }
11805                needSep = true;
11806                printedAnything = true;
11807                pw.print("  Sticky broadcasts for user ");
11808                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11809                StringBuilder sb = new StringBuilder(128);
11810                for (Map.Entry<String, ArrayList<Intent>> ent
11811                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11812                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11813                    if (dumpAll) {
11814                        pw.println(":");
11815                        ArrayList<Intent> intents = ent.getValue();
11816                        final int N = intents.size();
11817                        for (int i=0; i<N; i++) {
11818                            sb.setLength(0);
11819                            sb.append("    Intent: ");
11820                            intents.get(i).toShortString(sb, false, true, false, false);
11821                            pw.println(sb.toString());
11822                            Bundle bundle = intents.get(i).getExtras();
11823                            if (bundle != null) {
11824                                pw.print("      ");
11825                                pw.println(bundle.toString());
11826                            }
11827                        }
11828                    } else {
11829                        pw.println("");
11830                    }
11831                }
11832            }
11833        }
11834
11835        if (!onlyHistory && dumpAll) {
11836            pw.println();
11837            for (BroadcastQueue queue : mBroadcastQueues) {
11838                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11839                        + queue.mBroadcastsScheduled);
11840            }
11841            pw.println("  mHandler:");
11842            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11843            needSep = true;
11844            printedAnything = true;
11845        }
11846
11847        if (!printedAnything) {
11848            pw.println("  (nothing)");
11849        }
11850    }
11851
11852    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11853            int opti, boolean dumpAll, String dumpPackage) {
11854        boolean needSep;
11855        boolean printedAnything = false;
11856
11857        ItemMatcher matcher = new ItemMatcher();
11858        matcher.build(args, opti);
11859
11860        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11861
11862        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11863        printedAnything |= needSep;
11864
11865        if (mLaunchingProviders.size() > 0) {
11866            boolean printed = false;
11867            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11868                ContentProviderRecord r = mLaunchingProviders.get(i);
11869                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11870                    continue;
11871                }
11872                if (!printed) {
11873                    if (needSep) pw.println();
11874                    needSep = true;
11875                    pw.println("  Launching content providers:");
11876                    printed = true;
11877                    printedAnything = true;
11878                }
11879                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11880                        pw.println(r);
11881            }
11882        }
11883
11884        if (mGrantedUriPermissions.size() > 0) {
11885            boolean printed = false;
11886            int dumpUid = -2;
11887            if (dumpPackage != null) {
11888                try {
11889                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11890                } catch (NameNotFoundException e) {
11891                    dumpUid = -1;
11892                }
11893            }
11894            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11895                int uid = mGrantedUriPermissions.keyAt(i);
11896                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11897                    continue;
11898                }
11899                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11900                if (!printed) {
11901                    if (needSep) pw.println();
11902                    needSep = true;
11903                    pw.println("  Granted Uri Permissions:");
11904                    printed = true;
11905                    printedAnything = true;
11906                }
11907                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11908                for (UriPermission perm : perms.values()) {
11909                    pw.print("    "); pw.println(perm);
11910                    if (dumpAll) {
11911                        perm.dump(pw, "      ");
11912                    }
11913                }
11914            }
11915        }
11916
11917        if (!printedAnything) {
11918            pw.println("  (nothing)");
11919        }
11920    }
11921
11922    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11923            int opti, boolean dumpAll, String dumpPackage) {
11924        boolean printed = false;
11925
11926        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11927
11928        if (mIntentSenderRecords.size() > 0) {
11929            Iterator<WeakReference<PendingIntentRecord>> it
11930                    = mIntentSenderRecords.values().iterator();
11931            while (it.hasNext()) {
11932                WeakReference<PendingIntentRecord> ref = it.next();
11933                PendingIntentRecord rec = ref != null ? ref.get(): null;
11934                if (dumpPackage != null && (rec == null
11935                        || !dumpPackage.equals(rec.key.packageName))) {
11936                    continue;
11937                }
11938                printed = true;
11939                if (rec != null) {
11940                    pw.print("  * "); pw.println(rec);
11941                    if (dumpAll) {
11942                        rec.dump(pw, "    ");
11943                    }
11944                } else {
11945                    pw.print("  * "); pw.println(ref);
11946                }
11947            }
11948        }
11949
11950        if (!printed) {
11951            pw.println("  (nothing)");
11952        }
11953    }
11954
11955    private static final int dumpProcessList(PrintWriter pw,
11956            ActivityManagerService service, List list,
11957            String prefix, String normalLabel, String persistentLabel,
11958            String dumpPackage) {
11959        int numPers = 0;
11960        final int N = list.size()-1;
11961        for (int i=N; i>=0; i--) {
11962            ProcessRecord r = (ProcessRecord)list.get(i);
11963            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11964                continue;
11965            }
11966            pw.println(String.format("%s%s #%2d: %s",
11967                    prefix, (r.persistent ? persistentLabel : normalLabel),
11968                    i, r.toString()));
11969            if (r.persistent) {
11970                numPers++;
11971            }
11972        }
11973        return numPers;
11974    }
11975
11976    private static final boolean dumpProcessOomList(PrintWriter pw,
11977            ActivityManagerService service, List<ProcessRecord> origList,
11978            String prefix, String normalLabel, String persistentLabel,
11979            boolean inclDetails, String dumpPackage) {
11980
11981        ArrayList<Pair<ProcessRecord, Integer>> list
11982                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11983        for (int i=0; i<origList.size(); i++) {
11984            ProcessRecord r = origList.get(i);
11985            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11986                continue;
11987            }
11988            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11989        }
11990
11991        if (list.size() <= 0) {
11992            return false;
11993        }
11994
11995        Comparator<Pair<ProcessRecord, Integer>> comparator
11996                = new Comparator<Pair<ProcessRecord, Integer>>() {
11997            @Override
11998            public int compare(Pair<ProcessRecord, Integer> object1,
11999                    Pair<ProcessRecord, Integer> object2) {
12000                if (object1.first.setAdj != object2.first.setAdj) {
12001                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12002                }
12003                if (object1.second.intValue() != object2.second.intValue()) {
12004                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12005                }
12006                return 0;
12007            }
12008        };
12009
12010        Collections.sort(list, comparator);
12011
12012        final long curRealtime = SystemClock.elapsedRealtime();
12013        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12014        final long curUptime = SystemClock.uptimeMillis();
12015        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12016
12017        for (int i=list.size()-1; i>=0; i--) {
12018            ProcessRecord r = list.get(i).first;
12019            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12020            char schedGroup;
12021            switch (r.setSchedGroup) {
12022                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12023                    schedGroup = 'B';
12024                    break;
12025                case Process.THREAD_GROUP_DEFAULT:
12026                    schedGroup = 'F';
12027                    break;
12028                default:
12029                    schedGroup = '?';
12030                    break;
12031            }
12032            char foreground;
12033            if (r.foregroundActivities) {
12034                foreground = 'A';
12035            } else if (r.foregroundServices) {
12036                foreground = 'S';
12037            } else {
12038                foreground = ' ';
12039            }
12040            String procState = ProcessList.makeProcStateString(r.curProcState);
12041            pw.print(prefix);
12042            pw.print(r.persistent ? persistentLabel : normalLabel);
12043            pw.print(" #");
12044            int num = (origList.size()-1)-list.get(i).second;
12045            if (num < 10) pw.print(' ');
12046            pw.print(num);
12047            pw.print(": ");
12048            pw.print(oomAdj);
12049            pw.print(' ');
12050            pw.print(schedGroup);
12051            pw.print('/');
12052            pw.print(foreground);
12053            pw.print('/');
12054            pw.print(procState);
12055            pw.print(" trm:");
12056            if (r.trimMemoryLevel < 10) pw.print(' ');
12057            pw.print(r.trimMemoryLevel);
12058            pw.print(' ');
12059            pw.print(r.toShortString());
12060            pw.print(" (");
12061            pw.print(r.adjType);
12062            pw.println(')');
12063            if (r.adjSource != null || r.adjTarget != null) {
12064                pw.print(prefix);
12065                pw.print("    ");
12066                if (r.adjTarget instanceof ComponentName) {
12067                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12068                } else if (r.adjTarget != null) {
12069                    pw.print(r.adjTarget.toString());
12070                } else {
12071                    pw.print("{null}");
12072                }
12073                pw.print("<=");
12074                if (r.adjSource instanceof ProcessRecord) {
12075                    pw.print("Proc{");
12076                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12077                    pw.println("}");
12078                } else if (r.adjSource != null) {
12079                    pw.println(r.adjSource.toString());
12080                } else {
12081                    pw.println("{null}");
12082                }
12083            }
12084            if (inclDetails) {
12085                pw.print(prefix);
12086                pw.print("    ");
12087                pw.print("oom: max="); pw.print(r.maxAdj);
12088                pw.print(" curRaw="); pw.print(r.curRawAdj);
12089                pw.print(" setRaw="); pw.print(r.setRawAdj);
12090                pw.print(" cur="); pw.print(r.curAdj);
12091                pw.print(" set="); pw.println(r.setAdj);
12092                pw.print(prefix);
12093                pw.print("    ");
12094                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12095                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12096                pw.print(" lastPss="); pw.print(r.lastPss);
12097                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12098                pw.print(prefix);
12099                pw.print("    ");
12100                pw.print("keeping="); pw.print(r.keeping);
12101                pw.print(" cached="); pw.print(r.cached);
12102                pw.print(" empty="); pw.print(r.empty);
12103                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12104
12105                if (!r.keeping) {
12106                    if (r.lastWakeTime != 0) {
12107                        long wtime;
12108                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12109                        synchronized (stats) {
12110                            wtime = stats.getProcessWakeTime(r.info.uid,
12111                                    r.pid, curRealtime);
12112                        }
12113                        long timeUsed = wtime - r.lastWakeTime;
12114                        pw.print(prefix);
12115                        pw.print("    ");
12116                        pw.print("keep awake over ");
12117                        TimeUtils.formatDuration(realtimeSince, pw);
12118                        pw.print(" used ");
12119                        TimeUtils.formatDuration(timeUsed, pw);
12120                        pw.print(" (");
12121                        pw.print((timeUsed*100)/realtimeSince);
12122                        pw.println("%)");
12123                    }
12124                    if (r.lastCpuTime != 0) {
12125                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12126                        pw.print(prefix);
12127                        pw.print("    ");
12128                        pw.print("run cpu over ");
12129                        TimeUtils.formatDuration(uptimeSince, pw);
12130                        pw.print(" used ");
12131                        TimeUtils.formatDuration(timeUsed, pw);
12132                        pw.print(" (");
12133                        pw.print((timeUsed*100)/uptimeSince);
12134                        pw.println("%)");
12135                    }
12136                }
12137            }
12138        }
12139        return true;
12140    }
12141
12142    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12143        ArrayList<ProcessRecord> procs;
12144        synchronized (this) {
12145            if (args != null && args.length > start
12146                    && args[start].charAt(0) != '-') {
12147                procs = new ArrayList<ProcessRecord>();
12148                int pid = -1;
12149                try {
12150                    pid = Integer.parseInt(args[start]);
12151                } catch (NumberFormatException e) {
12152                }
12153                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12154                    ProcessRecord proc = mLruProcesses.get(i);
12155                    if (proc.pid == pid) {
12156                        procs.add(proc);
12157                    } else if (proc.processName.equals(args[start])) {
12158                        procs.add(proc);
12159                    }
12160                }
12161                if (procs.size() <= 0) {
12162                    return null;
12163                }
12164            } else {
12165                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12166            }
12167        }
12168        return procs;
12169    }
12170
12171    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12172            PrintWriter pw, String[] args) {
12173        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12174        if (procs == null) {
12175            pw.println("No process found for: " + args[0]);
12176            return;
12177        }
12178
12179        long uptime = SystemClock.uptimeMillis();
12180        long realtime = SystemClock.elapsedRealtime();
12181        pw.println("Applications Graphics Acceleration Info:");
12182        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12183
12184        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12185            ProcessRecord r = procs.get(i);
12186            if (r.thread != null) {
12187                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12188                pw.flush();
12189                try {
12190                    TransferPipe tp = new TransferPipe();
12191                    try {
12192                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12193                        tp.go(fd);
12194                    } finally {
12195                        tp.kill();
12196                    }
12197                } catch (IOException e) {
12198                    pw.println("Failure while dumping the app: " + r);
12199                    pw.flush();
12200                } catch (RemoteException e) {
12201                    pw.println("Got a RemoteException while dumping the app " + r);
12202                    pw.flush();
12203                }
12204            }
12205        }
12206    }
12207
12208    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12209        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12210        if (procs == null) {
12211            pw.println("No process found for: " + args[0]);
12212            return;
12213        }
12214
12215        pw.println("Applications Database Info:");
12216
12217        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12218            ProcessRecord r = procs.get(i);
12219            if (r.thread != null) {
12220                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12221                pw.flush();
12222                try {
12223                    TransferPipe tp = new TransferPipe();
12224                    try {
12225                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12226                        tp.go(fd);
12227                    } finally {
12228                        tp.kill();
12229                    }
12230                } catch (IOException e) {
12231                    pw.println("Failure while dumping the app: " + r);
12232                    pw.flush();
12233                } catch (RemoteException e) {
12234                    pw.println("Got a RemoteException while dumping the app " + r);
12235                    pw.flush();
12236                }
12237            }
12238        }
12239    }
12240
12241    final static class MemItem {
12242        final boolean isProc;
12243        final String label;
12244        final String shortLabel;
12245        final long pss;
12246        final int id;
12247        final boolean hasActivities;
12248        ArrayList<MemItem> subitems;
12249
12250        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12251                boolean _hasActivities) {
12252            isProc = true;
12253            label = _label;
12254            shortLabel = _shortLabel;
12255            pss = _pss;
12256            id = _id;
12257            hasActivities = _hasActivities;
12258        }
12259
12260        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12261            isProc = false;
12262            label = _label;
12263            shortLabel = _shortLabel;
12264            pss = _pss;
12265            id = _id;
12266            hasActivities = false;
12267        }
12268    }
12269
12270    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12271            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12272        if (sort && !isCompact) {
12273            Collections.sort(items, new Comparator<MemItem>() {
12274                @Override
12275                public int compare(MemItem lhs, MemItem rhs) {
12276                    if (lhs.pss < rhs.pss) {
12277                        return 1;
12278                    } else if (lhs.pss > rhs.pss) {
12279                        return -1;
12280                    }
12281                    return 0;
12282                }
12283            });
12284        }
12285
12286        for (int i=0; i<items.size(); i++) {
12287            MemItem mi = items.get(i);
12288            if (!isCompact) {
12289                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12290            } else if (mi.isProc) {
12291                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12292                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12293                pw.println(mi.hasActivities ? ",a" : ",e");
12294            } else {
12295                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12296                pw.println(mi.pss);
12297            }
12298            if (mi.subitems != null) {
12299                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12300                        true, isCompact);
12301            }
12302        }
12303    }
12304
12305    // These are in KB.
12306    static final long[] DUMP_MEM_BUCKETS = new long[] {
12307        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12308        120*1024, 160*1024, 200*1024,
12309        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12310        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12311    };
12312
12313    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12314            boolean stackLike) {
12315        int start = label.lastIndexOf('.');
12316        if (start >= 0) start++;
12317        else start = 0;
12318        int end = label.length();
12319        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12320            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12321                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12322                out.append(bucket);
12323                out.append(stackLike ? "MB." : "MB ");
12324                out.append(label, start, end);
12325                return;
12326            }
12327        }
12328        out.append(memKB/1024);
12329        out.append(stackLike ? "MB." : "MB ");
12330        out.append(label, start, end);
12331    }
12332
12333    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12334            ProcessList.NATIVE_ADJ,
12335            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12336            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12337            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12338            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12339            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12340    };
12341    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12342            "Native",
12343            "System", "Persistent", "Foreground",
12344            "Visible", "Perceptible",
12345            "Heavy Weight", "Backup",
12346            "A Services", "Home",
12347            "Previous", "B Services", "Cached"
12348    };
12349    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12350            "native",
12351            "sys", "pers", "fore",
12352            "vis", "percept",
12353            "heavy", "backup",
12354            "servicea", "home",
12355            "prev", "serviceb", "cached"
12356    };
12357
12358    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12359            long realtime, boolean isCheckinRequest, boolean isCompact) {
12360        if (isCheckinRequest || isCompact) {
12361            // short checkin version
12362            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12363        } else {
12364            pw.println("Applications Memory Usage (kB):");
12365            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12366        }
12367    }
12368
12369    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12370            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12371        boolean dumpDetails = false;
12372        boolean dumpFullDetails = false;
12373        boolean dumpDalvik = false;
12374        boolean oomOnly = false;
12375        boolean isCompact = false;
12376        boolean localOnly = false;
12377
12378        int opti = 0;
12379        while (opti < args.length) {
12380            String opt = args[opti];
12381            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12382                break;
12383            }
12384            opti++;
12385            if ("-a".equals(opt)) {
12386                dumpDetails = true;
12387                dumpFullDetails = true;
12388                dumpDalvik = true;
12389            } else if ("-d".equals(opt)) {
12390                dumpDalvik = true;
12391            } else if ("-c".equals(opt)) {
12392                isCompact = true;
12393            } else if ("--oom".equals(opt)) {
12394                oomOnly = true;
12395            } else if ("--local".equals(opt)) {
12396                localOnly = true;
12397            } else if ("-h".equals(opt)) {
12398                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12399                pw.println("  -a: include all available information for each process.");
12400                pw.println("  -d: include dalvik details when dumping process details.");
12401                pw.println("  -c: dump in a compact machine-parseable representation.");
12402                pw.println("  --oom: only show processes organized by oom adj.");
12403                pw.println("  --local: only collect details locally, don't call process.");
12404                pw.println("If [process] is specified it can be the name or ");
12405                pw.println("pid of a specific process to dump.");
12406                return;
12407            } else {
12408                pw.println("Unknown argument: " + opt + "; use -h for help");
12409            }
12410        }
12411
12412        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12413        long uptime = SystemClock.uptimeMillis();
12414        long realtime = SystemClock.elapsedRealtime();
12415        final long[] tmpLong = new long[1];
12416
12417        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12418        if (procs == null) {
12419            // No Java processes.  Maybe they want to print a native process.
12420            if (args != null && args.length > opti
12421                    && args[opti].charAt(0) != '-') {
12422                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12423                        = new ArrayList<ProcessCpuTracker.Stats>();
12424                updateCpuStatsNow();
12425                int findPid = -1;
12426                try {
12427                    findPid = Integer.parseInt(args[opti]);
12428                } catch (NumberFormatException e) {
12429                }
12430                synchronized (mProcessCpuThread) {
12431                    final int N = mProcessCpuTracker.countStats();
12432                    for (int i=0; i<N; i++) {
12433                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12434                        if (st.pid == findPid || (st.baseName != null
12435                                && st.baseName.equals(args[opti]))) {
12436                            nativeProcs.add(st);
12437                        }
12438                    }
12439                }
12440                if (nativeProcs.size() > 0) {
12441                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12442                            isCompact);
12443                    Debug.MemoryInfo mi = null;
12444                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12445                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12446                        final int pid = r.pid;
12447                        if (!isCheckinRequest && dumpDetails) {
12448                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12449                        }
12450                        if (mi == null) {
12451                            mi = new Debug.MemoryInfo();
12452                        }
12453                        if (dumpDetails || (!brief && !oomOnly)) {
12454                            Debug.getMemoryInfo(pid, mi);
12455                        } else {
12456                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12457                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12458                        }
12459                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12460                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12461                        if (isCheckinRequest) {
12462                            pw.println();
12463                        }
12464                    }
12465                    return;
12466                }
12467            }
12468            pw.println("No process found for: " + args[opti]);
12469            return;
12470        }
12471
12472        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12473            dumpDetails = true;
12474        }
12475
12476        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12477
12478        String[] innerArgs = new String[args.length-opti];
12479        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12480
12481        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12482        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12483        long nativePss=0, dalvikPss=0, otherPss=0;
12484        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12485
12486        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12487        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12488                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12489
12490        long totalPss = 0;
12491        long cachedPss = 0;
12492
12493        Debug.MemoryInfo mi = null;
12494        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12495            final ProcessRecord r = procs.get(i);
12496            final IApplicationThread thread;
12497            final int pid;
12498            final int oomAdj;
12499            final boolean hasActivities;
12500            synchronized (this) {
12501                thread = r.thread;
12502                pid = r.pid;
12503                oomAdj = r.getSetAdjWithServices();
12504                hasActivities = r.activities.size() > 0;
12505            }
12506            if (thread != null) {
12507                if (!isCheckinRequest && dumpDetails) {
12508                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12509                }
12510                if (mi == null) {
12511                    mi = new Debug.MemoryInfo();
12512                }
12513                if (dumpDetails || (!brief && !oomOnly)) {
12514                    Debug.getMemoryInfo(pid, mi);
12515                } else {
12516                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12517                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12518                }
12519                if (dumpDetails) {
12520                    if (localOnly) {
12521                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12522                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12523                        if (isCheckinRequest) {
12524                            pw.println();
12525                        }
12526                    } else {
12527                        try {
12528                            pw.flush();
12529                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12530                                    dumpDalvik, innerArgs);
12531                        } catch (RemoteException e) {
12532                            if (!isCheckinRequest) {
12533                                pw.println("Got RemoteException!");
12534                                pw.flush();
12535                            }
12536                        }
12537                    }
12538                }
12539
12540                final long myTotalPss = mi.getTotalPss();
12541                final long myTotalUss = mi.getTotalUss();
12542
12543                synchronized (this) {
12544                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12545                        // Record this for posterity if the process has been stable.
12546                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12547                    }
12548                }
12549
12550                if (!isCheckinRequest && mi != null) {
12551                    totalPss += myTotalPss;
12552                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12553                            (hasActivities ? " / activities)" : ")"),
12554                            r.processName, myTotalPss, pid, hasActivities);
12555                    procMems.add(pssItem);
12556                    procMemsMap.put(pid, pssItem);
12557
12558                    nativePss += mi.nativePss;
12559                    dalvikPss += mi.dalvikPss;
12560                    otherPss += mi.otherPss;
12561                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12562                        long mem = mi.getOtherPss(j);
12563                        miscPss[j] += mem;
12564                        otherPss -= mem;
12565                    }
12566
12567                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12568                        cachedPss += myTotalPss;
12569                    }
12570
12571                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12572                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12573                                || oomIndex == (oomPss.length-1)) {
12574                            oomPss[oomIndex] += myTotalPss;
12575                            if (oomProcs[oomIndex] == null) {
12576                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12577                            }
12578                            oomProcs[oomIndex].add(pssItem);
12579                            break;
12580                        }
12581                    }
12582                }
12583            }
12584        }
12585
12586        if (!isCheckinRequest && procs.size() > 1) {
12587            // If we are showing aggregations, also look for native processes to
12588            // include so that our aggregations are more accurate.
12589            updateCpuStatsNow();
12590            synchronized (mProcessCpuThread) {
12591                final int N = mProcessCpuTracker.countStats();
12592                for (int i=0; i<N; i++) {
12593                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12594                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12595                        if (mi == null) {
12596                            mi = new Debug.MemoryInfo();
12597                        }
12598                        if (!brief && !oomOnly) {
12599                            Debug.getMemoryInfo(st.pid, mi);
12600                        } else {
12601                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12602                            mi.nativePrivateDirty = (int)tmpLong[0];
12603                        }
12604
12605                        final long myTotalPss = mi.getTotalPss();
12606                        totalPss += myTotalPss;
12607
12608                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12609                                st.name, myTotalPss, st.pid, false);
12610                        procMems.add(pssItem);
12611
12612                        nativePss += mi.nativePss;
12613                        dalvikPss += mi.dalvikPss;
12614                        otherPss += mi.otherPss;
12615                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12616                            long mem = mi.getOtherPss(j);
12617                            miscPss[j] += mem;
12618                            otherPss -= mem;
12619                        }
12620                        oomPss[0] += myTotalPss;
12621                        if (oomProcs[0] == null) {
12622                            oomProcs[0] = new ArrayList<MemItem>();
12623                        }
12624                        oomProcs[0].add(pssItem);
12625                    }
12626                }
12627            }
12628
12629            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12630
12631            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12632            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12633            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12634            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12635                String label = Debug.MemoryInfo.getOtherLabel(j);
12636                catMems.add(new MemItem(label, label, miscPss[j], j));
12637            }
12638
12639            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12640            for (int j=0; j<oomPss.length; j++) {
12641                if (oomPss[j] != 0) {
12642                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12643                            : DUMP_MEM_OOM_LABEL[j];
12644                    MemItem item = new MemItem(label, label, oomPss[j],
12645                            DUMP_MEM_OOM_ADJ[j]);
12646                    item.subitems = oomProcs[j];
12647                    oomMems.add(item);
12648                }
12649            }
12650
12651            if (!brief && !oomOnly && !isCompact) {
12652                pw.println();
12653                pw.println("Total PSS by process:");
12654                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12655                pw.println();
12656            }
12657            if (!isCompact) {
12658                pw.println("Total PSS by OOM adjustment:");
12659            }
12660            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12661            if (!brief && !oomOnly) {
12662                PrintWriter out = categoryPw != null ? categoryPw : pw;
12663                if (!isCompact) {
12664                    out.println();
12665                    out.println("Total PSS by category:");
12666                }
12667                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12668            }
12669            if (!isCompact) {
12670                pw.println();
12671            }
12672            MemInfoReader memInfo = new MemInfoReader();
12673            memInfo.readMemInfo();
12674            if (!brief) {
12675                if (!isCompact) {
12676                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12677                    pw.print(" kB (status ");
12678                    switch (mLastMemoryLevel) {
12679                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12680                            pw.println("normal)");
12681                            break;
12682                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12683                            pw.println("moderate)");
12684                            break;
12685                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12686                            pw.println("low)");
12687                            break;
12688                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12689                            pw.println("critical)");
12690                            break;
12691                        default:
12692                            pw.print(mLastMemoryLevel);
12693                            pw.println(")");
12694                            break;
12695                    }
12696                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12697                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12698                            pw.print(cachedPss); pw.print(" cached pss + ");
12699                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12700                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12701                } else {
12702                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12703                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12704                            + memInfo.getFreeSizeKb()); pw.print(",");
12705                    pw.println(totalPss - cachedPss);
12706                }
12707            }
12708            if (!isCompact) {
12709                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12710                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12711                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12712                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12713                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12714                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12715                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12716                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12717                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12718                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12719                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12720            }
12721            if (!brief) {
12722                if (memInfo.getZramTotalSizeKb() != 0) {
12723                    if (!isCompact) {
12724                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12725                                pw.print(" kB physical used for ");
12726                                pw.print(memInfo.getSwapTotalSizeKb()
12727                                        - memInfo.getSwapFreeSizeKb());
12728                                pw.print(" kB in swap (");
12729                                pw.print(memInfo.getSwapTotalSizeKb());
12730                                pw.println(" kB total swap)");
12731                    } else {
12732                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12733                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12734                                pw.println(memInfo.getSwapFreeSizeKb());
12735                    }
12736                }
12737                final int[] SINGLE_LONG_FORMAT = new int[] {
12738                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12739                };
12740                long[] longOut = new long[1];
12741                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12742                        SINGLE_LONG_FORMAT, null, longOut, null);
12743                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12744                longOut[0] = 0;
12745                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12746                        SINGLE_LONG_FORMAT, null, longOut, null);
12747                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12748                longOut[0] = 0;
12749                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12750                        SINGLE_LONG_FORMAT, null, longOut, null);
12751                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12752                longOut[0] = 0;
12753                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12754                        SINGLE_LONG_FORMAT, null, longOut, null);
12755                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12756                if (!isCompact) {
12757                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12758                        pw.print("      KSM: "); pw.print(sharing);
12759                                pw.print(" kB saved from shared ");
12760                                pw.print(shared); pw.println(" kB");
12761                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12762                                pw.print(voltile); pw.println(" kB volatile");
12763                    }
12764                    pw.print("   Tuning: ");
12765                    pw.print(ActivityManager.staticGetMemoryClass());
12766                    pw.print(" (large ");
12767                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12768                    pw.print("), oom ");
12769                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12770                    pw.print(" kB");
12771                    pw.print(", restore limit ");
12772                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12773                    pw.print(" kB");
12774                    if (ActivityManager.isLowRamDeviceStatic()) {
12775                        pw.print(" (low-ram)");
12776                    }
12777                    if (ActivityManager.isHighEndGfx()) {
12778                        pw.print(" (high-end-gfx)");
12779                    }
12780                    pw.println();
12781                } else {
12782                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12783                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12784                    pw.println(voltile);
12785                    pw.print("tuning,");
12786                    pw.print(ActivityManager.staticGetMemoryClass());
12787                    pw.print(',');
12788                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12789                    pw.print(',');
12790                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12791                    if (ActivityManager.isLowRamDeviceStatic()) {
12792                        pw.print(",low-ram");
12793                    }
12794                    if (ActivityManager.isHighEndGfx()) {
12795                        pw.print(",high-end-gfx");
12796                    }
12797                    pw.println();
12798                }
12799            }
12800        }
12801    }
12802
12803    /**
12804     * Searches array of arguments for the specified string
12805     * @param args array of argument strings
12806     * @param value value to search for
12807     * @return true if the value is contained in the array
12808     */
12809    private static boolean scanArgs(String[] args, String value) {
12810        if (args != null) {
12811            for (String arg : args) {
12812                if (value.equals(arg)) {
12813                    return true;
12814                }
12815            }
12816        }
12817        return false;
12818    }
12819
12820    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12821            ContentProviderRecord cpr, boolean always) {
12822        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12823
12824        if (!inLaunching || always) {
12825            synchronized (cpr) {
12826                cpr.launchingApp = null;
12827                cpr.notifyAll();
12828            }
12829            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12830            String names[] = cpr.info.authority.split(";");
12831            for (int j = 0; j < names.length; j++) {
12832                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12833            }
12834        }
12835
12836        for (int i=0; i<cpr.connections.size(); i++) {
12837            ContentProviderConnection conn = cpr.connections.get(i);
12838            if (conn.waiting) {
12839                // If this connection is waiting for the provider, then we don't
12840                // need to mess with its process unless we are always removing
12841                // or for some reason the provider is not currently launching.
12842                if (inLaunching && !always) {
12843                    continue;
12844                }
12845            }
12846            ProcessRecord capp = conn.client;
12847            conn.dead = true;
12848            if (conn.stableCount > 0) {
12849                if (!capp.persistent && capp.thread != null
12850                        && capp.pid != 0
12851                        && capp.pid != MY_PID) {
12852                    killUnneededProcessLocked(capp, "depends on provider "
12853                            + cpr.name.flattenToShortString()
12854                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12855                }
12856            } else if (capp.thread != null && conn.provider.provider != null) {
12857                try {
12858                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12859                } catch (RemoteException e) {
12860                }
12861                // In the protocol here, we don't expect the client to correctly
12862                // clean up this connection, we'll just remove it.
12863                cpr.connections.remove(i);
12864                conn.client.conProviders.remove(conn);
12865            }
12866        }
12867
12868        if (inLaunching && always) {
12869            mLaunchingProviders.remove(cpr);
12870        }
12871        return inLaunching;
12872    }
12873
12874    /**
12875     * Main code for cleaning up a process when it has gone away.  This is
12876     * called both as a result of the process dying, or directly when stopping
12877     * a process when running in single process mode.
12878     */
12879    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12880            boolean restarting, boolean allowRestart, int index) {
12881        if (index >= 0) {
12882            removeLruProcessLocked(app);
12883            ProcessList.remove(app.pid);
12884        }
12885
12886        mProcessesToGc.remove(app);
12887        mPendingPssProcesses.remove(app);
12888
12889        // Dismiss any open dialogs.
12890        if (app.crashDialog != null && !app.forceCrashReport) {
12891            app.crashDialog.dismiss();
12892            app.crashDialog = null;
12893        }
12894        if (app.anrDialog != null) {
12895            app.anrDialog.dismiss();
12896            app.anrDialog = null;
12897        }
12898        if (app.waitDialog != null) {
12899            app.waitDialog.dismiss();
12900            app.waitDialog = null;
12901        }
12902
12903        app.crashing = false;
12904        app.notResponding = false;
12905
12906        app.resetPackageList(mProcessStats);
12907        app.unlinkDeathRecipient();
12908        app.makeInactive(mProcessStats);
12909        app.forcingToForeground = null;
12910        updateProcessForegroundLocked(app, false, false);
12911        app.foregroundActivities = false;
12912        app.hasShownUi = false;
12913        app.treatLikeActivity = false;
12914        app.hasAboveClient = false;
12915        app.hasClientActivities = false;
12916
12917        mServices.killServicesLocked(app, allowRestart);
12918
12919        boolean restart = false;
12920
12921        // Remove published content providers.
12922        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12923            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12924            final boolean always = app.bad || !allowRestart;
12925            if (removeDyingProviderLocked(app, cpr, always) || always) {
12926                // We left the provider in the launching list, need to
12927                // restart it.
12928                restart = true;
12929            }
12930
12931            cpr.provider = null;
12932            cpr.proc = null;
12933        }
12934        app.pubProviders.clear();
12935
12936        // Take care of any launching providers waiting for this process.
12937        if (checkAppInLaunchingProvidersLocked(app, false)) {
12938            restart = true;
12939        }
12940
12941        // Unregister from connected content providers.
12942        if (!app.conProviders.isEmpty()) {
12943            for (int i=0; i<app.conProviders.size(); i++) {
12944                ContentProviderConnection conn = app.conProviders.get(i);
12945                conn.provider.connections.remove(conn);
12946            }
12947            app.conProviders.clear();
12948        }
12949
12950        // At this point there may be remaining entries in mLaunchingProviders
12951        // where we were the only one waiting, so they are no longer of use.
12952        // Look for these and clean up if found.
12953        // XXX Commented out for now.  Trying to figure out a way to reproduce
12954        // the actual situation to identify what is actually going on.
12955        if (false) {
12956            for (int i=0; i<mLaunchingProviders.size(); i++) {
12957                ContentProviderRecord cpr = (ContentProviderRecord)
12958                        mLaunchingProviders.get(i);
12959                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12960                    synchronized (cpr) {
12961                        cpr.launchingApp = null;
12962                        cpr.notifyAll();
12963                    }
12964                }
12965            }
12966        }
12967
12968        skipCurrentReceiverLocked(app);
12969
12970        // Unregister any receivers.
12971        for (int i=app.receivers.size()-1; i>=0; i--) {
12972            removeReceiverLocked(app.receivers.valueAt(i));
12973        }
12974        app.receivers.clear();
12975
12976        // If the app is undergoing backup, tell the backup manager about it
12977        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12978            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12979                    + mBackupTarget.appInfo + " died during backup");
12980            try {
12981                IBackupManager bm = IBackupManager.Stub.asInterface(
12982                        ServiceManager.getService(Context.BACKUP_SERVICE));
12983                bm.agentDisconnected(app.info.packageName);
12984            } catch (RemoteException e) {
12985                // can't happen; backup manager is local
12986            }
12987        }
12988
12989        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12990            ProcessChangeItem item = mPendingProcessChanges.get(i);
12991            if (item.pid == app.pid) {
12992                mPendingProcessChanges.remove(i);
12993                mAvailProcessChanges.add(item);
12994            }
12995        }
12996        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12997
12998        // If the caller is restarting this app, then leave it in its
12999        // current lists and let the caller take care of it.
13000        if (restarting) {
13001            return;
13002        }
13003
13004        if (!app.persistent || app.isolated) {
13005            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13006                    "Removing non-persistent process during cleanup: " + app);
13007            mProcessNames.remove(app.processName, app.uid);
13008            mIsolatedProcesses.remove(app.uid);
13009            if (mHeavyWeightProcess == app) {
13010                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13011                        mHeavyWeightProcess.userId, 0));
13012                mHeavyWeightProcess = null;
13013            }
13014        } else if (!app.removed) {
13015            // This app is persistent, so we need to keep its record around.
13016            // If it is not already on the pending app list, add it there
13017            // and start a new process for it.
13018            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13019                mPersistentStartingProcesses.add(app);
13020                restart = true;
13021            }
13022        }
13023        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13024                "Clean-up removing on hold: " + app);
13025        mProcessesOnHold.remove(app);
13026
13027        if (app == mHomeProcess) {
13028            mHomeProcess = null;
13029        }
13030        if (app == mPreviousProcess) {
13031            mPreviousProcess = null;
13032        }
13033
13034        if (restart && !app.isolated) {
13035            // We have components that still need to be running in the
13036            // process, so re-launch it.
13037            mProcessNames.put(app.processName, app.uid, app);
13038            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13039        } else if (app.pid > 0 && app.pid != MY_PID) {
13040            // Goodbye!
13041            boolean removed;
13042            synchronized (mPidsSelfLocked) {
13043                mPidsSelfLocked.remove(app.pid);
13044                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13045            }
13046            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13047                    app.processName, app.info.uid);
13048            if (app.isolated) {
13049                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13050            }
13051            app.setPid(0);
13052        }
13053    }
13054
13055    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13056        // Look through the content providers we are waiting to have launched,
13057        // and if any run in this process then either schedule a restart of
13058        // the process or kill the client waiting for it if this process has
13059        // gone bad.
13060        int NL = mLaunchingProviders.size();
13061        boolean restart = false;
13062        for (int i=0; i<NL; i++) {
13063            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13064            if (cpr.launchingApp == app) {
13065                if (!alwaysBad && !app.bad) {
13066                    restart = true;
13067                } else {
13068                    removeDyingProviderLocked(app, cpr, true);
13069                    // cpr should have been removed from mLaunchingProviders
13070                    NL = mLaunchingProviders.size();
13071                    i--;
13072                }
13073            }
13074        }
13075        return restart;
13076    }
13077
13078    // =========================================================
13079    // SERVICES
13080    // =========================================================
13081
13082    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13083            int flags) {
13084        enforceNotIsolatedCaller("getServices");
13085        synchronized (this) {
13086            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13087        }
13088    }
13089
13090    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13091        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13092        synchronized (this) {
13093            return mServices.getRunningServiceControlPanelLocked(name);
13094        }
13095    }
13096
13097    public ComponentName startService(IApplicationThread caller, Intent service,
13098            String resolvedType, int userId) {
13099        enforceNotIsolatedCaller("startService");
13100        // Refuse possible leaked file descriptors
13101        if (service != null && service.hasFileDescriptors() == true) {
13102            throw new IllegalArgumentException("File descriptors passed in Intent");
13103        }
13104
13105        if (DEBUG_SERVICE)
13106            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13107        synchronized(this) {
13108            final int callingPid = Binder.getCallingPid();
13109            final int callingUid = Binder.getCallingUid();
13110            final long origId = Binder.clearCallingIdentity();
13111            ComponentName res = mServices.startServiceLocked(caller, service,
13112                    resolvedType, callingPid, callingUid, userId);
13113            Binder.restoreCallingIdentity(origId);
13114            return res;
13115        }
13116    }
13117
13118    ComponentName startServiceInPackage(int uid,
13119            Intent service, String resolvedType, int userId) {
13120        synchronized(this) {
13121            if (DEBUG_SERVICE)
13122                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13123            final long origId = Binder.clearCallingIdentity();
13124            ComponentName res = mServices.startServiceLocked(null, service,
13125                    resolvedType, -1, uid, userId);
13126            Binder.restoreCallingIdentity(origId);
13127            return res;
13128        }
13129    }
13130
13131    public int stopService(IApplicationThread caller, Intent service,
13132            String resolvedType, int userId) {
13133        enforceNotIsolatedCaller("stopService");
13134        // Refuse possible leaked file descriptors
13135        if (service != null && service.hasFileDescriptors() == true) {
13136            throw new IllegalArgumentException("File descriptors passed in Intent");
13137        }
13138
13139        synchronized(this) {
13140            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13141        }
13142    }
13143
13144    public IBinder peekService(Intent service, String resolvedType) {
13145        enforceNotIsolatedCaller("peekService");
13146        // Refuse possible leaked file descriptors
13147        if (service != null && service.hasFileDescriptors() == true) {
13148            throw new IllegalArgumentException("File descriptors passed in Intent");
13149        }
13150        synchronized(this) {
13151            return mServices.peekServiceLocked(service, resolvedType);
13152        }
13153    }
13154
13155    public boolean stopServiceToken(ComponentName className, IBinder token,
13156            int startId) {
13157        synchronized(this) {
13158            return mServices.stopServiceTokenLocked(className, token, startId);
13159        }
13160    }
13161
13162    public void setServiceForeground(ComponentName className, IBinder token,
13163            int id, Notification notification, boolean removeNotification) {
13164        synchronized(this) {
13165            mServices.setServiceForegroundLocked(className, token, id, notification,
13166                    removeNotification);
13167        }
13168    }
13169
13170    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13171            boolean requireFull, String name, String callerPackage) {
13172        final int callingUserId = UserHandle.getUserId(callingUid);
13173        if (callingUserId != userId) {
13174            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13175                if ((requireFull || checkComponentPermission(
13176                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13177                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13178                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13179                                callingPid, callingUid, -1, true)
13180                                != PackageManager.PERMISSION_GRANTED) {
13181                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13182                        // In this case, they would like to just execute as their
13183                        // owner user instead of failing.
13184                        userId = callingUserId;
13185                    } else {
13186                        StringBuilder builder = new StringBuilder(128);
13187                        builder.append("Permission Denial: ");
13188                        builder.append(name);
13189                        if (callerPackage != null) {
13190                            builder.append(" from ");
13191                            builder.append(callerPackage);
13192                        }
13193                        builder.append(" asks to run as user ");
13194                        builder.append(userId);
13195                        builder.append(" but is calling from user ");
13196                        builder.append(UserHandle.getUserId(callingUid));
13197                        builder.append("; this requires ");
13198                        builder.append(INTERACT_ACROSS_USERS_FULL);
13199                        if (!requireFull) {
13200                            builder.append(" or ");
13201                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13202                        }
13203                        String msg = builder.toString();
13204                        Slog.w(TAG, msg);
13205                        throw new SecurityException(msg);
13206                    }
13207                }
13208            }
13209            if (userId == UserHandle.USER_CURRENT
13210                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13211                // Note that we may be accessing this outside of a lock...
13212                // shouldn't be a big deal, if this is being called outside
13213                // of a locked context there is intrinsically a race with
13214                // the value the caller will receive and someone else changing it.
13215                userId = mCurrentUserId;
13216            }
13217            if (!allowAll && userId < 0) {
13218                throw new IllegalArgumentException(
13219                        "Call does not support special user #" + userId);
13220            }
13221        }
13222        return userId;
13223    }
13224
13225    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13226            String className, int flags) {
13227        boolean result = false;
13228        // For apps that don't have pre-defined UIDs, check for permission
13229        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13230            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13231                if (ActivityManager.checkUidPermission(
13232                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13233                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13234                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13235                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13236                            + " requests FLAG_SINGLE_USER, but app does not hold "
13237                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13238                    Slog.w(TAG, msg);
13239                    throw new SecurityException(msg);
13240                }
13241                // Permission passed
13242                result = true;
13243            }
13244        } else if ("system".equals(componentProcessName)) {
13245            result = true;
13246        } else {
13247            // App with pre-defined UID, check if it's a persistent app
13248            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13249        }
13250        if (DEBUG_MU) {
13251            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13252                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13253        }
13254        return result;
13255    }
13256
13257    /**
13258     * Checks to see if the caller is in the same app as the singleton
13259     * component, or the component is in a special app. It allows special apps
13260     * to export singleton components but prevents exporting singleton
13261     * components for regular apps.
13262     */
13263    boolean isValidSingletonCall(int callingUid, int componentUid) {
13264        int componentAppId = UserHandle.getAppId(componentUid);
13265        return UserHandle.isSameApp(callingUid, componentUid)
13266                || componentAppId == Process.SYSTEM_UID
13267                || componentAppId == Process.PHONE_UID
13268                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13269                        == PackageManager.PERMISSION_GRANTED;
13270    }
13271
13272    public int bindService(IApplicationThread caller, IBinder token,
13273            Intent service, String resolvedType,
13274            IServiceConnection connection, int flags, int userId) {
13275        enforceNotIsolatedCaller("bindService");
13276        // Refuse possible leaked file descriptors
13277        if (service != null && service.hasFileDescriptors() == true) {
13278            throw new IllegalArgumentException("File descriptors passed in Intent");
13279        }
13280
13281        synchronized(this) {
13282            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13283                    connection, flags, userId);
13284        }
13285    }
13286
13287    public boolean unbindService(IServiceConnection connection) {
13288        synchronized (this) {
13289            return mServices.unbindServiceLocked(connection);
13290        }
13291    }
13292
13293    public void publishService(IBinder token, Intent intent, IBinder service) {
13294        // Refuse possible leaked file descriptors
13295        if (intent != null && intent.hasFileDescriptors() == true) {
13296            throw new IllegalArgumentException("File descriptors passed in Intent");
13297        }
13298
13299        synchronized(this) {
13300            if (!(token instanceof ServiceRecord)) {
13301                throw new IllegalArgumentException("Invalid service token");
13302            }
13303            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13304        }
13305    }
13306
13307    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13308        // Refuse possible leaked file descriptors
13309        if (intent != null && intent.hasFileDescriptors() == true) {
13310            throw new IllegalArgumentException("File descriptors passed in Intent");
13311        }
13312
13313        synchronized(this) {
13314            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13315        }
13316    }
13317
13318    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13319        synchronized(this) {
13320            if (!(token instanceof ServiceRecord)) {
13321                throw new IllegalArgumentException("Invalid service token");
13322            }
13323            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13324        }
13325    }
13326
13327    // =========================================================
13328    // BACKUP AND RESTORE
13329    // =========================================================
13330
13331    // Cause the target app to be launched if necessary and its backup agent
13332    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13333    // activity manager to announce its creation.
13334    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13335        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13336        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13337
13338        synchronized(this) {
13339            // !!! TODO: currently no check here that we're already bound
13340            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13341            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13342            synchronized (stats) {
13343                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13344            }
13345
13346            // Backup agent is now in use, its package can't be stopped.
13347            try {
13348                AppGlobals.getPackageManager().setPackageStoppedState(
13349                        app.packageName, false, UserHandle.getUserId(app.uid));
13350            } catch (RemoteException e) {
13351            } catch (IllegalArgumentException e) {
13352                Slog.w(TAG, "Failed trying to unstop package "
13353                        + app.packageName + ": " + e);
13354            }
13355
13356            BackupRecord r = new BackupRecord(ss, app, backupMode);
13357            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13358                    ? new ComponentName(app.packageName, app.backupAgentName)
13359                    : new ComponentName("android", "FullBackupAgent");
13360            // startProcessLocked() returns existing proc's record if it's already running
13361            ProcessRecord proc = startProcessLocked(app.processName, app,
13362                    false, 0, "backup", hostingName, false, false, false);
13363            if (proc == null) {
13364                Slog.e(TAG, "Unable to start backup agent process " + r);
13365                return false;
13366            }
13367
13368            r.app = proc;
13369            mBackupTarget = r;
13370            mBackupAppName = app.packageName;
13371
13372            // Try not to kill the process during backup
13373            updateOomAdjLocked(proc);
13374
13375            // If the process is already attached, schedule the creation of the backup agent now.
13376            // If it is not yet live, this will be done when it attaches to the framework.
13377            if (proc.thread != null) {
13378                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13379                try {
13380                    proc.thread.scheduleCreateBackupAgent(app,
13381                            compatibilityInfoForPackageLocked(app), backupMode);
13382                } catch (RemoteException e) {
13383                    // Will time out on the backup manager side
13384                }
13385            } else {
13386                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13387            }
13388            // Invariants: at this point, the target app process exists and the application
13389            // is either already running or in the process of coming up.  mBackupTarget and
13390            // mBackupAppName describe the app, so that when it binds back to the AM we
13391            // know that it's scheduled for a backup-agent operation.
13392        }
13393
13394        return true;
13395    }
13396
13397    @Override
13398    public void clearPendingBackup() {
13399        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13400        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13401
13402        synchronized (this) {
13403            mBackupTarget = null;
13404            mBackupAppName = null;
13405        }
13406    }
13407
13408    // A backup agent has just come up
13409    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13410        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13411                + " = " + agent);
13412
13413        synchronized(this) {
13414            if (!agentPackageName.equals(mBackupAppName)) {
13415                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13416                return;
13417            }
13418        }
13419
13420        long oldIdent = Binder.clearCallingIdentity();
13421        try {
13422            IBackupManager bm = IBackupManager.Stub.asInterface(
13423                    ServiceManager.getService(Context.BACKUP_SERVICE));
13424            bm.agentConnected(agentPackageName, agent);
13425        } catch (RemoteException e) {
13426            // can't happen; the backup manager service is local
13427        } catch (Exception e) {
13428            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13429            e.printStackTrace();
13430        } finally {
13431            Binder.restoreCallingIdentity(oldIdent);
13432        }
13433    }
13434
13435    // done with this agent
13436    public void unbindBackupAgent(ApplicationInfo appInfo) {
13437        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13438        if (appInfo == null) {
13439            Slog.w(TAG, "unbind backup agent for null app");
13440            return;
13441        }
13442
13443        synchronized(this) {
13444            try {
13445                if (mBackupAppName == null) {
13446                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13447                    return;
13448                }
13449
13450                if (!mBackupAppName.equals(appInfo.packageName)) {
13451                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13452                    return;
13453                }
13454
13455                // Not backing this app up any more; reset its OOM adjustment
13456                final ProcessRecord proc = mBackupTarget.app;
13457                updateOomAdjLocked(proc);
13458
13459                // If the app crashed during backup, 'thread' will be null here
13460                if (proc.thread != null) {
13461                    try {
13462                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13463                                compatibilityInfoForPackageLocked(appInfo));
13464                    } catch (Exception e) {
13465                        Slog.e(TAG, "Exception when unbinding backup agent:");
13466                        e.printStackTrace();
13467                    }
13468                }
13469            } finally {
13470                mBackupTarget = null;
13471                mBackupAppName = null;
13472            }
13473        }
13474    }
13475    // =========================================================
13476    // BROADCASTS
13477    // =========================================================
13478
13479    private final List getStickiesLocked(String action, IntentFilter filter,
13480            List cur, int userId) {
13481        final ContentResolver resolver = mContext.getContentResolver();
13482        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13483        if (stickies == null) {
13484            return cur;
13485        }
13486        final ArrayList<Intent> list = stickies.get(action);
13487        if (list == null) {
13488            return cur;
13489        }
13490        int N = list.size();
13491        for (int i=0; i<N; i++) {
13492            Intent intent = list.get(i);
13493            if (filter.match(resolver, intent, true, TAG) >= 0) {
13494                if (cur == null) {
13495                    cur = new ArrayList<Intent>();
13496                }
13497                cur.add(intent);
13498            }
13499        }
13500        return cur;
13501    }
13502
13503    boolean isPendingBroadcastProcessLocked(int pid) {
13504        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13505                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13506    }
13507
13508    void skipPendingBroadcastLocked(int pid) {
13509            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13510            for (BroadcastQueue queue : mBroadcastQueues) {
13511                queue.skipPendingBroadcastLocked(pid);
13512            }
13513    }
13514
13515    // The app just attached; send any pending broadcasts that it should receive
13516    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13517        boolean didSomething = false;
13518        for (BroadcastQueue queue : mBroadcastQueues) {
13519            didSomething |= queue.sendPendingBroadcastsLocked(app);
13520        }
13521        return didSomething;
13522    }
13523
13524    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13525            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13526        enforceNotIsolatedCaller("registerReceiver");
13527        int callingUid;
13528        int callingPid;
13529        synchronized(this) {
13530            ProcessRecord callerApp = null;
13531            if (caller != null) {
13532                callerApp = getRecordForAppLocked(caller);
13533                if (callerApp == null) {
13534                    throw new SecurityException(
13535                            "Unable to find app for caller " + caller
13536                            + " (pid=" + Binder.getCallingPid()
13537                            + ") when registering receiver " + receiver);
13538                }
13539                if (callerApp.info.uid != Process.SYSTEM_UID &&
13540                        !callerApp.pkgList.containsKey(callerPackage) &&
13541                        !"android".equals(callerPackage)) {
13542                    throw new SecurityException("Given caller package " + callerPackage
13543                            + " is not running in process " + callerApp);
13544                }
13545                callingUid = callerApp.info.uid;
13546                callingPid = callerApp.pid;
13547            } else {
13548                callerPackage = null;
13549                callingUid = Binder.getCallingUid();
13550                callingPid = Binder.getCallingPid();
13551            }
13552
13553            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13554                    true, true, "registerReceiver", callerPackage);
13555
13556            List allSticky = null;
13557
13558            // Look for any matching sticky broadcasts...
13559            Iterator actions = filter.actionsIterator();
13560            if (actions != null) {
13561                while (actions.hasNext()) {
13562                    String action = (String)actions.next();
13563                    allSticky = getStickiesLocked(action, filter, allSticky,
13564                            UserHandle.USER_ALL);
13565                    allSticky = getStickiesLocked(action, filter, allSticky,
13566                            UserHandle.getUserId(callingUid));
13567                }
13568            } else {
13569                allSticky = getStickiesLocked(null, filter, allSticky,
13570                        UserHandle.USER_ALL);
13571                allSticky = getStickiesLocked(null, filter, allSticky,
13572                        UserHandle.getUserId(callingUid));
13573            }
13574
13575            // The first sticky in the list is returned directly back to
13576            // the client.
13577            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13578
13579            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13580                    + ": " + sticky);
13581
13582            if (receiver == null) {
13583                return sticky;
13584            }
13585
13586            ReceiverList rl
13587                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13588            if (rl == null) {
13589                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13590                        userId, receiver);
13591                if (rl.app != null) {
13592                    rl.app.receivers.add(rl);
13593                } else {
13594                    try {
13595                        receiver.asBinder().linkToDeath(rl, 0);
13596                    } catch (RemoteException e) {
13597                        return sticky;
13598                    }
13599                    rl.linkedToDeath = true;
13600                }
13601                mRegisteredReceivers.put(receiver.asBinder(), rl);
13602            } else if (rl.uid != callingUid) {
13603                throw new IllegalArgumentException(
13604                        "Receiver requested to register for uid " + callingUid
13605                        + " was previously registered for uid " + rl.uid);
13606            } else if (rl.pid != callingPid) {
13607                throw new IllegalArgumentException(
13608                        "Receiver requested to register for pid " + callingPid
13609                        + " was previously registered for pid " + rl.pid);
13610            } else if (rl.userId != userId) {
13611                throw new IllegalArgumentException(
13612                        "Receiver requested to register for user " + userId
13613                        + " was previously registered for user " + rl.userId);
13614            }
13615            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13616                    permission, callingUid, userId);
13617            rl.add(bf);
13618            if (!bf.debugCheck()) {
13619                Slog.w(TAG, "==> For Dynamic broadast");
13620            }
13621            mReceiverResolver.addFilter(bf);
13622
13623            // Enqueue broadcasts for all existing stickies that match
13624            // this filter.
13625            if (allSticky != null) {
13626                ArrayList receivers = new ArrayList();
13627                receivers.add(bf);
13628
13629                int N = allSticky.size();
13630                for (int i=0; i<N; i++) {
13631                    Intent intent = (Intent)allSticky.get(i);
13632                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13633                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13634                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13635                            null, null, false, true, true, -1);
13636                    queue.enqueueParallelBroadcastLocked(r);
13637                    queue.scheduleBroadcastsLocked();
13638                }
13639            }
13640
13641            return sticky;
13642        }
13643    }
13644
13645    public void unregisterReceiver(IIntentReceiver receiver) {
13646        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13647
13648        final long origId = Binder.clearCallingIdentity();
13649        try {
13650            boolean doTrim = false;
13651
13652            synchronized(this) {
13653                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13654                if (rl != null) {
13655                    if (rl.curBroadcast != null) {
13656                        BroadcastRecord r = rl.curBroadcast;
13657                        final boolean doNext = finishReceiverLocked(
13658                                receiver.asBinder(), r.resultCode, r.resultData,
13659                                r.resultExtras, r.resultAbort);
13660                        if (doNext) {
13661                            doTrim = true;
13662                            r.queue.processNextBroadcast(false);
13663                        }
13664                    }
13665
13666                    if (rl.app != null) {
13667                        rl.app.receivers.remove(rl);
13668                    }
13669                    removeReceiverLocked(rl);
13670                    if (rl.linkedToDeath) {
13671                        rl.linkedToDeath = false;
13672                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13673                    }
13674                }
13675            }
13676
13677            // If we actually concluded any broadcasts, we might now be able
13678            // to trim the recipients' apps from our working set
13679            if (doTrim) {
13680                trimApplications();
13681                return;
13682            }
13683
13684        } finally {
13685            Binder.restoreCallingIdentity(origId);
13686        }
13687    }
13688
13689    void removeReceiverLocked(ReceiverList rl) {
13690        mRegisteredReceivers.remove(rl.receiver.asBinder());
13691        int N = rl.size();
13692        for (int i=0; i<N; i++) {
13693            mReceiverResolver.removeFilter(rl.get(i));
13694        }
13695    }
13696
13697    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13698        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13699            ProcessRecord r = mLruProcesses.get(i);
13700            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13701                try {
13702                    r.thread.dispatchPackageBroadcast(cmd, packages);
13703                } catch (RemoteException ex) {
13704                }
13705            }
13706        }
13707    }
13708
13709    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13710            int[] users) {
13711        List<ResolveInfo> receivers = null;
13712        try {
13713            HashSet<ComponentName> singleUserReceivers = null;
13714            boolean scannedFirstReceivers = false;
13715            for (int user : users) {
13716                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13717                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13718                if (user != 0 && newReceivers != null) {
13719                    // If this is not the primary user, we need to check for
13720                    // any receivers that should be filtered out.
13721                    for (int i=0; i<newReceivers.size(); i++) {
13722                        ResolveInfo ri = newReceivers.get(i);
13723                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13724                            newReceivers.remove(i);
13725                            i--;
13726                        }
13727                    }
13728                }
13729                if (newReceivers != null && newReceivers.size() == 0) {
13730                    newReceivers = null;
13731                }
13732                if (receivers == null) {
13733                    receivers = newReceivers;
13734                } else if (newReceivers != null) {
13735                    // We need to concatenate the additional receivers
13736                    // found with what we have do far.  This would be easy,
13737                    // but we also need to de-dup any receivers that are
13738                    // singleUser.
13739                    if (!scannedFirstReceivers) {
13740                        // Collect any single user receivers we had already retrieved.
13741                        scannedFirstReceivers = true;
13742                        for (int i=0; i<receivers.size(); i++) {
13743                            ResolveInfo ri = receivers.get(i);
13744                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13745                                ComponentName cn = new ComponentName(
13746                                        ri.activityInfo.packageName, ri.activityInfo.name);
13747                                if (singleUserReceivers == null) {
13748                                    singleUserReceivers = new HashSet<ComponentName>();
13749                                }
13750                                singleUserReceivers.add(cn);
13751                            }
13752                        }
13753                    }
13754                    // Add the new results to the existing results, tracking
13755                    // and de-dupping single user receivers.
13756                    for (int i=0; i<newReceivers.size(); i++) {
13757                        ResolveInfo ri = newReceivers.get(i);
13758                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13759                            ComponentName cn = new ComponentName(
13760                                    ri.activityInfo.packageName, ri.activityInfo.name);
13761                            if (singleUserReceivers == null) {
13762                                singleUserReceivers = new HashSet<ComponentName>();
13763                            }
13764                            if (!singleUserReceivers.contains(cn)) {
13765                                singleUserReceivers.add(cn);
13766                                receivers.add(ri);
13767                            }
13768                        } else {
13769                            receivers.add(ri);
13770                        }
13771                    }
13772                }
13773            }
13774        } catch (RemoteException ex) {
13775            // pm is in same process, this will never happen.
13776        }
13777        return receivers;
13778    }
13779
13780    private final int broadcastIntentLocked(ProcessRecord callerApp,
13781            String callerPackage, Intent intent, String resolvedType,
13782            IIntentReceiver resultTo, int resultCode, String resultData,
13783            Bundle map, String requiredPermission, int appOp,
13784            boolean ordered, boolean sticky, int callingPid, int callingUid,
13785            int userId) {
13786        intent = new Intent(intent);
13787
13788        // By default broadcasts do not go to stopped apps.
13789        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13790
13791        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13792            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13793            + " ordered=" + ordered + " userid=" + userId);
13794        if ((resultTo != null) && !ordered) {
13795            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13796        }
13797
13798        userId = handleIncomingUser(callingPid, callingUid, userId,
13799                true, false, "broadcast", callerPackage);
13800
13801        // Make sure that the user who is receiving this broadcast is started.
13802        // If not, we will just skip it.
13803        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13804            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13805                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13806                Slog.w(TAG, "Skipping broadcast of " + intent
13807                        + ": user " + userId + " is stopped");
13808                return ActivityManager.BROADCAST_SUCCESS;
13809            }
13810        }
13811
13812        /*
13813         * Prevent non-system code (defined here to be non-persistent
13814         * processes) from sending protected broadcasts.
13815         */
13816        int callingAppId = UserHandle.getAppId(callingUid);
13817        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13818                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13819                || callingUid == 0) {
13820            // Always okay.
13821        } else if (callerApp == null || !callerApp.persistent) {
13822            try {
13823                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13824                        intent.getAction())) {
13825                    String msg = "Permission Denial: not allowed to send broadcast "
13826                            + intent.getAction() + " from pid="
13827                            + callingPid + ", uid=" + callingUid;
13828                    Slog.w(TAG, msg);
13829                    throw new SecurityException(msg);
13830                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13831                    // Special case for compatibility: we don't want apps to send this,
13832                    // but historically it has not been protected and apps may be using it
13833                    // to poke their own app widget.  So, instead of making it protected,
13834                    // just limit it to the caller.
13835                    if (callerApp == null) {
13836                        String msg = "Permission Denial: not allowed to send broadcast "
13837                                + intent.getAction() + " from unknown caller.";
13838                        Slog.w(TAG, msg);
13839                        throw new SecurityException(msg);
13840                    } else if (intent.getComponent() != null) {
13841                        // They are good enough to send to an explicit component...  verify
13842                        // it is being sent to the calling app.
13843                        if (!intent.getComponent().getPackageName().equals(
13844                                callerApp.info.packageName)) {
13845                            String msg = "Permission Denial: not allowed to send broadcast "
13846                                    + intent.getAction() + " to "
13847                                    + intent.getComponent().getPackageName() + " from "
13848                                    + callerApp.info.packageName;
13849                            Slog.w(TAG, msg);
13850                            throw new SecurityException(msg);
13851                        }
13852                    } else {
13853                        // Limit broadcast to their own package.
13854                        intent.setPackage(callerApp.info.packageName);
13855                    }
13856                }
13857            } catch (RemoteException e) {
13858                Slog.w(TAG, "Remote exception", e);
13859                return ActivityManager.BROADCAST_SUCCESS;
13860            }
13861        }
13862
13863        // Handle special intents: if this broadcast is from the package
13864        // manager about a package being removed, we need to remove all of
13865        // its activities from the history stack.
13866        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13867                intent.getAction());
13868        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13869                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13870                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13871                || uidRemoved) {
13872            if (checkComponentPermission(
13873                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13874                    callingPid, callingUid, -1, true)
13875                    == PackageManager.PERMISSION_GRANTED) {
13876                if (uidRemoved) {
13877                    final Bundle intentExtras = intent.getExtras();
13878                    final int uid = intentExtras != null
13879                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13880                    if (uid >= 0) {
13881                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13882                        synchronized (bs) {
13883                            bs.removeUidStatsLocked(uid);
13884                        }
13885                        mAppOpsService.uidRemoved(uid);
13886                    }
13887                } else {
13888                    // If resources are unavailable just force stop all
13889                    // those packages and flush the attribute cache as well.
13890                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13891                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13892                        if (list != null && (list.length > 0)) {
13893                            for (String pkg : list) {
13894                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13895                                        "storage unmount");
13896                            }
13897                            sendPackageBroadcastLocked(
13898                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13899                        }
13900                    } else {
13901                        Uri data = intent.getData();
13902                        String ssp;
13903                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13904                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13905                                    intent.getAction());
13906                            boolean fullUninstall = removed &&
13907                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13908                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13909                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13910                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13911                                        false, fullUninstall, userId,
13912                                        removed ? "pkg removed" : "pkg changed");
13913                            }
13914                            if (removed) {
13915                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13916                                        new String[] {ssp}, userId);
13917                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13918                                    mAppOpsService.packageRemoved(
13919                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13920
13921                                    // Remove all permissions granted from/to this package
13922                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13923                                }
13924                            }
13925                        }
13926                    }
13927                }
13928            } else {
13929                String msg = "Permission Denial: " + intent.getAction()
13930                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13931                        + ", uid=" + callingUid + ")"
13932                        + " requires "
13933                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13934                Slog.w(TAG, msg);
13935                throw new SecurityException(msg);
13936            }
13937
13938        // Special case for adding a package: by default turn on compatibility
13939        // mode.
13940        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13941            Uri data = intent.getData();
13942            String ssp;
13943            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13944                mCompatModePackages.handlePackageAddedLocked(ssp,
13945                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13946            }
13947        }
13948
13949        /*
13950         * If this is the time zone changed action, queue up a message that will reset the timezone
13951         * of all currently running processes. This message will get queued up before the broadcast
13952         * happens.
13953         */
13954        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13955            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13956        }
13957
13958        /*
13959         * If the user set the time, let all running processes know.
13960         */
13961        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13962            final int is24Hour = intent.getBooleanExtra(
13963                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13964            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13965        }
13966
13967        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13968            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13969        }
13970
13971        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13972            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13973            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13974        }
13975
13976        // Add to the sticky list if requested.
13977        if (sticky) {
13978            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13979                    callingPid, callingUid)
13980                    != PackageManager.PERMISSION_GRANTED) {
13981                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13982                        + callingPid + ", uid=" + callingUid
13983                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13984                Slog.w(TAG, msg);
13985                throw new SecurityException(msg);
13986            }
13987            if (requiredPermission != null) {
13988                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13989                        + " and enforce permission " + requiredPermission);
13990                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13991            }
13992            if (intent.getComponent() != null) {
13993                throw new SecurityException(
13994                        "Sticky broadcasts can't target a specific component");
13995            }
13996            // We use userId directly here, since the "all" target is maintained
13997            // as a separate set of sticky broadcasts.
13998            if (userId != UserHandle.USER_ALL) {
13999                // But first, if this is not a broadcast to all users, then
14000                // make sure it doesn't conflict with an existing broadcast to
14001                // all users.
14002                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14003                        UserHandle.USER_ALL);
14004                if (stickies != null) {
14005                    ArrayList<Intent> list = stickies.get(intent.getAction());
14006                    if (list != null) {
14007                        int N = list.size();
14008                        int i;
14009                        for (i=0; i<N; i++) {
14010                            if (intent.filterEquals(list.get(i))) {
14011                                throw new IllegalArgumentException(
14012                                        "Sticky broadcast " + intent + " for user "
14013                                        + userId + " conflicts with existing global broadcast");
14014                            }
14015                        }
14016                    }
14017                }
14018            }
14019            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14020            if (stickies == null) {
14021                stickies = new ArrayMap<String, ArrayList<Intent>>();
14022                mStickyBroadcasts.put(userId, stickies);
14023            }
14024            ArrayList<Intent> list = stickies.get(intent.getAction());
14025            if (list == null) {
14026                list = new ArrayList<Intent>();
14027                stickies.put(intent.getAction(), list);
14028            }
14029            int N = list.size();
14030            int i;
14031            for (i=0; i<N; i++) {
14032                if (intent.filterEquals(list.get(i))) {
14033                    // This sticky already exists, replace it.
14034                    list.set(i, new Intent(intent));
14035                    break;
14036                }
14037            }
14038            if (i >= N) {
14039                list.add(new Intent(intent));
14040            }
14041        }
14042
14043        int[] users;
14044        if (userId == UserHandle.USER_ALL) {
14045            // Caller wants broadcast to go to all started users.
14046            users = mStartedUserArray;
14047        } else {
14048            // Caller wants broadcast to go to one specific user.
14049            users = new int[] {userId};
14050        }
14051
14052        // Figure out who all will receive this broadcast.
14053        List receivers = null;
14054        List<BroadcastFilter> registeredReceivers = null;
14055        // Need to resolve the intent to interested receivers...
14056        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14057                 == 0) {
14058            receivers = collectReceiverComponents(intent, resolvedType, users);
14059        }
14060        if (intent.getComponent() == null) {
14061            registeredReceivers = mReceiverResolver.queryIntent(intent,
14062                    resolvedType, false, userId);
14063        }
14064
14065        final boolean replacePending =
14066                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14067
14068        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14069                + " replacePending=" + replacePending);
14070
14071        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14072        if (!ordered && NR > 0) {
14073            // If we are not serializing this broadcast, then send the
14074            // registered receivers separately so they don't wait for the
14075            // components to be launched.
14076            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14077            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14078                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14079                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14080                    ordered, sticky, false, userId);
14081            if (DEBUG_BROADCAST) Slog.v(
14082                    TAG, "Enqueueing parallel broadcast " + r);
14083            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14084            if (!replaced) {
14085                queue.enqueueParallelBroadcastLocked(r);
14086                queue.scheduleBroadcastsLocked();
14087            }
14088            registeredReceivers = null;
14089            NR = 0;
14090        }
14091
14092        // Merge into one list.
14093        int ir = 0;
14094        if (receivers != null) {
14095            // A special case for PACKAGE_ADDED: do not allow the package
14096            // being added to see this broadcast.  This prevents them from
14097            // using this as a back door to get run as soon as they are
14098            // installed.  Maybe in the future we want to have a special install
14099            // broadcast or such for apps, but we'd like to deliberately make
14100            // this decision.
14101            String skipPackages[] = null;
14102            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14103                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14104                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14105                Uri data = intent.getData();
14106                if (data != null) {
14107                    String pkgName = data.getSchemeSpecificPart();
14108                    if (pkgName != null) {
14109                        skipPackages = new String[] { pkgName };
14110                    }
14111                }
14112            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14113                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14114            }
14115            if (skipPackages != null && (skipPackages.length > 0)) {
14116                for (String skipPackage : skipPackages) {
14117                    if (skipPackage != null) {
14118                        int NT = receivers.size();
14119                        for (int it=0; it<NT; it++) {
14120                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14121                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14122                                receivers.remove(it);
14123                                it--;
14124                                NT--;
14125                            }
14126                        }
14127                    }
14128                }
14129            }
14130
14131            int NT = receivers != null ? receivers.size() : 0;
14132            int it = 0;
14133            ResolveInfo curt = null;
14134            BroadcastFilter curr = null;
14135            while (it < NT && ir < NR) {
14136                if (curt == null) {
14137                    curt = (ResolveInfo)receivers.get(it);
14138                }
14139                if (curr == null) {
14140                    curr = registeredReceivers.get(ir);
14141                }
14142                if (curr.getPriority() >= curt.priority) {
14143                    // Insert this broadcast record into the final list.
14144                    receivers.add(it, curr);
14145                    ir++;
14146                    curr = null;
14147                    it++;
14148                    NT++;
14149                } else {
14150                    // Skip to the next ResolveInfo in the final list.
14151                    it++;
14152                    curt = null;
14153                }
14154            }
14155        }
14156        while (ir < NR) {
14157            if (receivers == null) {
14158                receivers = new ArrayList();
14159            }
14160            receivers.add(registeredReceivers.get(ir));
14161            ir++;
14162        }
14163
14164        if ((receivers != null && receivers.size() > 0)
14165                || resultTo != null) {
14166            BroadcastQueue queue = broadcastQueueForIntent(intent);
14167            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14168                    callerPackage, callingPid, callingUid, resolvedType,
14169                    requiredPermission, appOp, receivers, resultTo, resultCode,
14170                    resultData, map, ordered, sticky, false, userId);
14171            if (DEBUG_BROADCAST) Slog.v(
14172                    TAG, "Enqueueing ordered broadcast " + r
14173                    + ": prev had " + queue.mOrderedBroadcasts.size());
14174            if (DEBUG_BROADCAST) {
14175                int seq = r.intent.getIntExtra("seq", -1);
14176                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14177            }
14178            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14179            if (!replaced) {
14180                queue.enqueueOrderedBroadcastLocked(r);
14181                queue.scheduleBroadcastsLocked();
14182            }
14183        }
14184
14185        return ActivityManager.BROADCAST_SUCCESS;
14186    }
14187
14188    final Intent verifyBroadcastLocked(Intent intent) {
14189        // Refuse possible leaked file descriptors
14190        if (intent != null && intent.hasFileDescriptors() == true) {
14191            throw new IllegalArgumentException("File descriptors passed in Intent");
14192        }
14193
14194        int flags = intent.getFlags();
14195
14196        if (!mProcessesReady) {
14197            // if the caller really truly claims to know what they're doing, go
14198            // ahead and allow the broadcast without launching any receivers
14199            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14200                intent = new Intent(intent);
14201                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14202            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14203                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14204                        + " before boot completion");
14205                throw new IllegalStateException("Cannot broadcast before boot completed");
14206            }
14207        }
14208
14209        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14210            throw new IllegalArgumentException(
14211                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14212        }
14213
14214        return intent;
14215    }
14216
14217    public final int broadcastIntent(IApplicationThread caller,
14218            Intent intent, String resolvedType, IIntentReceiver resultTo,
14219            int resultCode, String resultData, Bundle map,
14220            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14221        enforceNotIsolatedCaller("broadcastIntent");
14222        synchronized(this) {
14223            intent = verifyBroadcastLocked(intent);
14224
14225            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14226            final int callingPid = Binder.getCallingPid();
14227            final int callingUid = Binder.getCallingUid();
14228            final long origId = Binder.clearCallingIdentity();
14229            int res = broadcastIntentLocked(callerApp,
14230                    callerApp != null ? callerApp.info.packageName : null,
14231                    intent, resolvedType, resultTo,
14232                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14233                    callingPid, callingUid, userId);
14234            Binder.restoreCallingIdentity(origId);
14235            return res;
14236        }
14237    }
14238
14239    int broadcastIntentInPackage(String packageName, int uid,
14240            Intent intent, String resolvedType, IIntentReceiver resultTo,
14241            int resultCode, String resultData, Bundle map,
14242            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14243        synchronized(this) {
14244            intent = verifyBroadcastLocked(intent);
14245
14246            final long origId = Binder.clearCallingIdentity();
14247            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14248                    resultTo, resultCode, resultData, map, requiredPermission,
14249                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14250            Binder.restoreCallingIdentity(origId);
14251            return res;
14252        }
14253    }
14254
14255    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14256        // Refuse possible leaked file descriptors
14257        if (intent != null && intent.hasFileDescriptors() == true) {
14258            throw new IllegalArgumentException("File descriptors passed in Intent");
14259        }
14260
14261        userId = handleIncomingUser(Binder.getCallingPid(),
14262                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14263
14264        synchronized(this) {
14265            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14266                    != PackageManager.PERMISSION_GRANTED) {
14267                String msg = "Permission Denial: unbroadcastIntent() from pid="
14268                        + Binder.getCallingPid()
14269                        + ", uid=" + Binder.getCallingUid()
14270                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14271                Slog.w(TAG, msg);
14272                throw new SecurityException(msg);
14273            }
14274            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14275            if (stickies != null) {
14276                ArrayList<Intent> list = stickies.get(intent.getAction());
14277                if (list != null) {
14278                    int N = list.size();
14279                    int i;
14280                    for (i=0; i<N; i++) {
14281                        if (intent.filterEquals(list.get(i))) {
14282                            list.remove(i);
14283                            break;
14284                        }
14285                    }
14286                    if (list.size() <= 0) {
14287                        stickies.remove(intent.getAction());
14288                    }
14289                }
14290                if (stickies.size() <= 0) {
14291                    mStickyBroadcasts.remove(userId);
14292                }
14293            }
14294        }
14295    }
14296
14297    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14298            String resultData, Bundle resultExtras, boolean resultAbort) {
14299        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14300        if (r == null) {
14301            Slog.w(TAG, "finishReceiver called but not found on queue");
14302            return false;
14303        }
14304
14305        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14306    }
14307
14308    void backgroundServicesFinishedLocked(int userId) {
14309        for (BroadcastQueue queue : mBroadcastQueues) {
14310            queue.backgroundServicesFinishedLocked(userId);
14311        }
14312    }
14313
14314    public void finishReceiver(IBinder who, int resultCode, String resultData,
14315            Bundle resultExtras, boolean resultAbort) {
14316        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14317
14318        // Refuse possible leaked file descriptors
14319        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14320            throw new IllegalArgumentException("File descriptors passed in Bundle");
14321        }
14322
14323        final long origId = Binder.clearCallingIdentity();
14324        try {
14325            boolean doNext = false;
14326            BroadcastRecord r;
14327
14328            synchronized(this) {
14329                r = broadcastRecordForReceiverLocked(who);
14330                if (r != null) {
14331                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14332                        resultData, resultExtras, resultAbort, true);
14333                }
14334            }
14335
14336            if (doNext) {
14337                r.queue.processNextBroadcast(false);
14338            }
14339            trimApplications();
14340        } finally {
14341            Binder.restoreCallingIdentity(origId);
14342        }
14343    }
14344
14345    // =========================================================
14346    // INSTRUMENTATION
14347    // =========================================================
14348
14349    public boolean startInstrumentation(ComponentName className,
14350            String profileFile, int flags, Bundle arguments,
14351            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14352            int userId, String abiOverride) {
14353        enforceNotIsolatedCaller("startInstrumentation");
14354        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14355                userId, false, true, "startInstrumentation", null);
14356        // Refuse possible leaked file descriptors
14357        if (arguments != null && arguments.hasFileDescriptors()) {
14358            throw new IllegalArgumentException("File descriptors passed in Bundle");
14359        }
14360
14361        synchronized(this) {
14362            InstrumentationInfo ii = null;
14363            ApplicationInfo ai = null;
14364            try {
14365                ii = mContext.getPackageManager().getInstrumentationInfo(
14366                    className, STOCK_PM_FLAGS);
14367                ai = AppGlobals.getPackageManager().getApplicationInfo(
14368                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14369            } catch (PackageManager.NameNotFoundException e) {
14370            } catch (RemoteException e) {
14371            }
14372            if (ii == null) {
14373                reportStartInstrumentationFailure(watcher, className,
14374                        "Unable to find instrumentation info for: " + className);
14375                return false;
14376            }
14377            if (ai == null) {
14378                reportStartInstrumentationFailure(watcher, className,
14379                        "Unable to find instrumentation target package: " + ii.targetPackage);
14380                return false;
14381            }
14382
14383            int match = mContext.getPackageManager().checkSignatures(
14384                    ii.targetPackage, ii.packageName);
14385            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14386                String msg = "Permission Denial: starting instrumentation "
14387                        + className + " from pid="
14388                        + Binder.getCallingPid()
14389                        + ", uid=" + Binder.getCallingPid()
14390                        + " not allowed because package " + ii.packageName
14391                        + " does not have a signature matching the target "
14392                        + ii.targetPackage;
14393                reportStartInstrumentationFailure(watcher, className, msg);
14394                throw new SecurityException(msg);
14395            }
14396
14397            final long origId = Binder.clearCallingIdentity();
14398            // Instrumentation can kill and relaunch even persistent processes
14399            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14400                    "start instr");
14401            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14402            app.instrumentationClass = className;
14403            app.instrumentationInfo = ai;
14404            app.instrumentationProfileFile = profileFile;
14405            app.instrumentationArguments = arguments;
14406            app.instrumentationWatcher = watcher;
14407            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14408            app.instrumentationResultClass = className;
14409            Binder.restoreCallingIdentity(origId);
14410        }
14411
14412        return true;
14413    }
14414
14415    /**
14416     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14417     * error to the logs, but if somebody is watching, send the report there too.  This enables
14418     * the "am" command to report errors with more information.
14419     *
14420     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14421     * @param cn The component name of the instrumentation.
14422     * @param report The error report.
14423     */
14424    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14425            ComponentName cn, String report) {
14426        Slog.w(TAG, report);
14427        try {
14428            if (watcher != null) {
14429                Bundle results = new Bundle();
14430                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14431                results.putString("Error", report);
14432                watcher.instrumentationStatus(cn, -1, results);
14433            }
14434        } catch (RemoteException e) {
14435            Slog.w(TAG, e);
14436        }
14437    }
14438
14439    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14440        if (app.instrumentationWatcher != null) {
14441            try {
14442                // NOTE:  IInstrumentationWatcher *must* be oneway here
14443                app.instrumentationWatcher.instrumentationFinished(
14444                    app.instrumentationClass,
14445                    resultCode,
14446                    results);
14447            } catch (RemoteException e) {
14448            }
14449        }
14450        if (app.instrumentationUiAutomationConnection != null) {
14451            try {
14452                app.instrumentationUiAutomationConnection.shutdown();
14453            } catch (RemoteException re) {
14454                /* ignore */
14455            }
14456            // Only a UiAutomation can set this flag and now that
14457            // it is finished we make sure it is reset to its default.
14458            mUserIsMonkey = false;
14459        }
14460        app.instrumentationWatcher = null;
14461        app.instrumentationUiAutomationConnection = null;
14462        app.instrumentationClass = null;
14463        app.instrumentationInfo = null;
14464        app.instrumentationProfileFile = null;
14465        app.instrumentationArguments = null;
14466
14467        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14468                "finished inst");
14469    }
14470
14471    public void finishInstrumentation(IApplicationThread target,
14472            int resultCode, Bundle results) {
14473        int userId = UserHandle.getCallingUserId();
14474        // Refuse possible leaked file descriptors
14475        if (results != null && results.hasFileDescriptors()) {
14476            throw new IllegalArgumentException("File descriptors passed in Intent");
14477        }
14478
14479        synchronized(this) {
14480            ProcessRecord app = getRecordForAppLocked(target);
14481            if (app == null) {
14482                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14483                return;
14484            }
14485            final long origId = Binder.clearCallingIdentity();
14486            finishInstrumentationLocked(app, resultCode, results);
14487            Binder.restoreCallingIdentity(origId);
14488        }
14489    }
14490
14491    // =========================================================
14492    // CONFIGURATION
14493    // =========================================================
14494
14495    public ConfigurationInfo getDeviceConfigurationInfo() {
14496        ConfigurationInfo config = new ConfigurationInfo();
14497        synchronized (this) {
14498            config.reqTouchScreen = mConfiguration.touchscreen;
14499            config.reqKeyboardType = mConfiguration.keyboard;
14500            config.reqNavigation = mConfiguration.navigation;
14501            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14502                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14503                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14504            }
14505            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14506                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14507                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14508            }
14509            config.reqGlEsVersion = GL_ES_VERSION;
14510        }
14511        return config;
14512    }
14513
14514    ActivityStack getFocusedStack() {
14515        return mStackSupervisor.getFocusedStack();
14516    }
14517
14518    public Configuration getConfiguration() {
14519        Configuration ci;
14520        synchronized(this) {
14521            ci = new Configuration(mConfiguration);
14522        }
14523        return ci;
14524    }
14525
14526    public void updatePersistentConfiguration(Configuration values) {
14527        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14528                "updateConfiguration()");
14529        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14530                "updateConfiguration()");
14531        if (values == null) {
14532            throw new NullPointerException("Configuration must not be null");
14533        }
14534
14535        synchronized(this) {
14536            final long origId = Binder.clearCallingIdentity();
14537            updateConfigurationLocked(values, null, true, false);
14538            Binder.restoreCallingIdentity(origId);
14539        }
14540    }
14541
14542    public void updateConfiguration(Configuration values) {
14543        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14544                "updateConfiguration()");
14545
14546        synchronized(this) {
14547            if (values == null && mWindowManager != null) {
14548                // sentinel: fetch the current configuration from the window manager
14549                values = mWindowManager.computeNewConfiguration();
14550            }
14551
14552            if (mWindowManager != null) {
14553                mProcessList.applyDisplaySize(mWindowManager);
14554            }
14555
14556            final long origId = Binder.clearCallingIdentity();
14557            if (values != null) {
14558                Settings.System.clearConfiguration(values);
14559            }
14560            updateConfigurationLocked(values, null, false, false);
14561            Binder.restoreCallingIdentity(origId);
14562        }
14563    }
14564
14565    /**
14566     * Do either or both things: (1) change the current configuration, and (2)
14567     * make sure the given activity is running with the (now) current
14568     * configuration.  Returns true if the activity has been left running, or
14569     * false if <var>starting</var> is being destroyed to match the new
14570     * configuration.
14571     * @param persistent TODO
14572     */
14573    boolean updateConfigurationLocked(Configuration values,
14574            ActivityRecord starting, boolean persistent, boolean initLocale) {
14575        int changes = 0;
14576
14577        if (values != null) {
14578            Configuration newConfig = new Configuration(mConfiguration);
14579            changes = newConfig.updateFrom(values);
14580            if (changes != 0) {
14581                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14582                    Slog.i(TAG, "Updating configuration to: " + values);
14583                }
14584
14585                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14586
14587                if (values.locale != null && !initLocale) {
14588                    saveLocaleLocked(values.locale,
14589                                     !values.locale.equals(mConfiguration.locale),
14590                                     values.userSetLocale);
14591                }
14592
14593                mConfigurationSeq++;
14594                if (mConfigurationSeq <= 0) {
14595                    mConfigurationSeq = 1;
14596                }
14597                newConfig.seq = mConfigurationSeq;
14598                mConfiguration = newConfig;
14599                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14600                mUsageStatsService.noteStartConfig(newConfig);
14601
14602                final Configuration configCopy = new Configuration(mConfiguration);
14603
14604                // TODO: If our config changes, should we auto dismiss any currently
14605                // showing dialogs?
14606                mShowDialogs = shouldShowDialogs(newConfig);
14607
14608                AttributeCache ac = AttributeCache.instance();
14609                if (ac != null) {
14610                    ac.updateConfiguration(configCopy);
14611                }
14612
14613                // Make sure all resources in our process are updated
14614                // right now, so that anyone who is going to retrieve
14615                // resource values after we return will be sure to get
14616                // the new ones.  This is especially important during
14617                // boot, where the first config change needs to guarantee
14618                // all resources have that config before following boot
14619                // code is executed.
14620                mSystemThread.applyConfigurationToResources(configCopy);
14621
14622                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14623                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14624                    msg.obj = new Configuration(configCopy);
14625                    mHandler.sendMessage(msg);
14626                }
14627
14628                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14629                    ProcessRecord app = mLruProcesses.get(i);
14630                    try {
14631                        if (app.thread != null) {
14632                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14633                                    + app.processName + " new config " + mConfiguration);
14634                            app.thread.scheduleConfigurationChanged(configCopy);
14635                        }
14636                    } catch (Exception e) {
14637                    }
14638                }
14639                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14640                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14641                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14642                        | Intent.FLAG_RECEIVER_FOREGROUND);
14643                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14644                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14645                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14646                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14647                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14648                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14649                    broadcastIntentLocked(null, null, intent,
14650                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14651                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14652                }
14653            }
14654        }
14655
14656        boolean kept = true;
14657        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14658        // mainStack is null during startup.
14659        if (mainStack != null) {
14660            if (changes != 0 && starting == null) {
14661                // If the configuration changed, and the caller is not already
14662                // in the process of starting an activity, then find the top
14663                // activity to check if its configuration needs to change.
14664                starting = mainStack.topRunningActivityLocked(null);
14665            }
14666
14667            if (starting != null) {
14668                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14669                // And we need to make sure at this point that all other activities
14670                // are made visible with the correct configuration.
14671                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14672            }
14673        }
14674
14675        if (values != null && mWindowManager != null) {
14676            mWindowManager.setNewConfiguration(mConfiguration);
14677        }
14678
14679        return kept;
14680    }
14681
14682    /**
14683     * Decide based on the configuration whether we should shouw the ANR,
14684     * crash, etc dialogs.  The idea is that if there is no affordnace to
14685     * press the on-screen buttons, we shouldn't show the dialog.
14686     *
14687     * A thought: SystemUI might also want to get told about this, the Power
14688     * dialog / global actions also might want different behaviors.
14689     */
14690    private static final boolean shouldShowDialogs(Configuration config) {
14691        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14692                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14693    }
14694
14695    /**
14696     * Save the locale.  You must be inside a synchronized (this) block.
14697     */
14698    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14699        if(isDiff) {
14700            SystemProperties.set("user.language", l.getLanguage());
14701            SystemProperties.set("user.region", l.getCountry());
14702        }
14703
14704        if(isPersist) {
14705            SystemProperties.set("persist.sys.language", l.getLanguage());
14706            SystemProperties.set("persist.sys.country", l.getCountry());
14707            SystemProperties.set("persist.sys.localevar", l.getVariant());
14708        }
14709    }
14710
14711    @Override
14712    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14713        ActivityRecord srec = ActivityRecord.forToken(token);
14714        return srec != null && srec.task.affinity != null &&
14715                srec.task.affinity.equals(destAffinity);
14716    }
14717
14718    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14719            Intent resultData) {
14720
14721        synchronized (this) {
14722            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14723            if (stack != null) {
14724                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14725            }
14726            return false;
14727        }
14728    }
14729
14730    public int getLaunchedFromUid(IBinder activityToken) {
14731        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14732        if (srec == null) {
14733            return -1;
14734        }
14735        return srec.launchedFromUid;
14736    }
14737
14738    public String getLaunchedFromPackage(IBinder activityToken) {
14739        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14740        if (srec == null) {
14741            return null;
14742        }
14743        return srec.launchedFromPackage;
14744    }
14745
14746    // =========================================================
14747    // LIFETIME MANAGEMENT
14748    // =========================================================
14749
14750    // Returns which broadcast queue the app is the current [or imminent] receiver
14751    // on, or 'null' if the app is not an active broadcast recipient.
14752    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14753        BroadcastRecord r = app.curReceiver;
14754        if (r != null) {
14755            return r.queue;
14756        }
14757
14758        // It's not the current receiver, but it might be starting up to become one
14759        synchronized (this) {
14760            for (BroadcastQueue queue : mBroadcastQueues) {
14761                r = queue.mPendingBroadcast;
14762                if (r != null && r.curApp == app) {
14763                    // found it; report which queue it's in
14764                    return queue;
14765                }
14766            }
14767        }
14768
14769        return null;
14770    }
14771
14772    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14773            boolean doingAll, long now) {
14774        if (mAdjSeq == app.adjSeq) {
14775            // This adjustment has already been computed.
14776            return app.curRawAdj;
14777        }
14778
14779        if (app.thread == null) {
14780            app.adjSeq = mAdjSeq;
14781            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14782            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14783            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14784        }
14785
14786        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14787        app.adjSource = null;
14788        app.adjTarget = null;
14789        app.empty = false;
14790        app.cached = false;
14791
14792        final int activitiesSize = app.activities.size();
14793
14794        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14795            // The max adjustment doesn't allow this app to be anything
14796            // below foreground, so it is not worth doing work for it.
14797            app.adjType = "fixed";
14798            app.adjSeq = mAdjSeq;
14799            app.curRawAdj = app.maxAdj;
14800            app.foregroundActivities = false;
14801            app.keeping = true;
14802            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14803            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14804            // System processes can do UI, and when they do we want to have
14805            // them trim their memory after the user leaves the UI.  To
14806            // facilitate this, here we need to determine whether or not it
14807            // is currently showing UI.
14808            app.systemNoUi = true;
14809            if (app == TOP_APP) {
14810                app.systemNoUi = false;
14811            } else if (activitiesSize > 0) {
14812                for (int j = 0; j < activitiesSize; j++) {
14813                    final ActivityRecord r = app.activities.get(j);
14814                    if (r.visible) {
14815                        app.systemNoUi = false;
14816                    }
14817                }
14818            }
14819            if (!app.systemNoUi) {
14820                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14821            }
14822            return (app.curAdj=app.maxAdj);
14823        }
14824
14825        app.keeping = false;
14826        app.systemNoUi = false;
14827
14828        // Determine the importance of the process, starting with most
14829        // important to least, and assign an appropriate OOM adjustment.
14830        int adj;
14831        int schedGroup;
14832        int procState;
14833        boolean foregroundActivities = false;
14834        boolean interesting = false;
14835        BroadcastQueue queue;
14836        if (app == TOP_APP) {
14837            // The last app on the list is the foreground app.
14838            adj = ProcessList.FOREGROUND_APP_ADJ;
14839            schedGroup = Process.THREAD_GROUP_DEFAULT;
14840            app.adjType = "top-activity";
14841            foregroundActivities = true;
14842            interesting = true;
14843            procState = ActivityManager.PROCESS_STATE_TOP;
14844        } else if (app.instrumentationClass != null) {
14845            // Don't want to kill running instrumentation.
14846            adj = ProcessList.FOREGROUND_APP_ADJ;
14847            schedGroup = Process.THREAD_GROUP_DEFAULT;
14848            app.adjType = "instrumentation";
14849            interesting = true;
14850            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14851        } else if ((queue = isReceivingBroadcast(app)) != null) {
14852            // An app that is currently receiving a broadcast also
14853            // counts as being in the foreground for OOM killer purposes.
14854            // It's placed in a sched group based on the nature of the
14855            // broadcast as reflected by which queue it's active in.
14856            adj = ProcessList.FOREGROUND_APP_ADJ;
14857            schedGroup = (queue == mFgBroadcastQueue)
14858                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14859            app.adjType = "broadcast";
14860            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14861        } else if (app.executingServices.size() > 0) {
14862            // An app that is currently executing a service callback also
14863            // counts as being in the foreground.
14864            adj = ProcessList.FOREGROUND_APP_ADJ;
14865            schedGroup = app.execServicesFg ?
14866                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14867            app.adjType = "exec-service";
14868            procState = ActivityManager.PROCESS_STATE_SERVICE;
14869            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14870        } else {
14871            // As far as we know the process is empty.  We may change our mind later.
14872            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14873            // At this point we don't actually know the adjustment.  Use the cached adj
14874            // value that the caller wants us to.
14875            adj = cachedAdj;
14876            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14877            app.cached = true;
14878            app.empty = true;
14879            app.adjType = "cch-empty";
14880        }
14881
14882        // Examine all activities if not already foreground.
14883        if (!foregroundActivities && activitiesSize > 0) {
14884            for (int j = 0; j < activitiesSize; j++) {
14885                final ActivityRecord r = app.activities.get(j);
14886                if (r.app != app) {
14887                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14888                            + app + "?!?");
14889                    continue;
14890                }
14891                if (r.visible) {
14892                    // App has a visible activity; only upgrade adjustment.
14893                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14894                        adj = ProcessList.VISIBLE_APP_ADJ;
14895                        app.adjType = "visible";
14896                    }
14897                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14898                        procState = ActivityManager.PROCESS_STATE_TOP;
14899                    }
14900                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14901                    app.cached = false;
14902                    app.empty = false;
14903                    foregroundActivities = true;
14904                    break;
14905                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14906                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14907                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14908                        app.adjType = "pausing";
14909                    }
14910                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14911                        procState = ActivityManager.PROCESS_STATE_TOP;
14912                    }
14913                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14914                    app.cached = false;
14915                    app.empty = false;
14916                    foregroundActivities = true;
14917                } else if (r.state == ActivityState.STOPPING) {
14918                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14919                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14920                        app.adjType = "stopping";
14921                    }
14922                    // For the process state, we will at this point consider the
14923                    // process to be cached.  It will be cached either as an activity
14924                    // or empty depending on whether the activity is finishing.  We do
14925                    // this so that we can treat the process as cached for purposes of
14926                    // memory trimming (determing current memory level, trim command to
14927                    // send to process) since there can be an arbitrary number of stopping
14928                    // processes and they should soon all go into the cached state.
14929                    if (!r.finishing) {
14930                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14931                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14932                        }
14933                    }
14934                    app.cached = false;
14935                    app.empty = false;
14936                    foregroundActivities = true;
14937                } else {
14938                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14939                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14940                        app.adjType = "cch-act";
14941                    }
14942                }
14943            }
14944        }
14945
14946        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14947            if (app.foregroundServices) {
14948                // The user is aware of this app, so make it visible.
14949                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14950                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14951                app.cached = false;
14952                app.adjType = "fg-service";
14953                schedGroup = Process.THREAD_GROUP_DEFAULT;
14954            } else if (app.forcingToForeground != null) {
14955                // The user is aware of this app, so make it visible.
14956                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14957                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14958                app.cached = false;
14959                app.adjType = "force-fg";
14960                app.adjSource = app.forcingToForeground;
14961                schedGroup = Process.THREAD_GROUP_DEFAULT;
14962            }
14963        }
14964
14965        if (app.foregroundServices) {
14966            interesting = true;
14967        }
14968
14969        if (app == mHeavyWeightProcess) {
14970            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14971                // We don't want to kill the current heavy-weight process.
14972                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14973                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14974                app.cached = false;
14975                app.adjType = "heavy";
14976            }
14977            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14978                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14979            }
14980        }
14981
14982        if (app == mHomeProcess) {
14983            if (adj > ProcessList.HOME_APP_ADJ) {
14984                // This process is hosting what we currently consider to be the
14985                // home app, so we don't want to let it go into the background.
14986                adj = ProcessList.HOME_APP_ADJ;
14987                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14988                app.cached = false;
14989                app.adjType = "home";
14990            }
14991            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14992                procState = ActivityManager.PROCESS_STATE_HOME;
14993            }
14994        }
14995
14996        if (app == mPreviousProcess && app.activities.size() > 0) {
14997            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14998                // This was the previous process that showed UI to the user.
14999                // We want to try to keep it around more aggressively, to give
15000                // a good experience around switching between two apps.
15001                adj = ProcessList.PREVIOUS_APP_ADJ;
15002                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15003                app.cached = false;
15004                app.adjType = "previous";
15005            }
15006            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15007                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15008            }
15009        }
15010
15011        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15012                + " reason=" + app.adjType);
15013
15014        // By default, we use the computed adjustment.  It may be changed if
15015        // there are applications dependent on our services or providers, but
15016        // this gives us a baseline and makes sure we don't get into an
15017        // infinite recursion.
15018        app.adjSeq = mAdjSeq;
15019        app.curRawAdj = adj;
15020        app.hasStartedServices = false;
15021
15022        if (mBackupTarget != null && app == mBackupTarget.app) {
15023            // If possible we want to avoid killing apps while they're being backed up
15024            if (adj > ProcessList.BACKUP_APP_ADJ) {
15025                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15026                adj = ProcessList.BACKUP_APP_ADJ;
15027                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15028                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15029                }
15030                app.adjType = "backup";
15031                app.cached = false;
15032            }
15033            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15034                procState = ActivityManager.PROCESS_STATE_BACKUP;
15035            }
15036        }
15037
15038        boolean mayBeTop = false;
15039
15040        for (int is = app.services.size()-1;
15041                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15042                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15043                        || procState > ActivityManager.PROCESS_STATE_TOP);
15044                is--) {
15045            ServiceRecord s = app.services.valueAt(is);
15046            if (s.startRequested) {
15047                app.hasStartedServices = true;
15048                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15049                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15050                }
15051                if (app.hasShownUi && app != mHomeProcess) {
15052                    // If this process has shown some UI, let it immediately
15053                    // go to the LRU list because it may be pretty heavy with
15054                    // UI stuff.  We'll tag it with a label just to help
15055                    // debug and understand what is going on.
15056                    if (adj > ProcessList.SERVICE_ADJ) {
15057                        app.adjType = "cch-started-ui-services";
15058                    }
15059                } else {
15060                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15061                        // This service has seen some activity within
15062                        // recent memory, so we will keep its process ahead
15063                        // of the background processes.
15064                        if (adj > ProcessList.SERVICE_ADJ) {
15065                            adj = ProcessList.SERVICE_ADJ;
15066                            app.adjType = "started-services";
15067                            app.cached = false;
15068                        }
15069                    }
15070                    // If we have let the service slide into the background
15071                    // state, still have some text describing what it is doing
15072                    // even though the service no longer has an impact.
15073                    if (adj > ProcessList.SERVICE_ADJ) {
15074                        app.adjType = "cch-started-services";
15075                    }
15076                }
15077                // Don't kill this process because it is doing work; it
15078                // has said it is doing work.
15079                app.keeping = true;
15080            }
15081            for (int conni = s.connections.size()-1;
15082                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15083                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15084                            || procState > ActivityManager.PROCESS_STATE_TOP);
15085                    conni--) {
15086                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15087                for (int i = 0;
15088                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15089                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15090                                || procState > ActivityManager.PROCESS_STATE_TOP);
15091                        i++) {
15092                    // XXX should compute this based on the max of
15093                    // all connected clients.
15094                    ConnectionRecord cr = clist.get(i);
15095                    if (cr.binding.client == app) {
15096                        // Binding to ourself is not interesting.
15097                        continue;
15098                    }
15099                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15100                        ProcessRecord client = cr.binding.client;
15101                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15102                                TOP_APP, doingAll, now);
15103                        int clientProcState = client.curProcState;
15104                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15105                            // If the other app is cached for any reason, for purposes here
15106                            // we are going to consider it empty.  The specific cached state
15107                            // doesn't propagate except under certain conditions.
15108                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15109                        }
15110                        String adjType = null;
15111                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15112                            // Not doing bind OOM management, so treat
15113                            // this guy more like a started service.
15114                            if (app.hasShownUi && app != mHomeProcess) {
15115                                // If this process has shown some UI, let it immediately
15116                                // go to the LRU list because it may be pretty heavy with
15117                                // UI stuff.  We'll tag it with a label just to help
15118                                // debug and understand what is going on.
15119                                if (adj > clientAdj) {
15120                                    adjType = "cch-bound-ui-services";
15121                                }
15122                                app.cached = false;
15123                                clientAdj = adj;
15124                                clientProcState = procState;
15125                            } else {
15126                                if (now >= (s.lastActivity
15127                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15128                                    // This service has not seen activity within
15129                                    // recent memory, so allow it to drop to the
15130                                    // LRU list if there is no other reason to keep
15131                                    // it around.  We'll also tag it with a label just
15132                                    // to help debug and undertand what is going on.
15133                                    if (adj > clientAdj) {
15134                                        adjType = "cch-bound-services";
15135                                    }
15136                                    clientAdj = adj;
15137                                }
15138                            }
15139                        }
15140                        if (adj > clientAdj) {
15141                            // If this process has recently shown UI, and
15142                            // the process that is binding to it is less
15143                            // important than being visible, then we don't
15144                            // care about the binding as much as we care
15145                            // about letting this process get into the LRU
15146                            // list to be killed and restarted if needed for
15147                            // memory.
15148                            if (app.hasShownUi && app != mHomeProcess
15149                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15150                                adjType = "cch-bound-ui-services";
15151                            } else {
15152                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15153                                        |Context.BIND_IMPORTANT)) != 0) {
15154                                    adj = clientAdj;
15155                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15156                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15157                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15158                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15159                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15160                                    adj = clientAdj;
15161                                } else {
15162                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15163                                        adj = ProcessList.VISIBLE_APP_ADJ;
15164                                    }
15165                                }
15166                                if (!client.cached) {
15167                                    app.cached = false;
15168                                }
15169                                if (client.keeping) {
15170                                    app.keeping = true;
15171                                }
15172                                adjType = "service";
15173                            }
15174                        }
15175                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15176                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15177                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15178                            }
15179                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15180                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15181                                    // Special handling of clients who are in the top state.
15182                                    // We *may* want to consider this process to be in the
15183                                    // top state as well, but only if there is not another
15184                                    // reason for it to be running.  Being on the top is a
15185                                    // special state, meaning you are specifically running
15186                                    // for the current top app.  If the process is already
15187                                    // running in the background for some other reason, it
15188                                    // is more important to continue considering it to be
15189                                    // in the background state.
15190                                    mayBeTop = true;
15191                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15192                                } else {
15193                                    // Special handling for above-top states (persistent
15194                                    // processes).  These should not bring the current process
15195                                    // into the top state, since they are not on top.  Instead
15196                                    // give them the best state after that.
15197                                    clientProcState =
15198                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15199                                }
15200                            }
15201                        } else {
15202                            if (clientProcState <
15203                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15204                                clientProcState =
15205                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15206                            }
15207                        }
15208                        if (procState > clientProcState) {
15209                            procState = clientProcState;
15210                        }
15211                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15212                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15213                            app.pendingUiClean = true;
15214                        }
15215                        if (adjType != null) {
15216                            app.adjType = adjType;
15217                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15218                                    .REASON_SERVICE_IN_USE;
15219                            app.adjSource = cr.binding.client;
15220                            app.adjSourceOom = clientAdj;
15221                            app.adjTarget = s.name;
15222                        }
15223                    }
15224                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15225                        app.treatLikeActivity = true;
15226                    }
15227                    final ActivityRecord a = cr.activity;
15228                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15229                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15230                                (a.visible || a.state == ActivityState.RESUMED
15231                                 || a.state == ActivityState.PAUSING)) {
15232                            adj = ProcessList.FOREGROUND_APP_ADJ;
15233                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15234                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15235                            }
15236                            app.cached = false;
15237                            app.adjType = "service";
15238                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15239                                    .REASON_SERVICE_IN_USE;
15240                            app.adjSource = a;
15241                            app.adjSourceOom = adj;
15242                            app.adjTarget = s.name;
15243                        }
15244                    }
15245                }
15246            }
15247        }
15248
15249        for (int provi = app.pubProviders.size()-1;
15250                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15251                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15252                        || procState > ActivityManager.PROCESS_STATE_TOP);
15253                provi--) {
15254            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15255            for (int i = cpr.connections.size()-1;
15256                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15257                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15258                            || procState > ActivityManager.PROCESS_STATE_TOP);
15259                    i--) {
15260                ContentProviderConnection conn = cpr.connections.get(i);
15261                ProcessRecord client = conn.client;
15262                if (client == app) {
15263                    // Being our own client is not interesting.
15264                    continue;
15265                }
15266                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15267                int clientProcState = client.curProcState;
15268                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15269                    // If the other app is cached for any reason, for purposes here
15270                    // we are going to consider it empty.
15271                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15272                }
15273                if (adj > clientAdj) {
15274                    if (app.hasShownUi && app != mHomeProcess
15275                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15276                        app.adjType = "cch-ui-provider";
15277                    } else {
15278                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15279                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15280                        app.adjType = "provider";
15281                    }
15282                    app.cached &= client.cached;
15283                    app.keeping |= client.keeping;
15284                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15285                            .REASON_PROVIDER_IN_USE;
15286                    app.adjSource = client;
15287                    app.adjSourceOom = clientAdj;
15288                    app.adjTarget = cpr.name;
15289                }
15290                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15291                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15292                        // Special handling of clients who are in the top state.
15293                        // We *may* want to consider this process to be in the
15294                        // top state as well, but only if there is not another
15295                        // reason for it to be running.  Being on the top is a
15296                        // special state, meaning you are specifically running
15297                        // for the current top app.  If the process is already
15298                        // running in the background for some other reason, it
15299                        // is more important to continue considering it to be
15300                        // in the background state.
15301                        mayBeTop = true;
15302                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15303                    } else {
15304                        // Special handling for above-top states (persistent
15305                        // processes).  These should not bring the current process
15306                        // into the top state, since they are not on top.  Instead
15307                        // give them the best state after that.
15308                        clientProcState =
15309                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15310                    }
15311                }
15312                if (procState > clientProcState) {
15313                    procState = clientProcState;
15314                }
15315                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15316                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15317                }
15318            }
15319            // If the provider has external (non-framework) process
15320            // dependencies, ensure that its adjustment is at least
15321            // FOREGROUND_APP_ADJ.
15322            if (cpr.hasExternalProcessHandles()) {
15323                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15324                    adj = ProcessList.FOREGROUND_APP_ADJ;
15325                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15326                    app.cached = false;
15327                    app.keeping = true;
15328                    app.adjType = "provider";
15329                    app.adjTarget = cpr.name;
15330                }
15331                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15332                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15333                }
15334            }
15335        }
15336
15337        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15338            // A client of one of our services or providers is in the top state.  We
15339            // *may* want to be in the top state, but not if we are already running in
15340            // the background for some other reason.  For the decision here, we are going
15341            // to pick out a few specific states that we want to remain in when a client
15342            // is top (states that tend to be longer-term) and otherwise allow it to go
15343            // to the top state.
15344            switch (procState) {
15345                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15346                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15347                case ActivityManager.PROCESS_STATE_SERVICE:
15348                    // These all are longer-term states, so pull them up to the top
15349                    // of the background states, but not all the way to the top state.
15350                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15351                    break;
15352                default:
15353                    // Otherwise, top is a better choice, so take it.
15354                    procState = ActivityManager.PROCESS_STATE_TOP;
15355                    break;
15356            }
15357        }
15358
15359        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15360            if (app.hasClientActivities) {
15361                // This is a cached process, but with client activities.  Mark it so.
15362                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15363                app.adjType = "cch-client-act";
15364            } else if (app.treatLikeActivity) {
15365                // This is a cached process, but somebody wants us to treat it like it has
15366                // an activity, okay!
15367                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15368                app.adjType = "cch-as-act";
15369            }
15370        }
15371
15372        if (adj == ProcessList.SERVICE_ADJ) {
15373            if (doingAll) {
15374                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15375                mNewNumServiceProcs++;
15376                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15377                if (!app.serviceb) {
15378                    // This service isn't far enough down on the LRU list to
15379                    // normally be a B service, but if we are low on RAM and it
15380                    // is large we want to force it down since we would prefer to
15381                    // keep launcher over it.
15382                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15383                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15384                        app.serviceHighRam = true;
15385                        app.serviceb = true;
15386                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15387                    } else {
15388                        mNewNumAServiceProcs++;
15389                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15390                    }
15391                } else {
15392                    app.serviceHighRam = false;
15393                }
15394            }
15395            if (app.serviceb) {
15396                adj = ProcessList.SERVICE_B_ADJ;
15397            }
15398        }
15399
15400        app.curRawAdj = adj;
15401
15402        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15403        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15404        if (adj > app.maxAdj) {
15405            adj = app.maxAdj;
15406            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15407                schedGroup = Process.THREAD_GROUP_DEFAULT;
15408            }
15409        }
15410        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15411            app.keeping = true;
15412        }
15413
15414        // Do final modification to adj.  Everything we do between here and applying
15415        // the final setAdj must be done in this function, because we will also use
15416        // it when computing the final cached adj later.  Note that we don't need to
15417        // worry about this for max adj above, since max adj will always be used to
15418        // keep it out of the cached vaues.
15419        app.curAdj = app.modifyRawOomAdj(adj);
15420        app.curSchedGroup = schedGroup;
15421        app.curProcState = procState;
15422        app.foregroundActivities = foregroundActivities;
15423
15424        return app.curRawAdj;
15425    }
15426
15427    /**
15428     * Schedule PSS collection of a process.
15429     */
15430    void requestPssLocked(ProcessRecord proc, int procState) {
15431        if (mPendingPssProcesses.contains(proc)) {
15432            return;
15433        }
15434        if (mPendingPssProcesses.size() == 0) {
15435            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15436        }
15437        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15438        proc.pssProcState = procState;
15439        mPendingPssProcesses.add(proc);
15440    }
15441
15442    /**
15443     * Schedule PSS collection of all processes.
15444     */
15445    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15446        if (!always) {
15447            if (now < (mLastFullPssTime +
15448                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15449                return;
15450            }
15451        }
15452        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15453        mLastFullPssTime = now;
15454        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15455        mPendingPssProcesses.clear();
15456        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15457            ProcessRecord app = mLruProcesses.get(i);
15458            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15459                app.pssProcState = app.setProcState;
15460                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15461                        isSleeping(), now);
15462                mPendingPssProcesses.add(app);
15463            }
15464        }
15465        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15466    }
15467
15468    /**
15469     * Ask a given process to GC right now.
15470     */
15471    final void performAppGcLocked(ProcessRecord app) {
15472        try {
15473            app.lastRequestedGc = SystemClock.uptimeMillis();
15474            if (app.thread != null) {
15475                if (app.reportLowMemory) {
15476                    app.reportLowMemory = false;
15477                    app.thread.scheduleLowMemory();
15478                } else {
15479                    app.thread.processInBackground();
15480                }
15481            }
15482        } catch (Exception e) {
15483            // whatever.
15484        }
15485    }
15486
15487    /**
15488     * Returns true if things are idle enough to perform GCs.
15489     */
15490    private final boolean canGcNowLocked() {
15491        boolean processingBroadcasts = false;
15492        for (BroadcastQueue q : mBroadcastQueues) {
15493            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15494                processingBroadcasts = true;
15495            }
15496        }
15497        return !processingBroadcasts
15498                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15499    }
15500
15501    /**
15502     * Perform GCs on all processes that are waiting for it, but only
15503     * if things are idle.
15504     */
15505    final void performAppGcsLocked() {
15506        final int N = mProcessesToGc.size();
15507        if (N <= 0) {
15508            return;
15509        }
15510        if (canGcNowLocked()) {
15511            while (mProcessesToGc.size() > 0) {
15512                ProcessRecord proc = mProcessesToGc.remove(0);
15513                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15514                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15515                            <= SystemClock.uptimeMillis()) {
15516                        // To avoid spamming the system, we will GC processes one
15517                        // at a time, waiting a few seconds between each.
15518                        performAppGcLocked(proc);
15519                        scheduleAppGcsLocked();
15520                        return;
15521                    } else {
15522                        // It hasn't been long enough since we last GCed this
15523                        // process...  put it in the list to wait for its time.
15524                        addProcessToGcListLocked(proc);
15525                        break;
15526                    }
15527                }
15528            }
15529
15530            scheduleAppGcsLocked();
15531        }
15532    }
15533
15534    /**
15535     * If all looks good, perform GCs on all processes waiting for them.
15536     */
15537    final void performAppGcsIfAppropriateLocked() {
15538        if (canGcNowLocked()) {
15539            performAppGcsLocked();
15540            return;
15541        }
15542        // Still not idle, wait some more.
15543        scheduleAppGcsLocked();
15544    }
15545
15546    /**
15547     * Schedule the execution of all pending app GCs.
15548     */
15549    final void scheduleAppGcsLocked() {
15550        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15551
15552        if (mProcessesToGc.size() > 0) {
15553            // Schedule a GC for the time to the next process.
15554            ProcessRecord proc = mProcessesToGc.get(0);
15555            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15556
15557            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15558            long now = SystemClock.uptimeMillis();
15559            if (when < (now+GC_TIMEOUT)) {
15560                when = now + GC_TIMEOUT;
15561            }
15562            mHandler.sendMessageAtTime(msg, when);
15563        }
15564    }
15565
15566    /**
15567     * Add a process to the array of processes waiting to be GCed.  Keeps the
15568     * list in sorted order by the last GC time.  The process can't already be
15569     * on the list.
15570     */
15571    final void addProcessToGcListLocked(ProcessRecord proc) {
15572        boolean added = false;
15573        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15574            if (mProcessesToGc.get(i).lastRequestedGc <
15575                    proc.lastRequestedGc) {
15576                added = true;
15577                mProcessesToGc.add(i+1, proc);
15578                break;
15579            }
15580        }
15581        if (!added) {
15582            mProcessesToGc.add(0, proc);
15583        }
15584    }
15585
15586    /**
15587     * Set up to ask a process to GC itself.  This will either do it
15588     * immediately, or put it on the list of processes to gc the next
15589     * time things are idle.
15590     */
15591    final void scheduleAppGcLocked(ProcessRecord app) {
15592        long now = SystemClock.uptimeMillis();
15593        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15594            return;
15595        }
15596        if (!mProcessesToGc.contains(app)) {
15597            addProcessToGcListLocked(app);
15598            scheduleAppGcsLocked();
15599        }
15600    }
15601
15602    final void checkExcessivePowerUsageLocked(boolean doKills) {
15603        updateCpuStatsNow();
15604
15605        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15606        boolean doWakeKills = doKills;
15607        boolean doCpuKills = doKills;
15608        if (mLastPowerCheckRealtime == 0) {
15609            doWakeKills = false;
15610        }
15611        if (mLastPowerCheckUptime == 0) {
15612            doCpuKills = false;
15613        }
15614        if (stats.isScreenOn()) {
15615            doWakeKills = false;
15616        }
15617        final long curRealtime = SystemClock.elapsedRealtime();
15618        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15619        final long curUptime = SystemClock.uptimeMillis();
15620        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15621        mLastPowerCheckRealtime = curRealtime;
15622        mLastPowerCheckUptime = curUptime;
15623        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15624            doWakeKills = false;
15625        }
15626        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15627            doCpuKills = false;
15628        }
15629        int i = mLruProcesses.size();
15630        while (i > 0) {
15631            i--;
15632            ProcessRecord app = mLruProcesses.get(i);
15633            if (!app.keeping) {
15634                long wtime;
15635                synchronized (stats) {
15636                    wtime = stats.getProcessWakeTime(app.info.uid,
15637                            app.pid, curRealtime);
15638                }
15639                long wtimeUsed = wtime - app.lastWakeTime;
15640                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15641                if (DEBUG_POWER) {
15642                    StringBuilder sb = new StringBuilder(128);
15643                    sb.append("Wake for ");
15644                    app.toShortString(sb);
15645                    sb.append(": over ");
15646                    TimeUtils.formatDuration(realtimeSince, sb);
15647                    sb.append(" used ");
15648                    TimeUtils.formatDuration(wtimeUsed, sb);
15649                    sb.append(" (");
15650                    sb.append((wtimeUsed*100)/realtimeSince);
15651                    sb.append("%)");
15652                    Slog.i(TAG, sb.toString());
15653                    sb.setLength(0);
15654                    sb.append("CPU for ");
15655                    app.toShortString(sb);
15656                    sb.append(": over ");
15657                    TimeUtils.formatDuration(uptimeSince, sb);
15658                    sb.append(" used ");
15659                    TimeUtils.formatDuration(cputimeUsed, sb);
15660                    sb.append(" (");
15661                    sb.append((cputimeUsed*100)/uptimeSince);
15662                    sb.append("%)");
15663                    Slog.i(TAG, sb.toString());
15664                }
15665                // If a process has held a wake lock for more
15666                // than 50% of the time during this period,
15667                // that sounds bad.  Kill!
15668                if (doWakeKills && realtimeSince > 0
15669                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15670                    synchronized (stats) {
15671                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15672                                realtimeSince, wtimeUsed);
15673                    }
15674                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15675                            + " during " + realtimeSince);
15676                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15677                } else if (doCpuKills && uptimeSince > 0
15678                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15679                    synchronized (stats) {
15680                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15681                                uptimeSince, cputimeUsed);
15682                    }
15683                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15684                            + " during " + uptimeSince);
15685                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15686                } else {
15687                    app.lastWakeTime = wtime;
15688                    app.lastCpuTime = app.curCpuTime;
15689                }
15690            }
15691        }
15692    }
15693
15694    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15695            ProcessRecord TOP_APP, boolean doingAll, long now) {
15696        boolean success = true;
15697
15698        if (app.curRawAdj != app.setRawAdj) {
15699            if (wasKeeping && !app.keeping) {
15700                // This app is no longer something we want to keep.  Note
15701                // its current wake lock time to later know to kill it if
15702                // it is not behaving well.
15703                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15704                synchronized (stats) {
15705                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15706                            app.pid, SystemClock.elapsedRealtime());
15707                }
15708                app.lastCpuTime = app.curCpuTime;
15709            }
15710
15711            app.setRawAdj = app.curRawAdj;
15712        }
15713
15714        int changes = 0;
15715
15716        if (app.curAdj != app.setAdj) {
15717            ProcessList.setOomAdj(app.pid, app.curAdj);
15718            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15719                TAG, "Set " + app.pid + " " + app.processName +
15720                " adj " + app.curAdj + ": " + app.adjType);
15721            app.setAdj = app.curAdj;
15722        }
15723
15724        if (app.setSchedGroup != app.curSchedGroup) {
15725            app.setSchedGroup = app.curSchedGroup;
15726            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15727                    "Setting process group of " + app.processName
15728                    + " to " + app.curSchedGroup);
15729            if (app.waitingToKill != null &&
15730                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15731                killUnneededProcessLocked(app, app.waitingToKill);
15732                success = false;
15733            } else {
15734                if (true) {
15735                    long oldId = Binder.clearCallingIdentity();
15736                    try {
15737                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15738                    } catch (Exception e) {
15739                        Slog.w(TAG, "Failed setting process group of " + app.pid
15740                                + " to " + app.curSchedGroup);
15741                        e.printStackTrace();
15742                    } finally {
15743                        Binder.restoreCallingIdentity(oldId);
15744                    }
15745                } else {
15746                    if (app.thread != null) {
15747                        try {
15748                            app.thread.setSchedulingGroup(app.curSchedGroup);
15749                        } catch (RemoteException e) {
15750                        }
15751                    }
15752                }
15753                Process.setSwappiness(app.pid,
15754                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15755            }
15756        }
15757        if (app.repForegroundActivities != app.foregroundActivities) {
15758            app.repForegroundActivities = app.foregroundActivities;
15759            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15760        }
15761        if (app.repProcState != app.curProcState) {
15762            app.repProcState = app.curProcState;
15763            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15764            if (app.thread != null) {
15765                try {
15766                    if (false) {
15767                        //RuntimeException h = new RuntimeException("here");
15768                        Slog.i(TAG, "Sending new process state " + app.repProcState
15769                                + " to " + app /*, h*/);
15770                    }
15771                    app.thread.setProcessState(app.repProcState);
15772                } catch (RemoteException e) {
15773                }
15774            }
15775        }
15776        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15777                app.setProcState)) {
15778            app.lastStateTime = now;
15779            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15780                    isSleeping(), now);
15781            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15782                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15783                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15784                    + (app.nextPssTime-now) + ": " + app);
15785        } else {
15786            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15787                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15788                requestPssLocked(app, app.setProcState);
15789                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15790                        isSleeping(), now);
15791            } else if (false && DEBUG_PSS) {
15792                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15793            }
15794        }
15795        if (app.setProcState != app.curProcState) {
15796            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15797                    "Proc state change of " + app.processName
15798                    + " to " + app.curProcState);
15799            app.setProcState = app.curProcState;
15800            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15801                app.notCachedSinceIdle = false;
15802            }
15803            if (!doingAll) {
15804                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15805            } else {
15806                app.procStateChanged = true;
15807            }
15808        }
15809
15810        if (changes != 0) {
15811            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15812            int i = mPendingProcessChanges.size()-1;
15813            ProcessChangeItem item = null;
15814            while (i >= 0) {
15815                item = mPendingProcessChanges.get(i);
15816                if (item.pid == app.pid) {
15817                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15818                    break;
15819                }
15820                i--;
15821            }
15822            if (i < 0) {
15823                // No existing item in pending changes; need a new one.
15824                final int NA = mAvailProcessChanges.size();
15825                if (NA > 0) {
15826                    item = mAvailProcessChanges.remove(NA-1);
15827                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15828                } else {
15829                    item = new ProcessChangeItem();
15830                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15831                }
15832                item.changes = 0;
15833                item.pid = app.pid;
15834                item.uid = app.info.uid;
15835                if (mPendingProcessChanges.size() == 0) {
15836                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15837                            "*** Enqueueing dispatch processes changed!");
15838                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15839                }
15840                mPendingProcessChanges.add(item);
15841            }
15842            item.changes |= changes;
15843            item.processState = app.repProcState;
15844            item.foregroundActivities = app.repForegroundActivities;
15845            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15846                    + Integer.toHexString(System.identityHashCode(item))
15847                    + " " + app.toShortString() + ": changes=" + item.changes
15848                    + " procState=" + item.processState
15849                    + " foreground=" + item.foregroundActivities
15850                    + " type=" + app.adjType + " source=" + app.adjSource
15851                    + " target=" + app.adjTarget);
15852        }
15853
15854        return success;
15855    }
15856
15857    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15858        if (proc.thread != null && proc.baseProcessTracker != null) {
15859            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15860        }
15861    }
15862
15863    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15864            ProcessRecord TOP_APP, boolean doingAll, long now) {
15865        if (app.thread == null) {
15866            return false;
15867        }
15868
15869        final boolean wasKeeping = app.keeping;
15870
15871        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15872
15873        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15874    }
15875
15876    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15877            boolean oomAdj) {
15878        if (isForeground != proc.foregroundServices) {
15879            proc.foregroundServices = isForeground;
15880            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15881                    proc.info.uid);
15882            if (isForeground) {
15883                if (curProcs == null) {
15884                    curProcs = new ArrayList<ProcessRecord>();
15885                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15886                }
15887                if (!curProcs.contains(proc)) {
15888                    curProcs.add(proc);
15889                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15890                            proc.info.packageName, proc.info.uid);
15891                }
15892            } else {
15893                if (curProcs != null) {
15894                    if (curProcs.remove(proc)) {
15895                        mBatteryStatsService.noteEvent(
15896                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15897                                proc.info.packageName, proc.info.uid);
15898                        if (curProcs.size() <= 0) {
15899                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15900                        }
15901                    }
15902                }
15903            }
15904            if (oomAdj) {
15905                updateOomAdjLocked();
15906            }
15907        }
15908    }
15909
15910    private final ActivityRecord resumedAppLocked() {
15911        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15912        String pkg;
15913        int uid;
15914        if (act != null && !act.sleeping) {
15915            pkg = act.packageName;
15916            uid = act.info.applicationInfo.uid;
15917        } else {
15918            pkg = null;
15919            uid = -1;
15920        }
15921        // Has the UID or resumed package name changed?
15922        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15923                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15924            if (mCurResumedPackage != null) {
15925                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15926                        mCurResumedPackage, mCurResumedUid);
15927            }
15928            mCurResumedPackage = pkg;
15929            mCurResumedUid = uid;
15930            if (mCurResumedPackage != null) {
15931                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15932                        mCurResumedPackage, mCurResumedUid);
15933            }
15934        }
15935        return act;
15936    }
15937
15938    final boolean updateOomAdjLocked(ProcessRecord app) {
15939        final ActivityRecord TOP_ACT = resumedAppLocked();
15940        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15941        final boolean wasCached = app.cached;
15942
15943        mAdjSeq++;
15944
15945        // This is the desired cached adjusment we want to tell it to use.
15946        // If our app is currently cached, we know it, and that is it.  Otherwise,
15947        // we don't know it yet, and it needs to now be cached we will then
15948        // need to do a complete oom adj.
15949        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15950                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15951        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15952                SystemClock.uptimeMillis());
15953        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15954            // Changed to/from cached state, so apps after it in the LRU
15955            // list may also be changed.
15956            updateOomAdjLocked();
15957        }
15958        return success;
15959    }
15960
15961    final void updateOomAdjLocked() {
15962        final ActivityRecord TOP_ACT = resumedAppLocked();
15963        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15964        final long now = SystemClock.uptimeMillis();
15965        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15966        final int N = mLruProcesses.size();
15967
15968        if (false) {
15969            RuntimeException e = new RuntimeException();
15970            e.fillInStackTrace();
15971            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15972        }
15973
15974        mAdjSeq++;
15975        mNewNumServiceProcs = 0;
15976        mNewNumAServiceProcs = 0;
15977
15978        final int emptyProcessLimit;
15979        final int cachedProcessLimit;
15980        if (mProcessLimit <= 0) {
15981            emptyProcessLimit = cachedProcessLimit = 0;
15982        } else if (mProcessLimit == 1) {
15983            emptyProcessLimit = 1;
15984            cachedProcessLimit = 0;
15985        } else {
15986            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15987            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15988        }
15989
15990        // Let's determine how many processes we have running vs.
15991        // how many slots we have for background processes; we may want
15992        // to put multiple processes in a slot of there are enough of
15993        // them.
15994        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15995                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15996        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15997        if (numEmptyProcs > cachedProcessLimit) {
15998            // If there are more empty processes than our limit on cached
15999            // processes, then use the cached process limit for the factor.
16000            // This ensures that the really old empty processes get pushed
16001            // down to the bottom, so if we are running low on memory we will
16002            // have a better chance at keeping around more cached processes
16003            // instead of a gazillion empty processes.
16004            numEmptyProcs = cachedProcessLimit;
16005        }
16006        int emptyFactor = numEmptyProcs/numSlots;
16007        if (emptyFactor < 1) emptyFactor = 1;
16008        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16009        if (cachedFactor < 1) cachedFactor = 1;
16010        int stepCached = 0;
16011        int stepEmpty = 0;
16012        int numCached = 0;
16013        int numEmpty = 0;
16014        int numTrimming = 0;
16015
16016        mNumNonCachedProcs = 0;
16017        mNumCachedHiddenProcs = 0;
16018
16019        // First update the OOM adjustment for each of the
16020        // application processes based on their current state.
16021        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16022        int nextCachedAdj = curCachedAdj+1;
16023        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16024        int nextEmptyAdj = curEmptyAdj+2;
16025        for (int i=N-1; i>=0; i--) {
16026            ProcessRecord app = mLruProcesses.get(i);
16027            if (!app.killedByAm && app.thread != null) {
16028                app.procStateChanged = false;
16029                final boolean wasKeeping = app.keeping;
16030                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16031
16032                // If we haven't yet assigned the final cached adj
16033                // to the process, do that now.
16034                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16035                    switch (app.curProcState) {
16036                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16037                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16038                            // This process is a cached process holding activities...
16039                            // assign it the next cached value for that type, and then
16040                            // step that cached level.
16041                            app.curRawAdj = curCachedAdj;
16042                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16043                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16044                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16045                                    + ")");
16046                            if (curCachedAdj != nextCachedAdj) {
16047                                stepCached++;
16048                                if (stepCached >= cachedFactor) {
16049                                    stepCached = 0;
16050                                    curCachedAdj = nextCachedAdj;
16051                                    nextCachedAdj += 2;
16052                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16053                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16054                                    }
16055                                }
16056                            }
16057                            break;
16058                        default:
16059                            // For everything else, assign next empty cached process
16060                            // level and bump that up.  Note that this means that
16061                            // long-running services that have dropped down to the
16062                            // cached level will be treated as empty (since their process
16063                            // state is still as a service), which is what we want.
16064                            app.curRawAdj = curEmptyAdj;
16065                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16066                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16067                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16068                                    + ")");
16069                            if (curEmptyAdj != nextEmptyAdj) {
16070                                stepEmpty++;
16071                                if (stepEmpty >= emptyFactor) {
16072                                    stepEmpty = 0;
16073                                    curEmptyAdj = nextEmptyAdj;
16074                                    nextEmptyAdj += 2;
16075                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16076                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16077                                    }
16078                                }
16079                            }
16080                            break;
16081                    }
16082                }
16083
16084                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16085
16086                // Count the number of process types.
16087                switch (app.curProcState) {
16088                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16089                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16090                        mNumCachedHiddenProcs++;
16091                        numCached++;
16092                        if (numCached > cachedProcessLimit) {
16093                            killUnneededProcessLocked(app, "cached #" + numCached);
16094                        }
16095                        break;
16096                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16097                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16098                                && app.lastActivityTime < oldTime) {
16099                            killUnneededProcessLocked(app, "empty for "
16100                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16101                                    / 1000) + "s");
16102                        } else {
16103                            numEmpty++;
16104                            if (numEmpty > emptyProcessLimit) {
16105                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16106                            }
16107                        }
16108                        break;
16109                    default:
16110                        mNumNonCachedProcs++;
16111                        break;
16112                }
16113
16114                if (app.isolated && app.services.size() <= 0) {
16115                    // If this is an isolated process, and there are no
16116                    // services running in it, then the process is no longer
16117                    // needed.  We agressively kill these because we can by
16118                    // definition not re-use the same process again, and it is
16119                    // good to avoid having whatever code was running in them
16120                    // left sitting around after no longer needed.
16121                    killUnneededProcessLocked(app, "isolated not needed");
16122                }
16123
16124                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16125                        && !app.killedByAm) {
16126                    numTrimming++;
16127                }
16128            }
16129        }
16130
16131        mNumServiceProcs = mNewNumServiceProcs;
16132
16133        // Now determine the memory trimming level of background processes.
16134        // Unfortunately we need to start at the back of the list to do this
16135        // properly.  We only do this if the number of background apps we
16136        // are managing to keep around is less than half the maximum we desire;
16137        // if we are keeping a good number around, we'll let them use whatever
16138        // memory they want.
16139        final int numCachedAndEmpty = numCached + numEmpty;
16140        int memFactor;
16141        if (numCached <= ProcessList.TRIM_CACHED_APPS
16142                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16143            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16144                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16145            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16146                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16147            } else {
16148                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16149            }
16150        } else {
16151            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16152        }
16153        // We always allow the memory level to go up (better).  We only allow it to go
16154        // down if we are in a state where that is allowed, *and* the total number of processes
16155        // has gone down since last time.
16156        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16157                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16158                + " last=" + mLastNumProcesses);
16159        if (memFactor > mLastMemoryLevel) {
16160            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16161                memFactor = mLastMemoryLevel;
16162                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16163            }
16164        }
16165        mLastMemoryLevel = memFactor;
16166        mLastNumProcesses = mLruProcesses.size();
16167        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16168        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16169        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16170            if (mLowRamStartTime == 0) {
16171                mLowRamStartTime = now;
16172            }
16173            int step = 0;
16174            int fgTrimLevel;
16175            switch (memFactor) {
16176                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16177                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16178                    break;
16179                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16180                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16181                    break;
16182                default:
16183                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16184                    break;
16185            }
16186            int factor = numTrimming/3;
16187            int minFactor = 2;
16188            if (mHomeProcess != null) minFactor++;
16189            if (mPreviousProcess != null) minFactor++;
16190            if (factor < minFactor) factor = minFactor;
16191            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16192            for (int i=N-1; i>=0; i--) {
16193                ProcessRecord app = mLruProcesses.get(i);
16194                if (allChanged || app.procStateChanged) {
16195                    setProcessTrackerState(app, trackerMemFactor, now);
16196                    app.procStateChanged = false;
16197                }
16198                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16199                        && !app.killedByAm) {
16200                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16201                        try {
16202                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16203                                    "Trimming memory of " + app.processName
16204                                    + " to " + curLevel);
16205                            app.thread.scheduleTrimMemory(curLevel);
16206                        } catch (RemoteException e) {
16207                        }
16208                        if (false) {
16209                            // For now we won't do this; our memory trimming seems
16210                            // to be good enough at this point that destroying
16211                            // activities causes more harm than good.
16212                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16213                                    && app != mHomeProcess && app != mPreviousProcess) {
16214                                // Need to do this on its own message because the stack may not
16215                                // be in a consistent state at this point.
16216                                // For these apps we will also finish their activities
16217                                // to help them free memory.
16218                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16219                            }
16220                        }
16221                    }
16222                    app.trimMemoryLevel = curLevel;
16223                    step++;
16224                    if (step >= factor) {
16225                        step = 0;
16226                        switch (curLevel) {
16227                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16228                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16229                                break;
16230                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16231                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16232                                break;
16233                        }
16234                    }
16235                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16236                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16237                            && app.thread != null) {
16238                        try {
16239                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16240                                    "Trimming memory of heavy-weight " + app.processName
16241                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16242                            app.thread.scheduleTrimMemory(
16243                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16244                        } catch (RemoteException e) {
16245                        }
16246                    }
16247                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16248                } else {
16249                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16250                            || app.systemNoUi) && app.pendingUiClean) {
16251                        // If this application is now in the background and it
16252                        // had done UI, then give it the special trim level to
16253                        // have it free UI resources.
16254                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16255                        if (app.trimMemoryLevel < level && app.thread != null) {
16256                            try {
16257                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16258                                        "Trimming memory of bg-ui " + app.processName
16259                                        + " to " + level);
16260                                app.thread.scheduleTrimMemory(level);
16261                            } catch (RemoteException e) {
16262                            }
16263                        }
16264                        app.pendingUiClean = false;
16265                    }
16266                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16267                        try {
16268                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16269                                    "Trimming memory of fg " + app.processName
16270                                    + " to " + fgTrimLevel);
16271                            app.thread.scheduleTrimMemory(fgTrimLevel);
16272                        } catch (RemoteException e) {
16273                        }
16274                    }
16275                    app.trimMemoryLevel = fgTrimLevel;
16276                }
16277            }
16278        } else {
16279            if (mLowRamStartTime != 0) {
16280                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16281                mLowRamStartTime = 0;
16282            }
16283            for (int i=N-1; i>=0; i--) {
16284                ProcessRecord app = mLruProcesses.get(i);
16285                if (allChanged || app.procStateChanged) {
16286                    setProcessTrackerState(app, trackerMemFactor, now);
16287                    app.procStateChanged = false;
16288                }
16289                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16290                        || app.systemNoUi) && app.pendingUiClean) {
16291                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16292                            && app.thread != null) {
16293                        try {
16294                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16295                                    "Trimming memory of ui hidden " + app.processName
16296                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16297                            app.thread.scheduleTrimMemory(
16298                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16299                        } catch (RemoteException e) {
16300                        }
16301                    }
16302                    app.pendingUiClean = false;
16303                }
16304                app.trimMemoryLevel = 0;
16305            }
16306        }
16307
16308        if (mAlwaysFinishActivities) {
16309            // Need to do this on its own message because the stack may not
16310            // be in a consistent state at this point.
16311            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16312        }
16313
16314        if (allChanged) {
16315            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16316        }
16317
16318        if (mProcessStats.shouldWriteNowLocked(now)) {
16319            mHandler.post(new Runnable() {
16320                @Override public void run() {
16321                    synchronized (ActivityManagerService.this) {
16322                        mProcessStats.writeStateAsyncLocked();
16323                    }
16324                }
16325            });
16326        }
16327
16328        if (DEBUG_OOM_ADJ) {
16329            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16330        }
16331    }
16332
16333    final void trimApplications() {
16334        synchronized (this) {
16335            int i;
16336
16337            // First remove any unused application processes whose package
16338            // has been removed.
16339            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16340                final ProcessRecord app = mRemovedProcesses.get(i);
16341                if (app.activities.size() == 0
16342                        && app.curReceiver == null && app.services.size() == 0) {
16343                    Slog.i(
16344                        TAG, "Exiting empty application process "
16345                        + app.processName + " ("
16346                        + (app.thread != null ? app.thread.asBinder() : null)
16347                        + ")\n");
16348                    if (app.pid > 0 && app.pid != MY_PID) {
16349                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16350                                app.processName, app.setAdj, "empty");
16351                        app.killedByAm = true;
16352                        Process.killProcessQuiet(app.pid);
16353                    } else {
16354                        try {
16355                            app.thread.scheduleExit();
16356                        } catch (Exception e) {
16357                            // Ignore exceptions.
16358                        }
16359                    }
16360                    cleanUpApplicationRecordLocked(app, false, true, -1);
16361                    mRemovedProcesses.remove(i);
16362
16363                    if (app.persistent) {
16364                        if (app.persistent) {
16365                            addAppLocked(app.info, false, null /* ABI override */);
16366                        }
16367                    }
16368                }
16369            }
16370
16371            // Now update the oom adj for all processes.
16372            updateOomAdjLocked();
16373        }
16374    }
16375
16376    /** This method sends the specified signal to each of the persistent apps */
16377    public void signalPersistentProcesses(int sig) throws RemoteException {
16378        if (sig != Process.SIGNAL_USR1) {
16379            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16380        }
16381
16382        synchronized (this) {
16383            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16384                    != PackageManager.PERMISSION_GRANTED) {
16385                throw new SecurityException("Requires permission "
16386                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16387            }
16388
16389            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16390                ProcessRecord r = mLruProcesses.get(i);
16391                if (r.thread != null && r.persistent) {
16392                    Process.sendSignal(r.pid, sig);
16393                }
16394            }
16395        }
16396    }
16397
16398    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16399        if (proc == null || proc == mProfileProc) {
16400            proc = mProfileProc;
16401            path = mProfileFile;
16402            profileType = mProfileType;
16403            clearProfilerLocked();
16404        }
16405        if (proc == null) {
16406            return;
16407        }
16408        try {
16409            proc.thread.profilerControl(false, path, null, profileType);
16410        } catch (RemoteException e) {
16411            throw new IllegalStateException("Process disappeared");
16412        }
16413    }
16414
16415    private void clearProfilerLocked() {
16416        if (mProfileFd != null) {
16417            try {
16418                mProfileFd.close();
16419            } catch (IOException e) {
16420            }
16421        }
16422        mProfileApp = null;
16423        mProfileProc = null;
16424        mProfileFile = null;
16425        mProfileType = 0;
16426        mAutoStopProfiler = false;
16427    }
16428
16429    public boolean profileControl(String process, int userId, boolean start,
16430            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16431
16432        try {
16433            synchronized (this) {
16434                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16435                // its own permission.
16436                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16437                        != PackageManager.PERMISSION_GRANTED) {
16438                    throw new SecurityException("Requires permission "
16439                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16440                }
16441
16442                if (start && fd == null) {
16443                    throw new IllegalArgumentException("null fd");
16444                }
16445
16446                ProcessRecord proc = null;
16447                if (process != null) {
16448                    proc = findProcessLocked(process, userId, "profileControl");
16449                }
16450
16451                if (start && (proc == null || proc.thread == null)) {
16452                    throw new IllegalArgumentException("Unknown process: " + process);
16453                }
16454
16455                if (start) {
16456                    stopProfilerLocked(null, null, 0);
16457                    setProfileApp(proc.info, proc.processName, path, fd, false);
16458                    mProfileProc = proc;
16459                    mProfileType = profileType;
16460                    try {
16461                        fd = fd.dup();
16462                    } catch (IOException e) {
16463                        fd = null;
16464                    }
16465                    proc.thread.profilerControl(start, path, fd, profileType);
16466                    fd = null;
16467                    mProfileFd = null;
16468                } else {
16469                    stopProfilerLocked(proc, path, profileType);
16470                    if (fd != null) {
16471                        try {
16472                            fd.close();
16473                        } catch (IOException e) {
16474                        }
16475                    }
16476                }
16477
16478                return true;
16479            }
16480        } catch (RemoteException e) {
16481            throw new IllegalStateException("Process disappeared");
16482        } finally {
16483            if (fd != null) {
16484                try {
16485                    fd.close();
16486                } catch (IOException e) {
16487                }
16488            }
16489        }
16490    }
16491
16492    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16493        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16494                userId, true, true, callName, null);
16495        ProcessRecord proc = null;
16496        try {
16497            int pid = Integer.parseInt(process);
16498            synchronized (mPidsSelfLocked) {
16499                proc = mPidsSelfLocked.get(pid);
16500            }
16501        } catch (NumberFormatException e) {
16502        }
16503
16504        if (proc == null) {
16505            ArrayMap<String, SparseArray<ProcessRecord>> all
16506                    = mProcessNames.getMap();
16507            SparseArray<ProcessRecord> procs = all.get(process);
16508            if (procs != null && procs.size() > 0) {
16509                proc = procs.valueAt(0);
16510                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16511                    for (int i=1; i<procs.size(); i++) {
16512                        ProcessRecord thisProc = procs.valueAt(i);
16513                        if (thisProc.userId == userId) {
16514                            proc = thisProc;
16515                            break;
16516                        }
16517                    }
16518                }
16519            }
16520        }
16521
16522        return proc;
16523    }
16524
16525    public boolean dumpHeap(String process, int userId, boolean managed,
16526            String path, ParcelFileDescriptor fd) throws RemoteException {
16527
16528        try {
16529            synchronized (this) {
16530                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16531                // its own permission (same as profileControl).
16532                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16533                        != PackageManager.PERMISSION_GRANTED) {
16534                    throw new SecurityException("Requires permission "
16535                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16536                }
16537
16538                if (fd == null) {
16539                    throw new IllegalArgumentException("null fd");
16540                }
16541
16542                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16543                if (proc == null || proc.thread == null) {
16544                    throw new IllegalArgumentException("Unknown process: " + process);
16545                }
16546
16547                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16548                if (!isDebuggable) {
16549                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16550                        throw new SecurityException("Process not debuggable: " + proc);
16551                    }
16552                }
16553
16554                proc.thread.dumpHeap(managed, path, fd);
16555                fd = null;
16556                return true;
16557            }
16558        } catch (RemoteException e) {
16559            throw new IllegalStateException("Process disappeared");
16560        } finally {
16561            if (fd != null) {
16562                try {
16563                    fd.close();
16564                } catch (IOException e) {
16565                }
16566            }
16567        }
16568    }
16569
16570    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16571    public void monitor() {
16572        synchronized (this) { }
16573    }
16574
16575    void onCoreSettingsChange(Bundle settings) {
16576        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16577            ProcessRecord processRecord = mLruProcesses.get(i);
16578            try {
16579                if (processRecord.thread != null) {
16580                    processRecord.thread.setCoreSettings(settings);
16581                }
16582            } catch (RemoteException re) {
16583                /* ignore */
16584            }
16585        }
16586    }
16587
16588    // Multi-user methods
16589
16590    /**
16591     * Start user, if its not already running, but don't bring it to foreground.
16592     */
16593    @Override
16594    public boolean startUserInBackground(final int userId) {
16595        return startUser(userId, /* foreground */ false);
16596    }
16597
16598    /**
16599     * Refreshes the list of users related to the current user when either a
16600     * user switch happens or when a new related user is started in the
16601     * background.
16602     */
16603    private void updateCurrentProfileIdsLocked() {
16604        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16605                mCurrentUserId, false /* enabledOnly */);
16606        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16607        for (int i = 0; i < currentProfileIds.length; i++) {
16608            currentProfileIds[i] = profiles.get(i).id;
16609        }
16610        mCurrentProfileIds = currentProfileIds;
16611    }
16612
16613    private Set getProfileIdsLocked(int userId) {
16614        Set userIds = new HashSet<Integer>();
16615        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16616                userId, false /* enabledOnly */);
16617        for (UserInfo user : profiles) {
16618            userIds.add(Integer.valueOf(user.id));
16619        }
16620        return userIds;
16621    }
16622
16623    @Override
16624    public boolean switchUser(final int userId) {
16625        return startUser(userId, /* foregound */ true);
16626    }
16627
16628    private boolean startUser(final int userId, boolean foreground) {
16629        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16630                != PackageManager.PERMISSION_GRANTED) {
16631            String msg = "Permission Denial: switchUser() from pid="
16632                    + Binder.getCallingPid()
16633                    + ", uid=" + Binder.getCallingUid()
16634                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16635            Slog.w(TAG, msg);
16636            throw new SecurityException(msg);
16637        }
16638
16639        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16640
16641        final long ident = Binder.clearCallingIdentity();
16642        try {
16643            synchronized (this) {
16644                final int oldUserId = mCurrentUserId;
16645                if (oldUserId == userId) {
16646                    return true;
16647                }
16648
16649                mStackSupervisor.setLockTaskModeLocked(null);
16650
16651                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16652                if (userInfo == null) {
16653                    Slog.w(TAG, "No user info for user #" + userId);
16654                    return false;
16655                }
16656
16657                if (foreground) {
16658                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16659                            R.anim.screen_user_enter);
16660                }
16661
16662                boolean needStart = false;
16663
16664                // If the user we are switching to is not currently started, then
16665                // we need to start it now.
16666                if (mStartedUsers.get(userId) == null) {
16667                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16668                    updateStartedUserArrayLocked();
16669                    needStart = true;
16670                }
16671
16672                final Integer userIdInt = Integer.valueOf(userId);
16673                mUserLru.remove(userIdInt);
16674                mUserLru.add(userIdInt);
16675
16676                if (foreground) {
16677                    mCurrentUserId = userId;
16678                    updateCurrentProfileIdsLocked();
16679                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16680                    // Once the internal notion of the active user has switched, we lock the device
16681                    // with the option to show the user switcher on the keyguard.
16682                    mWindowManager.lockNow(null);
16683                } else {
16684                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16685                    updateCurrentProfileIdsLocked();
16686                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16687                    mUserLru.remove(currentUserIdInt);
16688                    mUserLru.add(currentUserIdInt);
16689                }
16690
16691                final UserStartedState uss = mStartedUsers.get(userId);
16692
16693                // Make sure user is in the started state.  If it is currently
16694                // stopping, we need to knock that off.
16695                if (uss.mState == UserStartedState.STATE_STOPPING) {
16696                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16697                    // so we can just fairly silently bring the user back from
16698                    // the almost-dead.
16699                    uss.mState = UserStartedState.STATE_RUNNING;
16700                    updateStartedUserArrayLocked();
16701                    needStart = true;
16702                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16703                    // This means ACTION_SHUTDOWN has been sent, so we will
16704                    // need to treat this as a new boot of the user.
16705                    uss.mState = UserStartedState.STATE_BOOTING;
16706                    updateStartedUserArrayLocked();
16707                    needStart = true;
16708                }
16709
16710                if (uss.mState == UserStartedState.STATE_BOOTING) {
16711                    // Booting up a new user, need to tell system services about it.
16712                    // Note that this is on the same handler as scheduling of broadcasts,
16713                    // which is important because it needs to go first.
16714                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16715                }
16716
16717                if (foreground) {
16718                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16719                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16720                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16721                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16722                            oldUserId, userId, uss));
16723                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16724                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16725                }
16726
16727                if (needStart) {
16728                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16729                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16730                            | Intent.FLAG_RECEIVER_FOREGROUND);
16731                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16732                    broadcastIntentLocked(null, null, intent,
16733                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16734                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16735                }
16736
16737                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16738                    if (userId != UserHandle.USER_OWNER) {
16739                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16740                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16741                        broadcastIntentLocked(null, null, intent, null,
16742                                new IIntentReceiver.Stub() {
16743                                    public void performReceive(Intent intent, int resultCode,
16744                                            String data, Bundle extras, boolean ordered,
16745                                            boolean sticky, int sendingUser) {
16746                                        userInitialized(uss, userId);
16747                                    }
16748                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16749                                true, false, MY_PID, Process.SYSTEM_UID,
16750                                userId);
16751                        uss.initializing = true;
16752                    } else {
16753                        getUserManagerLocked().makeInitialized(userInfo.id);
16754                    }
16755                }
16756
16757                if (foreground) {
16758                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16759                    if (homeInFront) {
16760                        startHomeActivityLocked(userId);
16761                    } else {
16762                        mStackSupervisor.resumeTopActivitiesLocked();
16763                    }
16764                    EventLogTags.writeAmSwitchUser(userId);
16765                    getUserManagerLocked().userForeground(userId);
16766                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16767                } else {
16768                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16769                }
16770
16771                if (needStart) {
16772                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16773                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16774                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16775                    broadcastIntentLocked(null, null, intent,
16776                            null, new IIntentReceiver.Stub() {
16777                                @Override
16778                                public void performReceive(Intent intent, int resultCode, String data,
16779                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16780                                        throws RemoteException {
16781                                }
16782                            }, 0, null, null,
16783                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16784                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16785                }
16786            }
16787        } finally {
16788            Binder.restoreCallingIdentity(ident);
16789        }
16790
16791        return true;
16792    }
16793
16794    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16795        long ident = Binder.clearCallingIdentity();
16796        try {
16797            Intent intent;
16798            if (oldUserId >= 0) {
16799                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16800                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16801                        | Intent.FLAG_RECEIVER_FOREGROUND);
16802                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16803                broadcastIntentLocked(null, null, intent,
16804                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16805                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16806            }
16807            if (newUserId >= 0) {
16808                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16809                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16810                        | Intent.FLAG_RECEIVER_FOREGROUND);
16811                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16812                broadcastIntentLocked(null, null, intent,
16813                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16814                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16815                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16816                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16817                        | Intent.FLAG_RECEIVER_FOREGROUND);
16818                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16819                broadcastIntentLocked(null, null, intent,
16820                        null, null, 0, null, null,
16821                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16822                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16823            }
16824        } finally {
16825            Binder.restoreCallingIdentity(ident);
16826        }
16827    }
16828
16829    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16830            final int newUserId) {
16831        final int N = mUserSwitchObservers.beginBroadcast();
16832        if (N > 0) {
16833            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16834                int mCount = 0;
16835                @Override
16836                public void sendResult(Bundle data) throws RemoteException {
16837                    synchronized (ActivityManagerService.this) {
16838                        if (mCurUserSwitchCallback == this) {
16839                            mCount++;
16840                            if (mCount == N) {
16841                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16842                            }
16843                        }
16844                    }
16845                }
16846            };
16847            synchronized (this) {
16848                uss.switching = true;
16849                mCurUserSwitchCallback = callback;
16850            }
16851            for (int i=0; i<N; i++) {
16852                try {
16853                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16854                            newUserId, callback);
16855                } catch (RemoteException e) {
16856                }
16857            }
16858        } else {
16859            synchronized (this) {
16860                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16861            }
16862        }
16863        mUserSwitchObservers.finishBroadcast();
16864    }
16865
16866    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16867        synchronized (this) {
16868            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16869            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16870        }
16871    }
16872
16873    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16874        mCurUserSwitchCallback = null;
16875        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16876        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16877                oldUserId, newUserId, uss));
16878    }
16879
16880    void userInitialized(UserStartedState uss, int newUserId) {
16881        completeSwitchAndInitalize(uss, newUserId, true, false);
16882    }
16883
16884    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16885        completeSwitchAndInitalize(uss, newUserId, false, true);
16886    }
16887
16888    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16889            boolean clearInitializing, boolean clearSwitching) {
16890        boolean unfrozen = false;
16891        synchronized (this) {
16892            if (clearInitializing) {
16893                uss.initializing = false;
16894                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16895            }
16896            if (clearSwitching) {
16897                uss.switching = false;
16898            }
16899            if (!uss.switching && !uss.initializing) {
16900                mWindowManager.stopFreezingScreen();
16901                unfrozen = true;
16902            }
16903        }
16904        if (unfrozen) {
16905            final int N = mUserSwitchObservers.beginBroadcast();
16906            for (int i=0; i<N; i++) {
16907                try {
16908                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16909                } catch (RemoteException e) {
16910                }
16911            }
16912            mUserSwitchObservers.finishBroadcast();
16913        }
16914    }
16915
16916    void scheduleStartProfilesLocked() {
16917        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16918            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16919                    DateUtils.SECOND_IN_MILLIS);
16920        }
16921    }
16922
16923    void startProfilesLocked() {
16924        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16925        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16926                mCurrentUserId, false /* enabledOnly */);
16927        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16928        for (UserInfo user : profiles) {
16929            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16930                    && user.id != mCurrentUserId) {
16931                toStart.add(user);
16932            }
16933        }
16934        final int n = toStart.size();
16935        int i = 0;
16936        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16937            startUserInBackground(toStart.get(i).id);
16938        }
16939        if (i < n) {
16940            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16941        }
16942    }
16943
16944    void finishUserBoot(UserStartedState uss) {
16945        synchronized (this) {
16946            if (uss.mState == UserStartedState.STATE_BOOTING
16947                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16948                uss.mState = UserStartedState.STATE_RUNNING;
16949                final int userId = uss.mHandle.getIdentifier();
16950                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16951                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16952                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16953                broadcastIntentLocked(null, null, intent,
16954                        null, null, 0, null, null,
16955                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16956                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16957            }
16958        }
16959    }
16960
16961    void finishUserSwitch(UserStartedState uss) {
16962        synchronized (this) {
16963            finishUserBoot(uss);
16964
16965            startProfilesLocked();
16966
16967            int num = mUserLru.size();
16968            int i = 0;
16969            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16970                Integer oldUserId = mUserLru.get(i);
16971                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16972                if (oldUss == null) {
16973                    // Shouldn't happen, but be sane if it does.
16974                    mUserLru.remove(i);
16975                    num--;
16976                    continue;
16977                }
16978                if (oldUss.mState == UserStartedState.STATE_STOPPING
16979                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16980                    // This user is already stopping, doesn't count.
16981                    num--;
16982                    i++;
16983                    continue;
16984                }
16985                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16986                    // Owner and current can't be stopped, but count as running.
16987                    i++;
16988                    continue;
16989                }
16990                // This is a user to be stopped.
16991                stopUserLocked(oldUserId, null);
16992                num--;
16993                i++;
16994            }
16995        }
16996    }
16997
16998    @Override
16999    public int stopUser(final int userId, final IStopUserCallback callback) {
17000        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17001                != PackageManager.PERMISSION_GRANTED) {
17002            String msg = "Permission Denial: switchUser() from pid="
17003                    + Binder.getCallingPid()
17004                    + ", uid=" + Binder.getCallingUid()
17005                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17006            Slog.w(TAG, msg);
17007            throw new SecurityException(msg);
17008        }
17009        if (userId <= 0) {
17010            throw new IllegalArgumentException("Can't stop primary user " + userId);
17011        }
17012        synchronized (this) {
17013            return stopUserLocked(userId, callback);
17014        }
17015    }
17016
17017    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17018        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17019        if (mCurrentUserId == userId) {
17020            return ActivityManager.USER_OP_IS_CURRENT;
17021        }
17022
17023        final UserStartedState uss = mStartedUsers.get(userId);
17024        if (uss == null) {
17025            // User is not started, nothing to do...  but we do need to
17026            // callback if requested.
17027            if (callback != null) {
17028                mHandler.post(new Runnable() {
17029                    @Override
17030                    public void run() {
17031                        try {
17032                            callback.userStopped(userId);
17033                        } catch (RemoteException e) {
17034                        }
17035                    }
17036                });
17037            }
17038            return ActivityManager.USER_OP_SUCCESS;
17039        }
17040
17041        if (callback != null) {
17042            uss.mStopCallbacks.add(callback);
17043        }
17044
17045        if (uss.mState != UserStartedState.STATE_STOPPING
17046                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17047            uss.mState = UserStartedState.STATE_STOPPING;
17048            updateStartedUserArrayLocked();
17049
17050            long ident = Binder.clearCallingIdentity();
17051            try {
17052                // We are going to broadcast ACTION_USER_STOPPING and then
17053                // once that is done send a final ACTION_SHUTDOWN and then
17054                // stop the user.
17055                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17056                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17057                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17058                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17059                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17060                // This is the result receiver for the final shutdown broadcast.
17061                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17062                    @Override
17063                    public void performReceive(Intent intent, int resultCode, String data,
17064                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17065                        finishUserStop(uss);
17066                    }
17067                };
17068                // This is the result receiver for the initial stopping broadcast.
17069                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17070                    @Override
17071                    public void performReceive(Intent intent, int resultCode, String data,
17072                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17073                        // On to the next.
17074                        synchronized (ActivityManagerService.this) {
17075                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17076                                // Whoops, we are being started back up.  Abort, abort!
17077                                return;
17078                            }
17079                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17080                        }
17081                        mSystemServiceManager.stopUser(userId);
17082                        broadcastIntentLocked(null, null, shutdownIntent,
17083                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17084                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17085                    }
17086                };
17087                // Kick things off.
17088                broadcastIntentLocked(null, null, stoppingIntent,
17089                        null, stoppingReceiver, 0, null, null,
17090                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17091                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17092            } finally {
17093                Binder.restoreCallingIdentity(ident);
17094            }
17095        }
17096
17097        return ActivityManager.USER_OP_SUCCESS;
17098    }
17099
17100    void finishUserStop(UserStartedState uss) {
17101        final int userId = uss.mHandle.getIdentifier();
17102        boolean stopped;
17103        ArrayList<IStopUserCallback> callbacks;
17104        synchronized (this) {
17105            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17106            if (mStartedUsers.get(userId) != uss) {
17107                stopped = false;
17108            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17109                stopped = false;
17110            } else {
17111                stopped = true;
17112                // User can no longer run.
17113                mStartedUsers.remove(userId);
17114                mUserLru.remove(Integer.valueOf(userId));
17115                updateStartedUserArrayLocked();
17116
17117                // Clean up all state and processes associated with the user.
17118                // Kill all the processes for the user.
17119                forceStopUserLocked(userId, "finish user");
17120            }
17121        }
17122
17123        for (int i=0; i<callbacks.size(); i++) {
17124            try {
17125                if (stopped) callbacks.get(i).userStopped(userId);
17126                else callbacks.get(i).userStopAborted(userId);
17127            } catch (RemoteException e) {
17128            }
17129        }
17130
17131        if (stopped) {
17132            mSystemServiceManager.cleanupUser(userId);
17133            synchronized (this) {
17134                mStackSupervisor.removeUserLocked(userId);
17135            }
17136        }
17137    }
17138
17139    @Override
17140    public UserInfo getCurrentUser() {
17141        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17142                != PackageManager.PERMISSION_GRANTED) && (
17143                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17144                != PackageManager.PERMISSION_GRANTED)) {
17145            String msg = "Permission Denial: getCurrentUser() from pid="
17146                    + Binder.getCallingPid()
17147                    + ", uid=" + Binder.getCallingUid()
17148                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17149            Slog.w(TAG, msg);
17150            throw new SecurityException(msg);
17151        }
17152        synchronized (this) {
17153            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17154        }
17155    }
17156
17157    int getCurrentUserIdLocked() {
17158        return mCurrentUserId;
17159    }
17160
17161    @Override
17162    public boolean isUserRunning(int userId, boolean orStopped) {
17163        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17164                != PackageManager.PERMISSION_GRANTED) {
17165            String msg = "Permission Denial: isUserRunning() from pid="
17166                    + Binder.getCallingPid()
17167                    + ", uid=" + Binder.getCallingUid()
17168                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17169            Slog.w(TAG, msg);
17170            throw new SecurityException(msg);
17171        }
17172        synchronized (this) {
17173            return isUserRunningLocked(userId, orStopped);
17174        }
17175    }
17176
17177    boolean isUserRunningLocked(int userId, boolean orStopped) {
17178        UserStartedState state = mStartedUsers.get(userId);
17179        if (state == null) {
17180            return false;
17181        }
17182        if (orStopped) {
17183            return true;
17184        }
17185        return state.mState != UserStartedState.STATE_STOPPING
17186                && state.mState != UserStartedState.STATE_SHUTDOWN;
17187    }
17188
17189    @Override
17190    public int[] getRunningUserIds() {
17191        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17192                != PackageManager.PERMISSION_GRANTED) {
17193            String msg = "Permission Denial: isUserRunning() from pid="
17194                    + Binder.getCallingPid()
17195                    + ", uid=" + Binder.getCallingUid()
17196                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17197            Slog.w(TAG, msg);
17198            throw new SecurityException(msg);
17199        }
17200        synchronized (this) {
17201            return mStartedUserArray;
17202        }
17203    }
17204
17205    private void updateStartedUserArrayLocked() {
17206        int num = 0;
17207        for (int i=0; i<mStartedUsers.size();  i++) {
17208            UserStartedState uss = mStartedUsers.valueAt(i);
17209            // This list does not include stopping users.
17210            if (uss.mState != UserStartedState.STATE_STOPPING
17211                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17212                num++;
17213            }
17214        }
17215        mStartedUserArray = new int[num];
17216        num = 0;
17217        for (int i=0; i<mStartedUsers.size();  i++) {
17218            UserStartedState uss = mStartedUsers.valueAt(i);
17219            if (uss.mState != UserStartedState.STATE_STOPPING
17220                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17221                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17222                num++;
17223            }
17224        }
17225    }
17226
17227    @Override
17228    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17229        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17230                != PackageManager.PERMISSION_GRANTED) {
17231            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17232                    + Binder.getCallingPid()
17233                    + ", uid=" + Binder.getCallingUid()
17234                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17235            Slog.w(TAG, msg);
17236            throw new SecurityException(msg);
17237        }
17238
17239        mUserSwitchObservers.register(observer);
17240    }
17241
17242    @Override
17243    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17244        mUserSwitchObservers.unregister(observer);
17245    }
17246
17247    private boolean userExists(int userId) {
17248        if (userId == 0) {
17249            return true;
17250        }
17251        UserManagerService ums = getUserManagerLocked();
17252        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17253    }
17254
17255    int[] getUsersLocked() {
17256        UserManagerService ums = getUserManagerLocked();
17257        return ums != null ? ums.getUserIds() : new int[] { 0 };
17258    }
17259
17260    UserManagerService getUserManagerLocked() {
17261        if (mUserManager == null) {
17262            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17263            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17264        }
17265        return mUserManager;
17266    }
17267
17268    private int applyUserId(int uid, int userId) {
17269        return UserHandle.getUid(userId, uid);
17270    }
17271
17272    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17273        if (info == null) return null;
17274        ApplicationInfo newInfo = new ApplicationInfo(info);
17275        newInfo.uid = applyUserId(info.uid, userId);
17276        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17277                + info.packageName;
17278        return newInfo;
17279    }
17280
17281    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17282        if (aInfo == null
17283                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17284            return aInfo;
17285        }
17286
17287        ActivityInfo info = new ActivityInfo(aInfo);
17288        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17289        return info;
17290    }
17291
17292    private final class LocalService extends ActivityManagerInternal {
17293        @Override
17294        public void goingToSleep() {
17295            ActivityManagerService.this.goingToSleep();
17296        }
17297
17298        @Override
17299        public void wakingUp() {
17300            ActivityManagerService.this.wakingUp();
17301        }
17302    }
17303
17304    /**
17305     * An implementation of IAppTask, that allows an app to manage its own tasks via
17306     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17307     * only the process that calls getAppTasks() can call the AppTask methods.
17308     */
17309    class AppTaskImpl extends IAppTask.Stub {
17310        private int mTaskId;
17311        private int mCallingUid;
17312
17313        public AppTaskImpl(int taskId, int callingUid) {
17314            mTaskId = taskId;
17315            mCallingUid = callingUid;
17316        }
17317
17318        @Override
17319        public void finishAndRemoveTask() {
17320            // Ensure that we are called from the same process that created this AppTask
17321            if (mCallingUid != Binder.getCallingUid()) {
17322                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17323                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17324                return;
17325            }
17326
17327            synchronized (ActivityManagerService.this) {
17328                long origId = Binder.clearCallingIdentity();
17329                try {
17330                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17331                    if (tr != null) {
17332                        // Only kill the process if we are not a new document
17333                        int flags = tr.getBaseIntent().getFlags();
17334                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17335                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17336                        removeTaskByIdLocked(mTaskId,
17337                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17338                    }
17339                } finally {
17340                    Binder.restoreCallingIdentity(origId);
17341                }
17342            }
17343        }
17344
17345        @Override
17346        public ActivityManager.RecentTaskInfo getTaskInfo() {
17347            // Ensure that we are called from the same process that created this AppTask
17348            if (mCallingUid != Binder.getCallingUid()) {
17349                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17350                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17351                return null;
17352            }
17353
17354            synchronized (ActivityManagerService.this) {
17355                long origId = Binder.clearCallingIdentity();
17356                try {
17357                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17358                    if (tr != null) {
17359                        return createRecentTaskInfoFromTaskRecord(tr);
17360                    }
17361                } finally {
17362                    Binder.restoreCallingIdentity(origId);
17363                }
17364                return null;
17365            }
17366        }
17367    }
17368}
17369