ActivityManagerService.java revision 7f2d5162fd19345945d54cc864b3cc82bea35a2e
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 : 20;
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        for (int i=0; i<N; i++) {
3542            TaskRecord tr = mRecentTasks.get(i);
3543            if (task != tr) {
3544                if (task.userId != tr.userId) {
3545                    continue;
3546                }
3547                final Intent trIntent = tr.intent;
3548                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3549                    (intent == null || !intent.filterEquals(trIntent))) {
3550                    continue;
3551                }
3552                if (document || trIntent != null && trIntent.isDocument()) {
3553                    // Document tasks do not match other tasks.
3554                    continue;
3555                }
3556            }
3557
3558            // Either task and tr are the same or, their affinities match or their intents match
3559            // and neither of them is a document.
3560            tr.disposeThumbnail();
3561            mRecentTasks.remove(i);
3562            i--;
3563            N--;
3564            if (task.intent == null) {
3565                // If the new recent task we are adding is not fully
3566                // specified, then replace it with the existing recent task.
3567                task = tr;
3568            }
3569        }
3570        if (N >= MAX_RECENT_TASKS) {
3571            mRecentTasks.remove(N-1).disposeThumbnail();
3572        }
3573        mRecentTasks.add(0, task);
3574    }
3575
3576    @Override
3577    public void reportActivityFullyDrawn(IBinder token) {
3578        synchronized (this) {
3579            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3580            if (r == null) {
3581                return;
3582            }
3583            r.reportFullyDrawnLocked();
3584        }
3585    }
3586
3587    @Override
3588    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3589        synchronized (this) {
3590            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3591            if (r == null) {
3592                return;
3593            }
3594            final long origId = Binder.clearCallingIdentity();
3595            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3596            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3597                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3598            if (config != null) {
3599                r.frozenBeforeDestroy = true;
3600                if (!updateConfigurationLocked(config, r, false, false)) {
3601                    mStackSupervisor.resumeTopActivitiesLocked();
3602                }
3603            }
3604            Binder.restoreCallingIdentity(origId);
3605        }
3606    }
3607
3608    @Override
3609    public int getRequestedOrientation(IBinder token) {
3610        synchronized (this) {
3611            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3612            if (r == null) {
3613                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3614            }
3615            return mWindowManager.getAppOrientation(r.appToken);
3616        }
3617    }
3618
3619    /**
3620     * This is the internal entry point for handling Activity.finish().
3621     *
3622     * @param token The Binder token referencing the Activity we want to finish.
3623     * @param resultCode Result code, if any, from this Activity.
3624     * @param resultData Result data (Intent), if any, from this Activity.
3625     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3626     *            the root Activity in the task.
3627     *
3628     * @return Returns true if the activity successfully finished, or false if it is still running.
3629     */
3630    @Override
3631    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3632            boolean finishTask) {
3633        // Refuse possible leaked file descriptors
3634        if (resultData != null && resultData.hasFileDescriptors() == true) {
3635            throw new IllegalArgumentException("File descriptors passed in Intent");
3636        }
3637
3638        synchronized(this) {
3639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3640            if (r == null) {
3641                return true;
3642            }
3643            // Keep track of the root activity of the task before we finish it
3644            TaskRecord tr = r.task;
3645            ActivityRecord rootR = tr.getRootActivity();
3646            if (mController != null) {
3647                // Find the first activity that is not finishing.
3648                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3649                if (next != null) {
3650                    // ask watcher if this is allowed
3651                    boolean resumeOK = true;
3652                    try {
3653                        resumeOK = mController.activityResuming(next.packageName);
3654                    } catch (RemoteException e) {
3655                        mController = null;
3656                        Watchdog.getInstance().setActivityController(null);
3657                    }
3658
3659                    if (!resumeOK) {
3660                        return false;
3661                    }
3662                }
3663            }
3664            final long origId = Binder.clearCallingIdentity();
3665            try {
3666                boolean res;
3667                if (finishTask && r == rootR) {
3668                    // If requested, remove the task that is associated to this activity only if it
3669                    // was the root activity in the task.  The result code and data is ignored because
3670                    // we don't support returning them across task boundaries.
3671                    res = removeTaskByIdLocked(tr.taskId, 0);
3672                } else {
3673                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3674                            resultData, "app-request", true);
3675                }
3676                return res;
3677            } finally {
3678                Binder.restoreCallingIdentity(origId);
3679            }
3680        }
3681    }
3682
3683    @Override
3684    public final void finishHeavyWeightApp() {
3685        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3686                != PackageManager.PERMISSION_GRANTED) {
3687            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3688                    + Binder.getCallingPid()
3689                    + ", uid=" + Binder.getCallingUid()
3690                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3691            Slog.w(TAG, msg);
3692            throw new SecurityException(msg);
3693        }
3694
3695        synchronized(this) {
3696            if (mHeavyWeightProcess == null) {
3697                return;
3698            }
3699
3700            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3701                    mHeavyWeightProcess.activities);
3702            for (int i=0; i<activities.size(); i++) {
3703                ActivityRecord r = activities.get(i);
3704                if (!r.finishing) {
3705                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3706                            null, "finish-heavy", true);
3707                }
3708            }
3709
3710            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3711                    mHeavyWeightProcess.userId, 0));
3712            mHeavyWeightProcess = null;
3713        }
3714    }
3715
3716    @Override
3717    public void crashApplication(int uid, int initialPid, String packageName,
3718            String message) {
3719        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3720                != PackageManager.PERMISSION_GRANTED) {
3721            String msg = "Permission Denial: crashApplication() from pid="
3722                    + Binder.getCallingPid()
3723                    + ", uid=" + Binder.getCallingUid()
3724                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3725            Slog.w(TAG, msg);
3726            throw new SecurityException(msg);
3727        }
3728
3729        synchronized(this) {
3730            ProcessRecord proc = null;
3731
3732            // Figure out which process to kill.  We don't trust that initialPid
3733            // still has any relation to current pids, so must scan through the
3734            // list.
3735            synchronized (mPidsSelfLocked) {
3736                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3737                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3738                    if (p.uid != uid) {
3739                        continue;
3740                    }
3741                    if (p.pid == initialPid) {
3742                        proc = p;
3743                        break;
3744                    }
3745                    if (p.pkgList.containsKey(packageName)) {
3746                        proc = p;
3747                    }
3748                }
3749            }
3750
3751            if (proc == null) {
3752                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3753                        + " initialPid=" + initialPid
3754                        + " packageName=" + packageName);
3755                return;
3756            }
3757
3758            if (proc.thread != null) {
3759                if (proc.pid == Process.myPid()) {
3760                    Log.w(TAG, "crashApplication: trying to crash self!");
3761                    return;
3762                }
3763                long ident = Binder.clearCallingIdentity();
3764                try {
3765                    proc.thread.scheduleCrash(message);
3766                } catch (RemoteException e) {
3767                }
3768                Binder.restoreCallingIdentity(ident);
3769            }
3770        }
3771    }
3772
3773    @Override
3774    public final void finishSubActivity(IBinder token, String resultWho,
3775            int requestCode) {
3776        synchronized(this) {
3777            final long origId = Binder.clearCallingIdentity();
3778            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3779            if (r != null) {
3780                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3781            }
3782            Binder.restoreCallingIdentity(origId);
3783        }
3784    }
3785
3786    @Override
3787    public boolean finishActivityAffinity(IBinder token) {
3788        synchronized(this) {
3789            final long origId = Binder.clearCallingIdentity();
3790            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3791            boolean res = false;
3792            if (r != null) {
3793                res = r.task.stack.finishActivityAffinityLocked(r);
3794            }
3795            Binder.restoreCallingIdentity(origId);
3796            return res;
3797        }
3798    }
3799
3800    @Override
3801    public boolean willActivityBeVisible(IBinder token) {
3802        synchronized(this) {
3803            ActivityStack stack = ActivityRecord.getStackLocked(token);
3804            if (stack != null) {
3805                return stack.willActivityBeVisibleLocked(token);
3806            }
3807            return false;
3808        }
3809    }
3810
3811    @Override
3812    public void overridePendingTransition(IBinder token, String packageName,
3813            int enterAnim, int exitAnim) {
3814        synchronized(this) {
3815            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3816            if (self == null) {
3817                return;
3818            }
3819
3820            final long origId = Binder.clearCallingIdentity();
3821
3822            if (self.state == ActivityState.RESUMED
3823                    || self.state == ActivityState.PAUSING) {
3824                mWindowManager.overridePendingAppTransition(packageName,
3825                        enterAnim, exitAnim, null);
3826            }
3827
3828            Binder.restoreCallingIdentity(origId);
3829        }
3830    }
3831
3832    /**
3833     * Main function for removing an existing process from the activity manager
3834     * as a result of that process going away.  Clears out all connections
3835     * to the process.
3836     */
3837    private final void handleAppDiedLocked(ProcessRecord app,
3838            boolean restarting, boolean allowRestart) {
3839        int pid = app.pid;
3840        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3841        if (!restarting) {
3842            removeLruProcessLocked(app);
3843            if (pid > 0) {
3844                ProcessList.remove(pid);
3845            }
3846        }
3847
3848        if (mProfileProc == app) {
3849            clearProfilerLocked();
3850        }
3851
3852        // Remove this application's activities from active lists.
3853        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3854
3855        app.activities.clear();
3856
3857        if (app.instrumentationClass != null) {
3858            Slog.w(TAG, "Crash of app " + app.processName
3859                  + " running instrumentation " + app.instrumentationClass);
3860            Bundle info = new Bundle();
3861            info.putString("shortMsg", "Process crashed.");
3862            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3863        }
3864
3865        if (!restarting) {
3866            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3867                // If there was nothing to resume, and we are not already
3868                // restarting this process, but there is a visible activity that
3869                // is hosted by the process...  then make sure all visible
3870                // activities are running, taking care of restarting this
3871                // process.
3872                if (hasVisibleActivities) {
3873                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3874                }
3875            }
3876        }
3877    }
3878
3879    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3880        IBinder threadBinder = thread.asBinder();
3881        // Find the application record.
3882        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3883            ProcessRecord rec = mLruProcesses.get(i);
3884            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3885                return i;
3886            }
3887        }
3888        return -1;
3889    }
3890
3891    final ProcessRecord getRecordForAppLocked(
3892            IApplicationThread thread) {
3893        if (thread == null) {
3894            return null;
3895        }
3896
3897        int appIndex = getLRURecordIndexForAppLocked(thread);
3898        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3899    }
3900
3901    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3902        // If there are no longer any background processes running,
3903        // and the app that died was not running instrumentation,
3904        // then tell everyone we are now low on memory.
3905        boolean haveBg = false;
3906        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3907            ProcessRecord rec = mLruProcesses.get(i);
3908            if (rec.thread != null
3909                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3910                haveBg = true;
3911                break;
3912            }
3913        }
3914
3915        if (!haveBg) {
3916            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3917            if (doReport) {
3918                long now = SystemClock.uptimeMillis();
3919                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3920                    doReport = false;
3921                } else {
3922                    mLastMemUsageReportTime = now;
3923                }
3924            }
3925            final ArrayList<ProcessMemInfo> memInfos
3926                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3927            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3928            long now = SystemClock.uptimeMillis();
3929            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3930                ProcessRecord rec = mLruProcesses.get(i);
3931                if (rec == dyingProc || rec.thread == null) {
3932                    continue;
3933                }
3934                if (doReport) {
3935                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3936                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3937                }
3938                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3939                    // The low memory report is overriding any current
3940                    // state for a GC request.  Make sure to do
3941                    // heavy/important/visible/foreground processes first.
3942                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3943                        rec.lastRequestedGc = 0;
3944                    } else {
3945                        rec.lastRequestedGc = rec.lastLowMemory;
3946                    }
3947                    rec.reportLowMemory = true;
3948                    rec.lastLowMemory = now;
3949                    mProcessesToGc.remove(rec);
3950                    addProcessToGcListLocked(rec);
3951                }
3952            }
3953            if (doReport) {
3954                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3955                mHandler.sendMessage(msg);
3956            }
3957            scheduleAppGcsLocked();
3958        }
3959    }
3960
3961    final void appDiedLocked(ProcessRecord app, int pid,
3962            IApplicationThread thread) {
3963
3964        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3965        synchronized (stats) {
3966            stats.noteProcessDiedLocked(app.info.uid, pid);
3967        }
3968
3969        // Clean up already done if the process has been re-started.
3970        if (app.pid == pid && app.thread != null &&
3971                app.thread.asBinder() == thread.asBinder()) {
3972            boolean doLowMem = app.instrumentationClass == null;
3973            boolean doOomAdj = doLowMem;
3974            if (!app.killedByAm) {
3975                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3976                        + ") has died.");
3977                mAllowLowerMemLevel = true;
3978            } else {
3979                // Note that we always want to do oom adj to update our state with the
3980                // new number of procs.
3981                mAllowLowerMemLevel = false;
3982                doLowMem = false;
3983            }
3984            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3985            if (DEBUG_CLEANUP) Slog.v(
3986                TAG, "Dying app: " + app + ", pid: " + pid
3987                + ", thread: " + thread.asBinder());
3988            handleAppDiedLocked(app, false, true);
3989
3990            if (doOomAdj) {
3991                updateOomAdjLocked();
3992            }
3993            if (doLowMem) {
3994                doLowMemReportIfNeededLocked(app);
3995            }
3996        } else if (app.pid != pid) {
3997            // A new process has already been started.
3998            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3999                    + ") has died and restarted (pid " + app.pid + ").");
4000            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4001        } else if (DEBUG_PROCESSES) {
4002            Slog.d(TAG, "Received spurious death notification for thread "
4003                    + thread.asBinder());
4004        }
4005    }
4006
4007    /**
4008     * If a stack trace dump file is configured, dump process stack traces.
4009     * @param clearTraces causes the dump file to be erased prior to the new
4010     *    traces being written, if true; when false, the new traces will be
4011     *    appended to any existing file content.
4012     * @param firstPids of dalvik VM processes to dump stack traces for first
4013     * @param lastPids of dalvik VM processes to dump stack traces for last
4014     * @param nativeProcs optional list of native process names to dump stack crawls
4015     * @return file containing stack traces, or null if no dump file is configured
4016     */
4017    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4018            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4019        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4020        if (tracesPath == null || tracesPath.length() == 0) {
4021            return null;
4022        }
4023
4024        File tracesFile = new File(tracesPath);
4025        try {
4026            File tracesDir = tracesFile.getParentFile();
4027            if (!tracesDir.exists()) {
4028                tracesFile.mkdirs();
4029                if (!SELinux.restorecon(tracesDir)) {
4030                    return null;
4031                }
4032            }
4033            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4034
4035            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4036            tracesFile.createNewFile();
4037            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4038        } catch (IOException e) {
4039            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4040            return null;
4041        }
4042
4043        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4044        return tracesFile;
4045    }
4046
4047    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4048            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4049        // Use a FileObserver to detect when traces finish writing.
4050        // The order of traces is considered important to maintain for legibility.
4051        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4052            @Override
4053            public synchronized void onEvent(int event, String path) { notify(); }
4054        };
4055
4056        try {
4057            observer.startWatching();
4058
4059            // First collect all of the stacks of the most important pids.
4060            if (firstPids != null) {
4061                try {
4062                    int num = firstPids.size();
4063                    for (int i = 0; i < num; i++) {
4064                        synchronized (observer) {
4065                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4066                            observer.wait(200);  // Wait for write-close, give up after 200msec
4067                        }
4068                    }
4069                } catch (InterruptedException e) {
4070                    Log.wtf(TAG, e);
4071                }
4072            }
4073
4074            // Next collect the stacks of the native pids
4075            if (nativeProcs != null) {
4076                int[] pids = Process.getPidsForCommands(nativeProcs);
4077                if (pids != null) {
4078                    for (int pid : pids) {
4079                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4080                    }
4081                }
4082            }
4083
4084            // Lastly, measure CPU usage.
4085            if (processCpuTracker != null) {
4086                processCpuTracker.init();
4087                System.gc();
4088                processCpuTracker.update();
4089                try {
4090                    synchronized (processCpuTracker) {
4091                        processCpuTracker.wait(500); // measure over 1/2 second.
4092                    }
4093                } catch (InterruptedException e) {
4094                }
4095                processCpuTracker.update();
4096
4097                // We'll take the stack crawls of just the top apps using CPU.
4098                final int N = processCpuTracker.countWorkingStats();
4099                int numProcs = 0;
4100                for (int i=0; i<N && numProcs<5; i++) {
4101                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4102                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4103                        numProcs++;
4104                        try {
4105                            synchronized (observer) {
4106                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4107                                observer.wait(200);  // Wait for write-close, give up after 200msec
4108                            }
4109                        } catch (InterruptedException e) {
4110                            Log.wtf(TAG, e);
4111                        }
4112
4113                    }
4114                }
4115            }
4116        } finally {
4117            observer.stopWatching();
4118        }
4119    }
4120
4121    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4122        if (true || IS_USER_BUILD) {
4123            return;
4124        }
4125        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4126        if (tracesPath == null || tracesPath.length() == 0) {
4127            return;
4128        }
4129
4130        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4131        StrictMode.allowThreadDiskWrites();
4132        try {
4133            final File tracesFile = new File(tracesPath);
4134            final File tracesDir = tracesFile.getParentFile();
4135            final File tracesTmp = new File(tracesDir, "__tmp__");
4136            try {
4137                if (!tracesDir.exists()) {
4138                    tracesFile.mkdirs();
4139                    if (!SELinux.restorecon(tracesDir.getPath())) {
4140                        return;
4141                    }
4142                }
4143                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4144
4145                if (tracesFile.exists()) {
4146                    tracesTmp.delete();
4147                    tracesFile.renameTo(tracesTmp);
4148                }
4149                StringBuilder sb = new StringBuilder();
4150                Time tobj = new Time();
4151                tobj.set(System.currentTimeMillis());
4152                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4153                sb.append(": ");
4154                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4155                sb.append(" since ");
4156                sb.append(msg);
4157                FileOutputStream fos = new FileOutputStream(tracesFile);
4158                fos.write(sb.toString().getBytes());
4159                if (app == null) {
4160                    fos.write("\n*** No application process!".getBytes());
4161                }
4162                fos.close();
4163                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4164            } catch (IOException e) {
4165                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4166                return;
4167            }
4168
4169            if (app != null) {
4170                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4171                firstPids.add(app.pid);
4172                dumpStackTraces(tracesPath, firstPids, null, null, null);
4173            }
4174
4175            File lastTracesFile = null;
4176            File curTracesFile = null;
4177            for (int i=9; i>=0; i--) {
4178                String name = String.format(Locale.US, "slow%02d.txt", i);
4179                curTracesFile = new File(tracesDir, name);
4180                if (curTracesFile.exists()) {
4181                    if (lastTracesFile != null) {
4182                        curTracesFile.renameTo(lastTracesFile);
4183                    } else {
4184                        curTracesFile.delete();
4185                    }
4186                }
4187                lastTracesFile = curTracesFile;
4188            }
4189            tracesFile.renameTo(curTracesFile);
4190            if (tracesTmp.exists()) {
4191                tracesTmp.renameTo(tracesFile);
4192            }
4193        } finally {
4194            StrictMode.setThreadPolicy(oldPolicy);
4195        }
4196    }
4197
4198    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4199            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4200        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4201        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4202
4203        if (mController != null) {
4204            try {
4205                // 0 == continue, -1 = kill process immediately
4206                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4207                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4208            } catch (RemoteException e) {
4209                mController = null;
4210                Watchdog.getInstance().setActivityController(null);
4211            }
4212        }
4213
4214        long anrTime = SystemClock.uptimeMillis();
4215        if (MONITOR_CPU_USAGE) {
4216            updateCpuStatsNow();
4217        }
4218
4219        synchronized (this) {
4220            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4221            if (mShuttingDown) {
4222                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4223                return;
4224            } else if (app.notResponding) {
4225                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4226                return;
4227            } else if (app.crashing) {
4228                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4229                return;
4230            }
4231
4232            // In case we come through here for the same app before completing
4233            // this one, mark as anring now so we will bail out.
4234            app.notResponding = true;
4235
4236            // Log the ANR to the event log.
4237            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4238                    app.processName, app.info.flags, annotation);
4239
4240            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4241            firstPids.add(app.pid);
4242
4243            int parentPid = app.pid;
4244            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4245            if (parentPid != app.pid) firstPids.add(parentPid);
4246
4247            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4248
4249            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4250                ProcessRecord r = mLruProcesses.get(i);
4251                if (r != null && r.thread != null) {
4252                    int pid = r.pid;
4253                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4254                        if (r.persistent) {
4255                            firstPids.add(pid);
4256                        } else {
4257                            lastPids.put(pid, Boolean.TRUE);
4258                        }
4259                    }
4260                }
4261            }
4262        }
4263
4264        // Log the ANR to the main log.
4265        StringBuilder info = new StringBuilder();
4266        info.setLength(0);
4267        info.append("ANR in ").append(app.processName);
4268        if (activity != null && activity.shortComponentName != null) {
4269            info.append(" (").append(activity.shortComponentName).append(")");
4270        }
4271        info.append("\n");
4272        info.append("PID: ").append(app.pid).append("\n");
4273        if (annotation != null) {
4274            info.append("Reason: ").append(annotation).append("\n");
4275        }
4276        if (parent != null && parent != activity) {
4277            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4278        }
4279
4280        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4281
4282        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4283                NATIVE_STACKS_OF_INTEREST);
4284
4285        String cpuInfo = null;
4286        if (MONITOR_CPU_USAGE) {
4287            updateCpuStatsNow();
4288            synchronized (mProcessCpuThread) {
4289                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4290            }
4291            info.append(processCpuTracker.printCurrentLoad());
4292            info.append(cpuInfo);
4293        }
4294
4295        info.append(processCpuTracker.printCurrentState(anrTime));
4296
4297        Slog.e(TAG, info.toString());
4298        if (tracesFile == null) {
4299            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4300            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4301        }
4302
4303        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4304                cpuInfo, tracesFile, null);
4305
4306        if (mController != null) {
4307            try {
4308                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4309                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4310                if (res != 0) {
4311                    if (res < 0 && app.pid != MY_PID) {
4312                        Process.killProcess(app.pid);
4313                    } else {
4314                        synchronized (this) {
4315                            mServices.scheduleServiceTimeoutLocked(app);
4316                        }
4317                    }
4318                    return;
4319                }
4320            } catch (RemoteException e) {
4321                mController = null;
4322                Watchdog.getInstance().setActivityController(null);
4323            }
4324        }
4325
4326        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4327        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4328                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4329
4330        synchronized (this) {
4331            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4332                killUnneededProcessLocked(app, "background ANR");
4333                return;
4334            }
4335
4336            // Set the app's notResponding state, and look up the errorReportReceiver
4337            makeAppNotRespondingLocked(app,
4338                    activity != null ? activity.shortComponentName : null,
4339                    annotation != null ? "ANR " + annotation : "ANR",
4340                    info.toString());
4341
4342            // Bring up the infamous App Not Responding dialog
4343            Message msg = Message.obtain();
4344            HashMap<String, Object> map = new HashMap<String, Object>();
4345            msg.what = SHOW_NOT_RESPONDING_MSG;
4346            msg.obj = map;
4347            msg.arg1 = aboveSystem ? 1 : 0;
4348            map.put("app", app);
4349            if (activity != null) {
4350                map.put("activity", activity);
4351            }
4352
4353            mHandler.sendMessage(msg);
4354        }
4355    }
4356
4357    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4358        if (!mLaunchWarningShown) {
4359            mLaunchWarningShown = true;
4360            mHandler.post(new Runnable() {
4361                @Override
4362                public void run() {
4363                    synchronized (ActivityManagerService.this) {
4364                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4365                        d.show();
4366                        mHandler.postDelayed(new Runnable() {
4367                            @Override
4368                            public void run() {
4369                                synchronized (ActivityManagerService.this) {
4370                                    d.dismiss();
4371                                    mLaunchWarningShown = false;
4372                                }
4373                            }
4374                        }, 4000);
4375                    }
4376                }
4377            });
4378        }
4379    }
4380
4381    @Override
4382    public boolean clearApplicationUserData(final String packageName,
4383            final IPackageDataObserver observer, int userId) {
4384        enforceNotIsolatedCaller("clearApplicationUserData");
4385        int uid = Binder.getCallingUid();
4386        int pid = Binder.getCallingPid();
4387        userId = handleIncomingUser(pid, uid,
4388                userId, false, true, "clearApplicationUserData", null);
4389        long callingId = Binder.clearCallingIdentity();
4390        try {
4391            IPackageManager pm = AppGlobals.getPackageManager();
4392            int pkgUid = -1;
4393            synchronized(this) {
4394                try {
4395                    pkgUid = pm.getPackageUid(packageName, userId);
4396                } catch (RemoteException e) {
4397                }
4398                if (pkgUid == -1) {
4399                    Slog.w(TAG, "Invalid packageName: " + packageName);
4400                    if (observer != null) {
4401                        try {
4402                            observer.onRemoveCompleted(packageName, false);
4403                        } catch (RemoteException e) {
4404                            Slog.i(TAG, "Observer no longer exists.");
4405                        }
4406                    }
4407                    return false;
4408                }
4409                if (uid == pkgUid || checkComponentPermission(
4410                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4411                        pid, uid, -1, true)
4412                        == PackageManager.PERMISSION_GRANTED) {
4413                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4414                } else {
4415                    throw new SecurityException("PID " + pid + " does not have permission "
4416                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4417                                    + " of package " + packageName);
4418                }
4419            }
4420
4421            try {
4422                // Clear application user data
4423                pm.clearApplicationUserData(packageName, observer, userId);
4424
4425                // Remove all permissions granted from/to this package
4426                removeUriPermissionsForPackageLocked(packageName, userId, true);
4427
4428                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4429                        Uri.fromParts("package", packageName, null));
4430                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4431                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4432                        null, null, 0, null, null, null, false, false, userId);
4433            } catch (RemoteException e) {
4434            }
4435        } finally {
4436            Binder.restoreCallingIdentity(callingId);
4437        }
4438        return true;
4439    }
4440
4441    @Override
4442    public void killBackgroundProcesses(final String packageName, int userId) {
4443        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4444                != PackageManager.PERMISSION_GRANTED &&
4445                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4446                        != PackageManager.PERMISSION_GRANTED) {
4447            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4448                    + Binder.getCallingPid()
4449                    + ", uid=" + Binder.getCallingUid()
4450                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4451            Slog.w(TAG, msg);
4452            throw new SecurityException(msg);
4453        }
4454
4455        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4456                userId, true, true, "killBackgroundProcesses", null);
4457        long callingId = Binder.clearCallingIdentity();
4458        try {
4459            IPackageManager pm = AppGlobals.getPackageManager();
4460            synchronized(this) {
4461                int appId = -1;
4462                try {
4463                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4464                } catch (RemoteException e) {
4465                }
4466                if (appId == -1) {
4467                    Slog.w(TAG, "Invalid packageName: " + packageName);
4468                    return;
4469                }
4470                killPackageProcessesLocked(packageName, appId, userId,
4471                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4472            }
4473        } finally {
4474            Binder.restoreCallingIdentity(callingId);
4475        }
4476    }
4477
4478    @Override
4479    public void killAllBackgroundProcesses() {
4480        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4481                != PackageManager.PERMISSION_GRANTED) {
4482            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4483                    + Binder.getCallingPid()
4484                    + ", uid=" + Binder.getCallingUid()
4485                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4486            Slog.w(TAG, msg);
4487            throw new SecurityException(msg);
4488        }
4489
4490        long callingId = Binder.clearCallingIdentity();
4491        try {
4492            synchronized(this) {
4493                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4494                final int NP = mProcessNames.getMap().size();
4495                for (int ip=0; ip<NP; ip++) {
4496                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4497                    final int NA = apps.size();
4498                    for (int ia=0; ia<NA; ia++) {
4499                        ProcessRecord app = apps.valueAt(ia);
4500                        if (app.persistent) {
4501                            // we don't kill persistent processes
4502                            continue;
4503                        }
4504                        if (app.removed) {
4505                            procs.add(app);
4506                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4507                            app.removed = true;
4508                            procs.add(app);
4509                        }
4510                    }
4511                }
4512
4513                int N = procs.size();
4514                for (int i=0; i<N; i++) {
4515                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4516                }
4517                mAllowLowerMemLevel = true;
4518                updateOomAdjLocked();
4519                doLowMemReportIfNeededLocked(null);
4520            }
4521        } finally {
4522            Binder.restoreCallingIdentity(callingId);
4523        }
4524    }
4525
4526    @Override
4527    public void forceStopPackage(final String packageName, int userId) {
4528        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4529                != PackageManager.PERMISSION_GRANTED) {
4530            String msg = "Permission Denial: forceStopPackage() from pid="
4531                    + Binder.getCallingPid()
4532                    + ", uid=" + Binder.getCallingUid()
4533                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4534            Slog.w(TAG, msg);
4535            throw new SecurityException(msg);
4536        }
4537        final int callingPid = Binder.getCallingPid();
4538        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4539                userId, true, true, "forceStopPackage", null);
4540        long callingId = Binder.clearCallingIdentity();
4541        try {
4542            IPackageManager pm = AppGlobals.getPackageManager();
4543            synchronized(this) {
4544                int[] users = userId == UserHandle.USER_ALL
4545                        ? getUsersLocked() : new int[] { userId };
4546                for (int user : users) {
4547                    int pkgUid = -1;
4548                    try {
4549                        pkgUid = pm.getPackageUid(packageName, user);
4550                    } catch (RemoteException e) {
4551                    }
4552                    if (pkgUid == -1) {
4553                        Slog.w(TAG, "Invalid packageName: " + packageName);
4554                        continue;
4555                    }
4556                    try {
4557                        pm.setPackageStoppedState(packageName, true, user);
4558                    } catch (RemoteException e) {
4559                    } catch (IllegalArgumentException e) {
4560                        Slog.w(TAG, "Failed trying to unstop package "
4561                                + packageName + ": " + e);
4562                    }
4563                    if (isUserRunningLocked(user, false)) {
4564                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4565                    }
4566                }
4567            }
4568        } finally {
4569            Binder.restoreCallingIdentity(callingId);
4570        }
4571    }
4572
4573    /*
4574     * The pkg name and app id have to be specified.
4575     */
4576    @Override
4577    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4578        if (pkg == null) {
4579            return;
4580        }
4581        // Make sure the uid is valid.
4582        if (appid < 0) {
4583            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4584            return;
4585        }
4586        int callerUid = Binder.getCallingUid();
4587        // Only the system server can kill an application
4588        if (callerUid == Process.SYSTEM_UID) {
4589            // Post an aysnc message to kill the application
4590            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4591            msg.arg1 = appid;
4592            msg.arg2 = 0;
4593            Bundle bundle = new Bundle();
4594            bundle.putString("pkg", pkg);
4595            bundle.putString("reason", reason);
4596            msg.obj = bundle;
4597            mHandler.sendMessage(msg);
4598        } else {
4599            throw new SecurityException(callerUid + " cannot kill pkg: " +
4600                    pkg);
4601        }
4602    }
4603
4604    @Override
4605    public void closeSystemDialogs(String reason) {
4606        enforceNotIsolatedCaller("closeSystemDialogs");
4607
4608        final int pid = Binder.getCallingPid();
4609        final int uid = Binder.getCallingUid();
4610        final long origId = Binder.clearCallingIdentity();
4611        try {
4612            synchronized (this) {
4613                // Only allow this from foreground processes, so that background
4614                // applications can't abuse it to prevent system UI from being shown.
4615                if (uid >= Process.FIRST_APPLICATION_UID) {
4616                    ProcessRecord proc;
4617                    synchronized (mPidsSelfLocked) {
4618                        proc = mPidsSelfLocked.get(pid);
4619                    }
4620                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4621                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4622                                + " from background process " + proc);
4623                        return;
4624                    }
4625                }
4626                closeSystemDialogsLocked(reason);
4627            }
4628        } finally {
4629            Binder.restoreCallingIdentity(origId);
4630        }
4631    }
4632
4633    void closeSystemDialogsLocked(String reason) {
4634        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4635        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4636                | Intent.FLAG_RECEIVER_FOREGROUND);
4637        if (reason != null) {
4638            intent.putExtra("reason", reason);
4639        }
4640        mWindowManager.closeSystemDialogs(reason);
4641
4642        mStackSupervisor.closeSystemDialogsLocked();
4643
4644        broadcastIntentLocked(null, null, intent, null,
4645                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4646                Process.SYSTEM_UID, UserHandle.USER_ALL);
4647    }
4648
4649    @Override
4650    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4651        enforceNotIsolatedCaller("getProcessMemoryInfo");
4652        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4653        for (int i=pids.length-1; i>=0; i--) {
4654            ProcessRecord proc;
4655            int oomAdj;
4656            synchronized (this) {
4657                synchronized (mPidsSelfLocked) {
4658                    proc = mPidsSelfLocked.get(pids[i]);
4659                    oomAdj = proc != null ? proc.setAdj : 0;
4660                }
4661            }
4662            infos[i] = new Debug.MemoryInfo();
4663            Debug.getMemoryInfo(pids[i], infos[i]);
4664            if (proc != null) {
4665                synchronized (this) {
4666                    if (proc.thread != null && proc.setAdj == oomAdj) {
4667                        // Record this for posterity if the process has been stable.
4668                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4669                                infos[i].getTotalUss(), false, proc.pkgList);
4670                    }
4671                }
4672            }
4673        }
4674        return infos;
4675    }
4676
4677    @Override
4678    public long[] getProcessPss(int[] pids) {
4679        enforceNotIsolatedCaller("getProcessPss");
4680        long[] pss = new long[pids.length];
4681        for (int i=pids.length-1; i>=0; i--) {
4682            ProcessRecord proc;
4683            int oomAdj;
4684            synchronized (this) {
4685                synchronized (mPidsSelfLocked) {
4686                    proc = mPidsSelfLocked.get(pids[i]);
4687                    oomAdj = proc != null ? proc.setAdj : 0;
4688                }
4689            }
4690            long[] tmpUss = new long[1];
4691            pss[i] = Debug.getPss(pids[i], tmpUss);
4692            if (proc != null) {
4693                synchronized (this) {
4694                    if (proc.thread != null && proc.setAdj == oomAdj) {
4695                        // Record this for posterity if the process has been stable.
4696                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4697                    }
4698                }
4699            }
4700        }
4701        return pss;
4702    }
4703
4704    @Override
4705    public void killApplicationProcess(String processName, int uid) {
4706        if (processName == null) {
4707            return;
4708        }
4709
4710        int callerUid = Binder.getCallingUid();
4711        // Only the system server can kill an application
4712        if (callerUid == Process.SYSTEM_UID) {
4713            synchronized (this) {
4714                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4715                if (app != null && app.thread != null) {
4716                    try {
4717                        app.thread.scheduleSuicide();
4718                    } catch (RemoteException e) {
4719                        // If the other end already died, then our work here is done.
4720                    }
4721                } else {
4722                    Slog.w(TAG, "Process/uid not found attempting kill of "
4723                            + processName + " / " + uid);
4724                }
4725            }
4726        } else {
4727            throw new SecurityException(callerUid + " cannot kill app process: " +
4728                    processName);
4729        }
4730    }
4731
4732    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4733        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4734                false, true, false, false, UserHandle.getUserId(uid), reason);
4735        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4736                Uri.fromParts("package", packageName, null));
4737        if (!mProcessesReady) {
4738            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4739                    | Intent.FLAG_RECEIVER_FOREGROUND);
4740        }
4741        intent.putExtra(Intent.EXTRA_UID, uid);
4742        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4743        broadcastIntentLocked(null, null, intent,
4744                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4745                false, false,
4746                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4747    }
4748
4749    private void forceStopUserLocked(int userId, String reason) {
4750        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4751        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4752        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4753                | Intent.FLAG_RECEIVER_FOREGROUND);
4754        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4755        broadcastIntentLocked(null, null, intent,
4756                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4757                false, false,
4758                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4759    }
4760
4761    private final boolean killPackageProcessesLocked(String packageName, int appId,
4762            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4763            boolean doit, boolean evenPersistent, String reason) {
4764        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4765
4766        // Remove all processes this package may have touched: all with the
4767        // same UID (except for the system or root user), and all whose name
4768        // matches the package name.
4769        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4770        final int NP = mProcessNames.getMap().size();
4771        for (int ip=0; ip<NP; ip++) {
4772            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4773            final int NA = apps.size();
4774            for (int ia=0; ia<NA; ia++) {
4775                ProcessRecord app = apps.valueAt(ia);
4776                if (app.persistent && !evenPersistent) {
4777                    // we don't kill persistent processes
4778                    continue;
4779                }
4780                if (app.removed) {
4781                    if (doit) {
4782                        procs.add(app);
4783                    }
4784                    continue;
4785                }
4786
4787                // Skip process if it doesn't meet our oom adj requirement.
4788                if (app.setAdj < minOomAdj) {
4789                    continue;
4790                }
4791
4792                // If no package is specified, we call all processes under the
4793                // give user id.
4794                if (packageName == null) {
4795                    if (app.userId != userId) {
4796                        continue;
4797                    }
4798                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4799                        continue;
4800                    }
4801                // Package has been specified, we want to hit all processes
4802                // that match it.  We need to qualify this by the processes
4803                // that are running under the specified app and user ID.
4804                } else {
4805                    if (UserHandle.getAppId(app.uid) != appId) {
4806                        continue;
4807                    }
4808                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4809                        continue;
4810                    }
4811                    if (!app.pkgList.containsKey(packageName)) {
4812                        continue;
4813                    }
4814                }
4815
4816                // Process has passed all conditions, kill it!
4817                if (!doit) {
4818                    return true;
4819                }
4820                app.removed = true;
4821                procs.add(app);
4822            }
4823        }
4824
4825        int N = procs.size();
4826        for (int i=0; i<N; i++) {
4827            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4828        }
4829        updateOomAdjLocked();
4830        return N > 0;
4831    }
4832
4833    private final boolean forceStopPackageLocked(String name, int appId,
4834            boolean callerWillRestart, boolean purgeCache, boolean doit,
4835            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4836        int i;
4837        int N;
4838
4839        if (userId == UserHandle.USER_ALL && name == null) {
4840            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4841        }
4842
4843        if (appId < 0 && name != null) {
4844            try {
4845                appId = UserHandle.getAppId(
4846                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4847            } catch (RemoteException e) {
4848            }
4849        }
4850
4851        if (doit) {
4852            if (name != null) {
4853                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4854                        + " user=" + userId + ": " + reason);
4855            } else {
4856                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4857            }
4858
4859            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4860            for (int ip=pmap.size()-1; ip>=0; ip--) {
4861                SparseArray<Long> ba = pmap.valueAt(ip);
4862                for (i=ba.size()-1; i>=0; i--) {
4863                    boolean remove = false;
4864                    final int entUid = ba.keyAt(i);
4865                    if (name != null) {
4866                        if (userId == UserHandle.USER_ALL) {
4867                            if (UserHandle.getAppId(entUid) == appId) {
4868                                remove = true;
4869                            }
4870                        } else {
4871                            if (entUid == UserHandle.getUid(userId, appId)) {
4872                                remove = true;
4873                            }
4874                        }
4875                    } else if (UserHandle.getUserId(entUid) == userId) {
4876                        remove = true;
4877                    }
4878                    if (remove) {
4879                        ba.removeAt(i);
4880                    }
4881                }
4882                if (ba.size() == 0) {
4883                    pmap.removeAt(ip);
4884                }
4885            }
4886        }
4887
4888        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4889                -100, callerWillRestart, true, doit, evenPersistent,
4890                name == null ? ("stop user " + userId) : ("stop " + name));
4891
4892        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4893            if (!doit) {
4894                return true;
4895            }
4896            didSomething = true;
4897        }
4898
4899        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4900            if (!doit) {
4901                return true;
4902            }
4903            didSomething = true;
4904        }
4905
4906        if (name == null) {
4907            // Remove all sticky broadcasts from this user.
4908            mStickyBroadcasts.remove(userId);
4909        }
4910
4911        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4912        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4913                userId, providers)) {
4914            if (!doit) {
4915                return true;
4916            }
4917            didSomething = true;
4918        }
4919        N = providers.size();
4920        for (i=0; i<N; i++) {
4921            removeDyingProviderLocked(null, providers.get(i), true);
4922        }
4923
4924        // Remove transient permissions granted from/to this package/user
4925        removeUriPermissionsForPackageLocked(name, userId, false);
4926
4927        if (name == null || uninstalling) {
4928            // Remove pending intents.  For now we only do this when force
4929            // stopping users, because we have some problems when doing this
4930            // for packages -- app widgets are not currently cleaned up for
4931            // such packages, so they can be left with bad pending intents.
4932            if (mIntentSenderRecords.size() > 0) {
4933                Iterator<WeakReference<PendingIntentRecord>> it
4934                        = mIntentSenderRecords.values().iterator();
4935                while (it.hasNext()) {
4936                    WeakReference<PendingIntentRecord> wpir = it.next();
4937                    if (wpir == null) {
4938                        it.remove();
4939                        continue;
4940                    }
4941                    PendingIntentRecord pir = wpir.get();
4942                    if (pir == null) {
4943                        it.remove();
4944                        continue;
4945                    }
4946                    if (name == null) {
4947                        // Stopping user, remove all objects for the user.
4948                        if (pir.key.userId != userId) {
4949                            // Not the same user, skip it.
4950                            continue;
4951                        }
4952                    } else {
4953                        if (UserHandle.getAppId(pir.uid) != appId) {
4954                            // Different app id, skip it.
4955                            continue;
4956                        }
4957                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4958                            // Different user, skip it.
4959                            continue;
4960                        }
4961                        if (!pir.key.packageName.equals(name)) {
4962                            // Different package, skip it.
4963                            continue;
4964                        }
4965                    }
4966                    if (!doit) {
4967                        return true;
4968                    }
4969                    didSomething = true;
4970                    it.remove();
4971                    pir.canceled = true;
4972                    if (pir.key.activity != null) {
4973                        pir.key.activity.pendingResults.remove(pir.ref);
4974                    }
4975                }
4976            }
4977        }
4978
4979        if (doit) {
4980            if (purgeCache && name != null) {
4981                AttributeCache ac = AttributeCache.instance();
4982                if (ac != null) {
4983                    ac.removePackage(name);
4984                }
4985            }
4986            if (mBooted) {
4987                mStackSupervisor.resumeTopActivitiesLocked();
4988                mStackSupervisor.scheduleIdleLocked();
4989            }
4990        }
4991
4992        return didSomething;
4993    }
4994
4995    private final boolean removeProcessLocked(ProcessRecord app,
4996            boolean callerWillRestart, boolean allowRestart, String reason) {
4997        final String name = app.processName;
4998        final int uid = app.uid;
4999        if (DEBUG_PROCESSES) Slog.d(
5000            TAG, "Force removing proc " + app.toShortString() + " (" + name
5001            + "/" + uid + ")");
5002
5003        mProcessNames.remove(name, uid);
5004        mIsolatedProcesses.remove(app.uid);
5005        if (mHeavyWeightProcess == app) {
5006            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5007                    mHeavyWeightProcess.userId, 0));
5008            mHeavyWeightProcess = null;
5009        }
5010        boolean needRestart = false;
5011        if (app.pid > 0 && app.pid != MY_PID) {
5012            int pid = app.pid;
5013            synchronized (mPidsSelfLocked) {
5014                mPidsSelfLocked.remove(pid);
5015                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5016            }
5017            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5018                    app.processName, app.info.uid);
5019            if (app.isolated) {
5020                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5021            }
5022            killUnneededProcessLocked(app, reason);
5023            handleAppDiedLocked(app, true, allowRestart);
5024            removeLruProcessLocked(app);
5025
5026            if (app.persistent && !app.isolated) {
5027                if (!callerWillRestart) {
5028                    addAppLocked(app.info, false, null /* ABI override */);
5029                } else {
5030                    needRestart = true;
5031                }
5032            }
5033        } else {
5034            mRemovedProcesses.add(app);
5035        }
5036
5037        return needRestart;
5038    }
5039
5040    private final void processStartTimedOutLocked(ProcessRecord app) {
5041        final int pid = app.pid;
5042        boolean gone = false;
5043        synchronized (mPidsSelfLocked) {
5044            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5045            if (knownApp != null && knownApp.thread == null) {
5046                mPidsSelfLocked.remove(pid);
5047                gone = true;
5048            }
5049        }
5050
5051        if (gone) {
5052            Slog.w(TAG, "Process " + app + " failed to attach");
5053            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5054                    pid, app.uid, app.processName);
5055            mProcessNames.remove(app.processName, app.uid);
5056            mIsolatedProcesses.remove(app.uid);
5057            if (mHeavyWeightProcess == app) {
5058                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5059                        mHeavyWeightProcess.userId, 0));
5060                mHeavyWeightProcess = null;
5061            }
5062            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5063                    app.processName, app.info.uid);
5064            if (app.isolated) {
5065                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5066            }
5067            // Take care of any launching providers waiting for this process.
5068            checkAppInLaunchingProvidersLocked(app, true);
5069            // Take care of any services that are waiting for the process.
5070            mServices.processStartTimedOutLocked(app);
5071            killUnneededProcessLocked(app, "start timeout");
5072            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5073                Slog.w(TAG, "Unattached app died before backup, skipping");
5074                try {
5075                    IBackupManager bm = IBackupManager.Stub.asInterface(
5076                            ServiceManager.getService(Context.BACKUP_SERVICE));
5077                    bm.agentDisconnected(app.info.packageName);
5078                } catch (RemoteException e) {
5079                    // Can't happen; the backup manager is local
5080                }
5081            }
5082            if (isPendingBroadcastProcessLocked(pid)) {
5083                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5084                skipPendingBroadcastLocked(pid);
5085            }
5086        } else {
5087            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5088        }
5089    }
5090
5091    private final boolean attachApplicationLocked(IApplicationThread thread,
5092            int pid) {
5093
5094        // Find the application record that is being attached...  either via
5095        // the pid if we are running in multiple processes, or just pull the
5096        // next app record if we are emulating process with anonymous threads.
5097        ProcessRecord app;
5098        if (pid != MY_PID && pid >= 0) {
5099            synchronized (mPidsSelfLocked) {
5100                app = mPidsSelfLocked.get(pid);
5101            }
5102        } else {
5103            app = null;
5104        }
5105
5106        if (app == null) {
5107            Slog.w(TAG, "No pending application record for pid " + pid
5108                    + " (IApplicationThread " + thread + "); dropping process");
5109            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5110            if (pid > 0 && pid != MY_PID) {
5111                Process.killProcessQuiet(pid);
5112            } else {
5113                try {
5114                    thread.scheduleExit();
5115                } catch (Exception e) {
5116                    // Ignore exceptions.
5117                }
5118            }
5119            return false;
5120        }
5121
5122        // If this application record is still attached to a previous
5123        // process, clean it up now.
5124        if (app.thread != null) {
5125            handleAppDiedLocked(app, true, true);
5126        }
5127
5128        // Tell the process all about itself.
5129
5130        if (localLOGV) Slog.v(
5131                TAG, "Binding process pid " + pid + " to record " + app);
5132
5133        final String processName = app.processName;
5134        try {
5135            AppDeathRecipient adr = new AppDeathRecipient(
5136                    app, pid, thread);
5137            thread.asBinder().linkToDeath(adr, 0);
5138            app.deathRecipient = adr;
5139        } catch (RemoteException e) {
5140            app.resetPackageList(mProcessStats);
5141            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5142            return false;
5143        }
5144
5145        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5146
5147        app.makeActive(thread, mProcessStats);
5148        app.curAdj = app.setAdj = -100;
5149        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5150        app.forcingToForeground = null;
5151        updateProcessForegroundLocked(app, false, false);
5152        app.hasShownUi = false;
5153        app.debugging = false;
5154        app.cached = false;
5155
5156        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5157
5158        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5159        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5160
5161        if (!normalMode) {
5162            Slog.i(TAG, "Launching preboot mode app: " + app);
5163        }
5164
5165        if (localLOGV) Slog.v(
5166            TAG, "New app record " + app
5167            + " thread=" + thread.asBinder() + " pid=" + pid);
5168        try {
5169            int testMode = IApplicationThread.DEBUG_OFF;
5170            if (mDebugApp != null && mDebugApp.equals(processName)) {
5171                testMode = mWaitForDebugger
5172                    ? IApplicationThread.DEBUG_WAIT
5173                    : IApplicationThread.DEBUG_ON;
5174                app.debugging = true;
5175                if (mDebugTransient) {
5176                    mDebugApp = mOrigDebugApp;
5177                    mWaitForDebugger = mOrigWaitForDebugger;
5178                }
5179            }
5180            String profileFile = app.instrumentationProfileFile;
5181            ParcelFileDescriptor profileFd = null;
5182            boolean profileAutoStop = false;
5183            if (mProfileApp != null && mProfileApp.equals(processName)) {
5184                mProfileProc = app;
5185                profileFile = mProfileFile;
5186                profileFd = mProfileFd;
5187                profileAutoStop = mAutoStopProfiler;
5188            }
5189            boolean enableOpenGlTrace = false;
5190            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5191                enableOpenGlTrace = true;
5192                mOpenGlTraceApp = null;
5193            }
5194
5195            // If the app is being launched for restore or full backup, set it up specially
5196            boolean isRestrictedBackupMode = false;
5197            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5198                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5199                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5200                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5201            }
5202
5203            ensurePackageDexOpt(app.instrumentationInfo != null
5204                    ? app.instrumentationInfo.packageName
5205                    : app.info.packageName);
5206            if (app.instrumentationClass != null) {
5207                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5208            }
5209            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5210                    + processName + " with config " + mConfiguration);
5211            ApplicationInfo appInfo = app.instrumentationInfo != null
5212                    ? app.instrumentationInfo : app.info;
5213            app.compat = compatibilityInfoForPackageLocked(appInfo);
5214            if (profileFd != null) {
5215                profileFd = profileFd.dup();
5216            }
5217            thread.bindApplication(processName, appInfo, providers,
5218                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5219                    app.instrumentationArguments, app.instrumentationWatcher,
5220                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5221                    isRestrictedBackupMode || !normalMode, app.persistent,
5222                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5223                    mCoreSettingsObserver.getCoreSettingsLocked());
5224            updateLruProcessLocked(app, false, null);
5225            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5226        } catch (Exception e) {
5227            // todo: Yikes!  What should we do?  For now we will try to
5228            // start another process, but that could easily get us in
5229            // an infinite loop of restarting processes...
5230            Slog.w(TAG, "Exception thrown during bind!", e);
5231
5232            app.resetPackageList(mProcessStats);
5233            app.unlinkDeathRecipient();
5234            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5235            return false;
5236        }
5237
5238        // Remove this record from the list of starting applications.
5239        mPersistentStartingProcesses.remove(app);
5240        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5241                "Attach application locked removing on hold: " + app);
5242        mProcessesOnHold.remove(app);
5243
5244        boolean badApp = false;
5245        boolean didSomething = false;
5246
5247        // See if the top visible activity is waiting to run in this process...
5248        if (normalMode) {
5249            try {
5250                if (mStackSupervisor.attachApplicationLocked(app)) {
5251                    didSomething = true;
5252                }
5253            } catch (Exception e) {
5254                badApp = true;
5255            }
5256        }
5257
5258        // Find any services that should be running in this process...
5259        if (!badApp) {
5260            try {
5261                didSomething |= mServices.attachApplicationLocked(app, processName);
5262            } catch (Exception e) {
5263                badApp = true;
5264            }
5265        }
5266
5267        // Check if a next-broadcast receiver is in this process...
5268        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5269            try {
5270                didSomething |= sendPendingBroadcastsLocked(app);
5271            } catch (Exception e) {
5272                // If the app died trying to launch the receiver we declare it 'bad'
5273                badApp = true;
5274            }
5275        }
5276
5277        // Check whether the next backup agent is in this process...
5278        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5279            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5280            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5281            try {
5282                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5283                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5284                        mBackupTarget.backupMode);
5285            } catch (Exception e) {
5286                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5287                e.printStackTrace();
5288            }
5289        }
5290
5291        if (badApp) {
5292            // todo: Also need to kill application to deal with all
5293            // kinds of exceptions.
5294            handleAppDiedLocked(app, false, true);
5295            return false;
5296        }
5297
5298        if (!didSomething) {
5299            updateOomAdjLocked();
5300        }
5301
5302        return true;
5303    }
5304
5305    @Override
5306    public final void attachApplication(IApplicationThread thread) {
5307        synchronized (this) {
5308            int callingPid = Binder.getCallingPid();
5309            final long origId = Binder.clearCallingIdentity();
5310            attachApplicationLocked(thread, callingPid);
5311            Binder.restoreCallingIdentity(origId);
5312        }
5313    }
5314
5315    @Override
5316    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5317        final long origId = Binder.clearCallingIdentity();
5318        synchronized (this) {
5319            ActivityStack stack = ActivityRecord.getStackLocked(token);
5320            if (stack != null) {
5321                ActivityRecord r =
5322                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5323                if (stopProfiling) {
5324                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5325                        try {
5326                            mProfileFd.close();
5327                        } catch (IOException e) {
5328                        }
5329                        clearProfilerLocked();
5330                    }
5331                }
5332            }
5333        }
5334        Binder.restoreCallingIdentity(origId);
5335    }
5336
5337    void enableScreenAfterBoot() {
5338        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5339                SystemClock.uptimeMillis());
5340        mWindowManager.enableScreenAfterBoot();
5341
5342        synchronized (this) {
5343            updateEventDispatchingLocked();
5344        }
5345    }
5346
5347    @Override
5348    public void showBootMessage(final CharSequence msg, final boolean always) {
5349        enforceNotIsolatedCaller("showBootMessage");
5350        mWindowManager.showBootMessage(msg, always);
5351    }
5352
5353    @Override
5354    public void dismissKeyguardOnNextActivity() {
5355        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5356        final long token = Binder.clearCallingIdentity();
5357        try {
5358            synchronized (this) {
5359                if (DEBUG_LOCKSCREEN) logLockScreen("");
5360                if (mLockScreenShown) {
5361                    mLockScreenShown = false;
5362                    comeOutOfSleepIfNeededLocked();
5363                }
5364                mStackSupervisor.setDismissKeyguard(true);
5365            }
5366        } finally {
5367            Binder.restoreCallingIdentity(token);
5368        }
5369    }
5370
5371    final void finishBooting() {
5372        // Register receivers to handle package update events
5373        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5374
5375        synchronized (this) {
5376            // Ensure that any processes we had put on hold are now started
5377            // up.
5378            final int NP = mProcessesOnHold.size();
5379            if (NP > 0) {
5380                ArrayList<ProcessRecord> procs =
5381                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5382                for (int ip=0; ip<NP; ip++) {
5383                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5384                            + procs.get(ip));
5385                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5386                }
5387            }
5388
5389            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5390                // Start looking for apps that are abusing wake locks.
5391                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5392                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5393                // Tell anyone interested that we are done booting!
5394                SystemProperties.set("sys.boot_completed", "1");
5395                SystemProperties.set("dev.bootcomplete", "1");
5396                for (int i=0; i<mStartedUsers.size(); i++) {
5397                    UserStartedState uss = mStartedUsers.valueAt(i);
5398                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5399                        uss.mState = UserStartedState.STATE_RUNNING;
5400                        final int userId = mStartedUsers.keyAt(i);
5401                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5402                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5403                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5404                        broadcastIntentLocked(null, null, intent, null,
5405                                new IIntentReceiver.Stub() {
5406                                    @Override
5407                                    public void performReceive(Intent intent, int resultCode,
5408                                            String data, Bundle extras, boolean ordered,
5409                                            boolean sticky, int sendingUser) {
5410                                        synchronized (ActivityManagerService.this) {
5411                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5412                                                    true, false);
5413                                        }
5414                                    }
5415                                },
5416                                0, null, null,
5417                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5418                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5419                                userId);
5420                    }
5421                }
5422                scheduleStartProfilesLocked();
5423            }
5424        }
5425    }
5426
5427    final void ensureBootCompleted() {
5428        boolean booting;
5429        boolean enableScreen;
5430        synchronized (this) {
5431            booting = mBooting;
5432            mBooting = false;
5433            enableScreen = !mBooted;
5434            mBooted = true;
5435        }
5436
5437        if (booting) {
5438            finishBooting();
5439        }
5440
5441        if (enableScreen) {
5442            enableScreenAfterBoot();
5443        }
5444    }
5445
5446    @Override
5447    public final void activityResumed(IBinder token) {
5448        final long origId = Binder.clearCallingIdentity();
5449        synchronized(this) {
5450            ActivityStack stack = ActivityRecord.getStackLocked(token);
5451            if (stack != null) {
5452                ActivityRecord.activityResumedLocked(token);
5453            }
5454        }
5455        Binder.restoreCallingIdentity(origId);
5456    }
5457
5458    @Override
5459    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5460        final long origId = Binder.clearCallingIdentity();
5461        synchronized(this) {
5462            ActivityStack stack = ActivityRecord.getStackLocked(token);
5463            if (stack != null) {
5464                stack.activityPausedLocked(token, false, persistentState);
5465            }
5466        }
5467        Binder.restoreCallingIdentity(origId);
5468    }
5469
5470    @Override
5471    public final void activityStopped(IBinder token, Bundle icicle,
5472            PersistableBundle persistentState, CharSequence description) {
5473        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5474
5475        // Refuse possible leaked file descriptors
5476        if (icicle != null && icicle.hasFileDescriptors()) {
5477            throw new IllegalArgumentException("File descriptors passed in Bundle");
5478        }
5479
5480        final long origId = Binder.clearCallingIdentity();
5481
5482        synchronized (this) {
5483            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5484            if (r != null) {
5485                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5486            }
5487        }
5488
5489        trimApplications();
5490
5491        Binder.restoreCallingIdentity(origId);
5492    }
5493
5494    @Override
5495    public final void activityDestroyed(IBinder token) {
5496        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5497        synchronized (this) {
5498            ActivityStack stack = ActivityRecord.getStackLocked(token);
5499            if (stack != null) {
5500                stack.activityDestroyedLocked(token);
5501            }
5502        }
5503    }
5504
5505    @Override
5506    public String getCallingPackage(IBinder token) {
5507        synchronized (this) {
5508            ActivityRecord r = getCallingRecordLocked(token);
5509            return r != null ? r.info.packageName : null;
5510        }
5511    }
5512
5513    @Override
5514    public ComponentName getCallingActivity(IBinder token) {
5515        synchronized (this) {
5516            ActivityRecord r = getCallingRecordLocked(token);
5517            return r != null ? r.intent.getComponent() : null;
5518        }
5519    }
5520
5521    private ActivityRecord getCallingRecordLocked(IBinder token) {
5522        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5523        if (r == null) {
5524            return null;
5525        }
5526        return r.resultTo;
5527    }
5528
5529    @Override
5530    public ComponentName getActivityClassForToken(IBinder token) {
5531        synchronized(this) {
5532            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5533            if (r == null) {
5534                return null;
5535            }
5536            return r.intent.getComponent();
5537        }
5538    }
5539
5540    @Override
5541    public String getPackageForToken(IBinder token) {
5542        synchronized(this) {
5543            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5544            if (r == null) {
5545                return null;
5546            }
5547            return r.packageName;
5548        }
5549    }
5550
5551    @Override
5552    public IIntentSender getIntentSender(int type,
5553            String packageName, IBinder token, String resultWho,
5554            int requestCode, Intent[] intents, String[] resolvedTypes,
5555            int flags, Bundle options, int userId) {
5556        enforceNotIsolatedCaller("getIntentSender");
5557        // Refuse possible leaked file descriptors
5558        if (intents != null) {
5559            if (intents.length < 1) {
5560                throw new IllegalArgumentException("Intents array length must be >= 1");
5561            }
5562            for (int i=0; i<intents.length; i++) {
5563                Intent intent = intents[i];
5564                if (intent != null) {
5565                    if (intent.hasFileDescriptors()) {
5566                        throw new IllegalArgumentException("File descriptors passed in Intent");
5567                    }
5568                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5569                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5570                        throw new IllegalArgumentException(
5571                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5572                    }
5573                    intents[i] = new Intent(intent);
5574                }
5575            }
5576            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5577                throw new IllegalArgumentException(
5578                        "Intent array length does not match resolvedTypes length");
5579            }
5580        }
5581        if (options != null) {
5582            if (options.hasFileDescriptors()) {
5583                throw new IllegalArgumentException("File descriptors passed in options");
5584            }
5585        }
5586
5587        synchronized(this) {
5588            int callingUid = Binder.getCallingUid();
5589            int origUserId = userId;
5590            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5591                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5592                    "getIntentSender", null);
5593            if (origUserId == UserHandle.USER_CURRENT) {
5594                // We don't want to evaluate this until the pending intent is
5595                // actually executed.  However, we do want to always do the
5596                // security checking for it above.
5597                userId = UserHandle.USER_CURRENT;
5598            }
5599            try {
5600                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5601                    int uid = AppGlobals.getPackageManager()
5602                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5603                    if (!UserHandle.isSameApp(callingUid, uid)) {
5604                        String msg = "Permission Denial: getIntentSender() from pid="
5605                            + Binder.getCallingPid()
5606                            + ", uid=" + Binder.getCallingUid()
5607                            + ", (need uid=" + uid + ")"
5608                            + " is not allowed to send as package " + packageName;
5609                        Slog.w(TAG, msg);
5610                        throw new SecurityException(msg);
5611                    }
5612                }
5613
5614                return getIntentSenderLocked(type, packageName, callingUid, userId,
5615                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5616
5617            } catch (RemoteException e) {
5618                throw new SecurityException(e);
5619            }
5620        }
5621    }
5622
5623    IIntentSender getIntentSenderLocked(int type, String packageName,
5624            int callingUid, int userId, IBinder token, String resultWho,
5625            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5626            Bundle options) {
5627        if (DEBUG_MU)
5628            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5629        ActivityRecord activity = null;
5630        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5631            activity = ActivityRecord.isInStackLocked(token);
5632            if (activity == null) {
5633                return null;
5634            }
5635            if (activity.finishing) {
5636                return null;
5637            }
5638        }
5639
5640        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5641        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5642        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5643        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5644                |PendingIntent.FLAG_UPDATE_CURRENT);
5645
5646        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5647                type, packageName, activity, resultWho,
5648                requestCode, intents, resolvedTypes, flags, options, userId);
5649        WeakReference<PendingIntentRecord> ref;
5650        ref = mIntentSenderRecords.get(key);
5651        PendingIntentRecord rec = ref != null ? ref.get() : null;
5652        if (rec != null) {
5653            if (!cancelCurrent) {
5654                if (updateCurrent) {
5655                    if (rec.key.requestIntent != null) {
5656                        rec.key.requestIntent.replaceExtras(intents != null ?
5657                                intents[intents.length - 1] : null);
5658                    }
5659                    if (intents != null) {
5660                        intents[intents.length-1] = rec.key.requestIntent;
5661                        rec.key.allIntents = intents;
5662                        rec.key.allResolvedTypes = resolvedTypes;
5663                    } else {
5664                        rec.key.allIntents = null;
5665                        rec.key.allResolvedTypes = null;
5666                    }
5667                }
5668                return rec;
5669            }
5670            rec.canceled = true;
5671            mIntentSenderRecords.remove(key);
5672        }
5673        if (noCreate) {
5674            return rec;
5675        }
5676        rec = new PendingIntentRecord(this, key, callingUid);
5677        mIntentSenderRecords.put(key, rec.ref);
5678        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5679            if (activity.pendingResults == null) {
5680                activity.pendingResults
5681                        = new HashSet<WeakReference<PendingIntentRecord>>();
5682            }
5683            activity.pendingResults.add(rec.ref);
5684        }
5685        return rec;
5686    }
5687
5688    @Override
5689    public void cancelIntentSender(IIntentSender sender) {
5690        if (!(sender instanceof PendingIntentRecord)) {
5691            return;
5692        }
5693        synchronized(this) {
5694            PendingIntentRecord rec = (PendingIntentRecord)sender;
5695            try {
5696                int uid = AppGlobals.getPackageManager()
5697                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5698                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5699                    String msg = "Permission Denial: cancelIntentSender() from pid="
5700                        + Binder.getCallingPid()
5701                        + ", uid=" + Binder.getCallingUid()
5702                        + " is not allowed to cancel packges "
5703                        + rec.key.packageName;
5704                    Slog.w(TAG, msg);
5705                    throw new SecurityException(msg);
5706                }
5707            } catch (RemoteException e) {
5708                throw new SecurityException(e);
5709            }
5710            cancelIntentSenderLocked(rec, true);
5711        }
5712    }
5713
5714    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5715        rec.canceled = true;
5716        mIntentSenderRecords.remove(rec.key);
5717        if (cleanActivity && rec.key.activity != null) {
5718            rec.key.activity.pendingResults.remove(rec.ref);
5719        }
5720    }
5721
5722    @Override
5723    public String getPackageForIntentSender(IIntentSender pendingResult) {
5724        if (!(pendingResult instanceof PendingIntentRecord)) {
5725            return null;
5726        }
5727        try {
5728            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5729            return res.key.packageName;
5730        } catch (ClassCastException e) {
5731        }
5732        return null;
5733    }
5734
5735    @Override
5736    public int getUidForIntentSender(IIntentSender sender) {
5737        if (sender instanceof PendingIntentRecord) {
5738            try {
5739                PendingIntentRecord res = (PendingIntentRecord)sender;
5740                return res.uid;
5741            } catch (ClassCastException e) {
5742            }
5743        }
5744        return -1;
5745    }
5746
5747    @Override
5748    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5749        if (!(pendingResult instanceof PendingIntentRecord)) {
5750            return false;
5751        }
5752        try {
5753            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5754            if (res.key.allIntents == null) {
5755                return false;
5756            }
5757            for (int i=0; i<res.key.allIntents.length; i++) {
5758                Intent intent = res.key.allIntents[i];
5759                if (intent.getPackage() != null && intent.getComponent() != null) {
5760                    return false;
5761                }
5762            }
5763            return true;
5764        } catch (ClassCastException e) {
5765        }
5766        return false;
5767    }
5768
5769    @Override
5770    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5771        if (!(pendingResult instanceof PendingIntentRecord)) {
5772            return false;
5773        }
5774        try {
5775            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5776            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5777                return true;
5778            }
5779            return false;
5780        } catch (ClassCastException e) {
5781        }
5782        return false;
5783    }
5784
5785    @Override
5786    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5787        if (!(pendingResult instanceof PendingIntentRecord)) {
5788            return null;
5789        }
5790        try {
5791            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5792            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5793        } catch (ClassCastException e) {
5794        }
5795        return null;
5796    }
5797
5798    @Override
5799    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5800        if (!(pendingResult instanceof PendingIntentRecord)) {
5801            return null;
5802        }
5803        try {
5804            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5805            Intent intent = res.key.requestIntent;
5806            if (intent != null) {
5807                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5808                        || res.lastTagPrefix.equals(prefix))) {
5809                    return res.lastTag;
5810                }
5811                res.lastTagPrefix = prefix;
5812                StringBuilder sb = new StringBuilder(128);
5813                if (prefix != null) {
5814                    sb.append(prefix);
5815                }
5816                if (intent.getAction() != null) {
5817                    sb.append(intent.getAction());
5818                } else if (intent.getComponent() != null) {
5819                    intent.getComponent().appendShortString(sb);
5820                } else {
5821                    sb.append("?");
5822                }
5823                return res.lastTag = sb.toString();
5824            }
5825        } catch (ClassCastException e) {
5826        }
5827        return null;
5828    }
5829
5830    @Override
5831    public void setProcessLimit(int max) {
5832        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5833                "setProcessLimit()");
5834        synchronized (this) {
5835            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5836            mProcessLimitOverride = max;
5837        }
5838        trimApplications();
5839    }
5840
5841    @Override
5842    public int getProcessLimit() {
5843        synchronized (this) {
5844            return mProcessLimitOverride;
5845        }
5846    }
5847
5848    void foregroundTokenDied(ForegroundToken token) {
5849        synchronized (ActivityManagerService.this) {
5850            synchronized (mPidsSelfLocked) {
5851                ForegroundToken cur
5852                    = mForegroundProcesses.get(token.pid);
5853                if (cur != token) {
5854                    return;
5855                }
5856                mForegroundProcesses.remove(token.pid);
5857                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5858                if (pr == null) {
5859                    return;
5860                }
5861                pr.forcingToForeground = null;
5862                updateProcessForegroundLocked(pr, false, false);
5863            }
5864            updateOomAdjLocked();
5865        }
5866    }
5867
5868    @Override
5869    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5870        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5871                "setProcessForeground()");
5872        synchronized(this) {
5873            boolean changed = false;
5874
5875            synchronized (mPidsSelfLocked) {
5876                ProcessRecord pr = mPidsSelfLocked.get(pid);
5877                if (pr == null && isForeground) {
5878                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5879                    return;
5880                }
5881                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5882                if (oldToken != null) {
5883                    oldToken.token.unlinkToDeath(oldToken, 0);
5884                    mForegroundProcesses.remove(pid);
5885                    if (pr != null) {
5886                        pr.forcingToForeground = null;
5887                    }
5888                    changed = true;
5889                }
5890                if (isForeground && token != null) {
5891                    ForegroundToken newToken = new ForegroundToken() {
5892                        @Override
5893                        public void binderDied() {
5894                            foregroundTokenDied(this);
5895                        }
5896                    };
5897                    newToken.pid = pid;
5898                    newToken.token = token;
5899                    try {
5900                        token.linkToDeath(newToken, 0);
5901                        mForegroundProcesses.put(pid, newToken);
5902                        pr.forcingToForeground = token;
5903                        changed = true;
5904                    } catch (RemoteException e) {
5905                        // If the process died while doing this, we will later
5906                        // do the cleanup with the process death link.
5907                    }
5908                }
5909            }
5910
5911            if (changed) {
5912                updateOomAdjLocked();
5913            }
5914        }
5915    }
5916
5917    // =========================================================
5918    // PERMISSIONS
5919    // =========================================================
5920
5921    static class PermissionController extends IPermissionController.Stub {
5922        ActivityManagerService mActivityManagerService;
5923        PermissionController(ActivityManagerService activityManagerService) {
5924            mActivityManagerService = activityManagerService;
5925        }
5926
5927        @Override
5928        public boolean checkPermission(String permission, int pid, int uid) {
5929            return mActivityManagerService.checkPermission(permission, pid,
5930                    uid) == PackageManager.PERMISSION_GRANTED;
5931        }
5932    }
5933
5934    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5935        @Override
5936        public int checkComponentPermission(String permission, int pid, int uid,
5937                int owningUid, boolean exported) {
5938            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5939                    owningUid, exported);
5940        }
5941
5942        @Override
5943        public Object getAMSLock() {
5944            return ActivityManagerService.this;
5945        }
5946    }
5947
5948    /**
5949     * This can be called with or without the global lock held.
5950     */
5951    int checkComponentPermission(String permission, int pid, int uid,
5952            int owningUid, boolean exported) {
5953        // We might be performing an operation on behalf of an indirect binder
5954        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5955        // client identity accordingly before proceeding.
5956        Identity tlsIdentity = sCallerIdentity.get();
5957        if (tlsIdentity != null) {
5958            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5959                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5960            uid = tlsIdentity.uid;
5961            pid = tlsIdentity.pid;
5962        }
5963
5964        if (pid == MY_PID) {
5965            return PackageManager.PERMISSION_GRANTED;
5966        }
5967
5968        return ActivityManager.checkComponentPermission(permission, uid,
5969                owningUid, exported);
5970    }
5971
5972    /**
5973     * As the only public entry point for permissions checking, this method
5974     * can enforce the semantic that requesting a check on a null global
5975     * permission is automatically denied.  (Internally a null permission
5976     * string is used when calling {@link #checkComponentPermission} in cases
5977     * when only uid-based security is needed.)
5978     *
5979     * This can be called with or without the global lock held.
5980     */
5981    @Override
5982    public int checkPermission(String permission, int pid, int uid) {
5983        if (permission == null) {
5984            return PackageManager.PERMISSION_DENIED;
5985        }
5986        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5987    }
5988
5989    /**
5990     * Binder IPC calls go through the public entry point.
5991     * This can be called with or without the global lock held.
5992     */
5993    int checkCallingPermission(String permission) {
5994        return checkPermission(permission,
5995                Binder.getCallingPid(),
5996                UserHandle.getAppId(Binder.getCallingUid()));
5997    }
5998
5999    /**
6000     * This can be called with or without the global lock held.
6001     */
6002    void enforceCallingPermission(String permission, String func) {
6003        if (checkCallingPermission(permission)
6004                == PackageManager.PERMISSION_GRANTED) {
6005            return;
6006        }
6007
6008        String msg = "Permission Denial: " + func + " from pid="
6009                + Binder.getCallingPid()
6010                + ", uid=" + Binder.getCallingUid()
6011                + " requires " + permission;
6012        Slog.w(TAG, msg);
6013        throw new SecurityException(msg);
6014    }
6015
6016    /**
6017     * Determine if UID is holding permissions required to access {@link Uri} in
6018     * the given {@link ProviderInfo}. Final permission checking is always done
6019     * in {@link ContentProvider}.
6020     */
6021    private final boolean checkHoldingPermissionsLocked(
6022            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6023        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6024                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6025        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6026            return false;
6027        }
6028
6029        if (pi.applicationInfo.uid == uid) {
6030            return true;
6031        } else if (!pi.exported) {
6032            return false;
6033        }
6034
6035        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6036        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6037        try {
6038            // check if target holds top-level <provider> permissions
6039            if (!readMet && pi.readPermission != null
6040                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6041                readMet = true;
6042            }
6043            if (!writeMet && pi.writePermission != null
6044                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6045                writeMet = true;
6046            }
6047
6048            // track if unprotected read/write is allowed; any denied
6049            // <path-permission> below removes this ability
6050            boolean allowDefaultRead = pi.readPermission == null;
6051            boolean allowDefaultWrite = pi.writePermission == null;
6052
6053            // check if target holds any <path-permission> that match uri
6054            final PathPermission[] pps = pi.pathPermissions;
6055            if (pps != null) {
6056                final String path = grantUri.uri.getPath();
6057                int i = pps.length;
6058                while (i > 0 && (!readMet || !writeMet)) {
6059                    i--;
6060                    PathPermission pp = pps[i];
6061                    if (pp.match(path)) {
6062                        if (!readMet) {
6063                            final String pprperm = pp.getReadPermission();
6064                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6065                                    + pprperm + " for " + pp.getPath()
6066                                    + ": match=" + pp.match(path)
6067                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6068                            if (pprperm != null) {
6069                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6070                                    readMet = true;
6071                                } else {
6072                                    allowDefaultRead = false;
6073                                }
6074                            }
6075                        }
6076                        if (!writeMet) {
6077                            final String ppwperm = pp.getWritePermission();
6078                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6079                                    + ppwperm + " for " + pp.getPath()
6080                                    + ": match=" + pp.match(path)
6081                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6082                            if (ppwperm != null) {
6083                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6084                                    writeMet = true;
6085                                } else {
6086                                    allowDefaultWrite = false;
6087                                }
6088                            }
6089                        }
6090                    }
6091                }
6092            }
6093
6094            // grant unprotected <provider> read/write, if not blocked by
6095            // <path-permission> above
6096            if (allowDefaultRead) readMet = true;
6097            if (allowDefaultWrite) writeMet = true;
6098
6099        } catch (RemoteException e) {
6100            return false;
6101        }
6102
6103        return readMet && writeMet;
6104    }
6105
6106    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6107        ProviderInfo pi = null;
6108        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6109        if (cpr != null) {
6110            pi = cpr.info;
6111        } else {
6112            try {
6113                pi = AppGlobals.getPackageManager().resolveContentProvider(
6114                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6115            } catch (RemoteException ex) {
6116            }
6117        }
6118        return pi;
6119    }
6120
6121    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6122        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6123        if (targetUris != null) {
6124            return targetUris.get(grantUri);
6125        }
6126        return null;
6127    }
6128
6129    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6130            String targetPkg, int targetUid, GrantUri grantUri) {
6131        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6132        if (targetUris == null) {
6133            targetUris = Maps.newArrayMap();
6134            mGrantedUriPermissions.put(targetUid, targetUris);
6135        }
6136
6137        UriPermission perm = targetUris.get(grantUri);
6138        if (perm == null) {
6139            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6140            targetUris.put(grantUri, perm);
6141        }
6142
6143        return perm;
6144    }
6145
6146    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6147            final int modeFlags) {
6148        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6149        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6150                : UriPermission.STRENGTH_OWNED;
6151
6152        // Root gets to do everything.
6153        if (uid == 0) {
6154            return true;
6155        }
6156
6157        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6158        if (perms == null) return false;
6159
6160        // First look for exact match
6161        final UriPermission exactPerm = perms.get(grantUri);
6162        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6163            return true;
6164        }
6165
6166        // No exact match, look for prefixes
6167        final int N = perms.size();
6168        for (int i = 0; i < N; i++) {
6169            final UriPermission perm = perms.valueAt(i);
6170            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6171                    && perm.getStrength(modeFlags) >= minStrength) {
6172                return true;
6173            }
6174        }
6175
6176        return false;
6177    }
6178
6179    @Override
6180    public int checkUriPermission(Uri uri, int pid, int uid,
6181            final int modeFlags, int userId) {
6182        enforceNotIsolatedCaller("checkUriPermission");
6183
6184        // Another redirected-binder-call permissions check as in
6185        // {@link checkComponentPermission}.
6186        Identity tlsIdentity = sCallerIdentity.get();
6187        if (tlsIdentity != null) {
6188            uid = tlsIdentity.uid;
6189            pid = tlsIdentity.pid;
6190        }
6191
6192        // Our own process gets to do everything.
6193        if (pid == MY_PID) {
6194            return PackageManager.PERMISSION_GRANTED;
6195        }
6196        synchronized (this) {
6197            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6198                    ? PackageManager.PERMISSION_GRANTED
6199                    : PackageManager.PERMISSION_DENIED;
6200        }
6201    }
6202
6203    /**
6204     * Check if the targetPkg can be granted permission to access uri by
6205     * the callingUid using the given modeFlags.  Throws a security exception
6206     * if callingUid is not allowed to do this.  Returns the uid of the target
6207     * if the URI permission grant should be performed; returns -1 if it is not
6208     * needed (for example targetPkg already has permission to access the URI).
6209     * If you already know the uid of the target, you can supply it in
6210     * lastTargetUid else set that to -1.
6211     */
6212    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6213            final int modeFlags, int lastTargetUid) {
6214        if (!Intent.isAccessUriMode(modeFlags)) {
6215            return -1;
6216        }
6217
6218        if (targetPkg != null) {
6219            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6220                    "Checking grant " + targetPkg + " permission to " + grantUri);
6221        }
6222
6223        final IPackageManager pm = AppGlobals.getPackageManager();
6224
6225        // If this is not a content: uri, we can't do anything with it.
6226        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6227            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6228                    "Can't grant URI permission for non-content URI: " + grantUri);
6229            return -1;
6230        }
6231
6232        final String authority = grantUri.uri.getAuthority();
6233        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6234        if (pi == null) {
6235            Slog.w(TAG, "No content provider found for permission check: " +
6236                    grantUri.uri.toSafeString());
6237            return -1;
6238        }
6239
6240        int targetUid = lastTargetUid;
6241        if (targetUid < 0 && targetPkg != null) {
6242            try {
6243                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6244                if (targetUid < 0) {
6245                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6246                            "Can't grant URI permission no uid for: " + targetPkg);
6247                    return -1;
6248                }
6249            } catch (RemoteException ex) {
6250                return -1;
6251            }
6252        }
6253
6254        if (targetUid >= 0) {
6255            // First...  does the target actually need this permission?
6256            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6257                // No need to grant the target this permission.
6258                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6259                        "Target " + targetPkg + " already has full permission to " + grantUri);
6260                return -1;
6261            }
6262        } else {
6263            // First...  there is no target package, so can anyone access it?
6264            boolean allowed = pi.exported;
6265            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6266                if (pi.readPermission != null) {
6267                    allowed = false;
6268                }
6269            }
6270            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6271                if (pi.writePermission != null) {
6272                    allowed = false;
6273                }
6274            }
6275            if (allowed) {
6276                return -1;
6277            }
6278        }
6279
6280        // Second...  is the provider allowing granting of URI permissions?
6281        if (!pi.grantUriPermissions) {
6282            throw new SecurityException("Provider " + pi.packageName
6283                    + "/" + pi.name
6284                    + " does not allow granting of Uri permissions (uri "
6285                    + grantUri + ")");
6286        }
6287        if (pi.uriPermissionPatterns != null) {
6288            final int N = pi.uriPermissionPatterns.length;
6289            boolean allowed = false;
6290            for (int i=0; i<N; i++) {
6291                if (pi.uriPermissionPatterns[i] != null
6292                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6293                    allowed = true;
6294                    break;
6295                }
6296            }
6297            if (!allowed) {
6298                throw new SecurityException("Provider " + pi.packageName
6299                        + "/" + pi.name
6300                        + " does not allow granting of permission to path of Uri "
6301                        + grantUri);
6302            }
6303        }
6304
6305        // Third...  does the caller itself have permission to access
6306        // this uri?
6307        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6308            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6309                // Require they hold a strong enough Uri permission
6310                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6311                    throw new SecurityException("Uid " + callingUid
6312                            + " does not have permission to uri " + grantUri);
6313                }
6314            }
6315        }
6316        return targetUid;
6317    }
6318
6319    @Override
6320    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6321            final int modeFlags, int userId) {
6322        enforceNotIsolatedCaller("checkGrantUriPermission");
6323        synchronized(this) {
6324            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6325                    new GrantUri(userId, uri, false), modeFlags, -1);
6326        }
6327    }
6328
6329    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6330            final int modeFlags, UriPermissionOwner owner) {
6331        if (!Intent.isAccessUriMode(modeFlags)) {
6332            return;
6333        }
6334
6335        // So here we are: the caller has the assumed permission
6336        // to the uri, and the target doesn't.  Let's now give this to
6337        // the target.
6338
6339        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6340                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6341
6342        final String authority = grantUri.uri.getAuthority();
6343        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6344        if (pi == null) {
6345            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6346            return;
6347        }
6348
6349        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6350            grantUri.prefix = true;
6351        }
6352        final UriPermission perm = findOrCreateUriPermissionLocked(
6353                pi.packageName, targetPkg, targetUid, grantUri);
6354        perm.grantModes(modeFlags, owner);
6355    }
6356
6357    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6358            final int modeFlags, UriPermissionOwner owner) {
6359        if (targetPkg == null) {
6360            throw new NullPointerException("targetPkg");
6361        }
6362
6363        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6364                -1);
6365        if (targetUid < 0) {
6366            return;
6367        }
6368
6369        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6370                owner);
6371    }
6372
6373    static class NeededUriGrants extends ArrayList<GrantUri> {
6374        final String targetPkg;
6375        final int targetUid;
6376        final int flags;
6377
6378        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6379            this.targetPkg = targetPkg;
6380            this.targetUid = targetUid;
6381            this.flags = flags;
6382        }
6383    }
6384
6385    /**
6386     * Like checkGrantUriPermissionLocked, but takes an Intent.
6387     */
6388    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6389            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6390        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6391                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6392                + " clip=" + (intent != null ? intent.getClipData() : null)
6393                + " from " + intent + "; flags=0x"
6394                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6395
6396        if (targetPkg == null) {
6397            throw new NullPointerException("targetPkg");
6398        }
6399
6400        if (intent == null) {
6401            return null;
6402        }
6403        Uri data = intent.getData();
6404        ClipData clip = intent.getClipData();
6405        if (data == null && clip == null) {
6406            return null;
6407        }
6408        final IPackageManager pm = AppGlobals.getPackageManager();
6409        int targetUid;
6410        if (needed != null) {
6411            targetUid = needed.targetUid;
6412        } else {
6413            try {
6414                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6415            } catch (RemoteException ex) {
6416                return null;
6417            }
6418            if (targetUid < 0) {
6419                if (DEBUG_URI_PERMISSION) {
6420                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6421                            + " on user " + targetUserId);
6422                }
6423                return null;
6424            }
6425        }
6426        if (data != null) {
6427            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6428            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6429                    targetUid);
6430            if (targetUid > 0) {
6431                if (needed == null) {
6432                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6433                }
6434                needed.add(grantUri);
6435            }
6436        }
6437        if (clip != null) {
6438            for (int i=0; i<clip.getItemCount(); i++) {
6439                Uri uri = clip.getItemAt(i).getUri();
6440                if (uri != null) {
6441                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
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                } else {
6451                    Intent clipIntent = clip.getItemAt(i).getIntent();
6452                    if (clipIntent != null) {
6453                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6454                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6455                        if (newNeeded != null) {
6456                            needed = newNeeded;
6457                        }
6458                    }
6459                }
6460            }
6461        }
6462
6463        return needed;
6464    }
6465
6466    /**
6467     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6468     */
6469    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6470            UriPermissionOwner owner) {
6471        if (needed != null) {
6472            for (int i=0; i<needed.size(); i++) {
6473                GrantUri grantUri = needed.get(i);
6474                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6475                        grantUri, needed.flags, owner);
6476            }
6477        }
6478    }
6479
6480    void grantUriPermissionFromIntentLocked(int callingUid,
6481            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6482        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6483                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6484        if (needed == null) {
6485            return;
6486        }
6487
6488        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6489    }
6490
6491    @Override
6492    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6493            final int modeFlags, int userId) {
6494        enforceNotIsolatedCaller("grantUriPermission");
6495        GrantUri grantUri = new GrantUri(userId, uri, false);
6496        synchronized(this) {
6497            final ProcessRecord r = getRecordForAppLocked(caller);
6498            if (r == null) {
6499                throw new SecurityException("Unable to find app for caller "
6500                        + caller
6501                        + " when granting permission to uri " + grantUri);
6502            }
6503            if (targetPkg == null) {
6504                throw new IllegalArgumentException("null target");
6505            }
6506            if (grantUri == null) {
6507                throw new IllegalArgumentException("null uri");
6508            }
6509
6510            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6511                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6512                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6513                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6514
6515            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6516        }
6517    }
6518
6519    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6520        if (perm.modeFlags == 0) {
6521            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6522                    perm.targetUid);
6523            if (perms != null) {
6524                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6525                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6526
6527                perms.remove(perm.uri);
6528                if (perms.isEmpty()) {
6529                    mGrantedUriPermissions.remove(perm.targetUid);
6530                }
6531            }
6532        }
6533    }
6534
6535    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6536        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6537
6538        final IPackageManager pm = AppGlobals.getPackageManager();
6539        final String authority = grantUri.uri.getAuthority();
6540        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6541        if (pi == null) {
6542            Slog.w(TAG, "No content provider found for permission revoke: "
6543                    + grantUri.toSafeString());
6544            return;
6545        }
6546
6547        // Does the caller have this permission on the URI?
6548        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6549            // Right now, if you are not the original owner of the permission,
6550            // you are not allowed to revoke it.
6551            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6552                throw new SecurityException("Uid " + callingUid
6553                        + " does not have permission to uri " + grantUri);
6554            //}
6555        }
6556
6557        boolean persistChanged = false;
6558
6559        // Go through all of the permissions and remove any that match.
6560        int N = mGrantedUriPermissions.size();
6561        for (int i = 0; i < N; i++) {
6562            final int targetUid = mGrantedUriPermissions.keyAt(i);
6563            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6564
6565            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6566                final UriPermission perm = it.next();
6567                if (perm.uri.sourceUserId == grantUri.sourceUserId
6568                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6569                    if (DEBUG_URI_PERMISSION)
6570                        Slog.v(TAG,
6571                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6572                    persistChanged |= perm.revokeModes(
6573                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6574                    if (perm.modeFlags == 0) {
6575                        it.remove();
6576                    }
6577                }
6578            }
6579
6580            if (perms.isEmpty()) {
6581                mGrantedUriPermissions.remove(targetUid);
6582                N--;
6583                i--;
6584            }
6585        }
6586
6587        if (persistChanged) {
6588            schedulePersistUriGrants();
6589        }
6590    }
6591
6592    @Override
6593    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6594            int userId) {
6595        enforceNotIsolatedCaller("revokeUriPermission");
6596        synchronized(this) {
6597            final ProcessRecord r = getRecordForAppLocked(caller);
6598            if (r == null) {
6599                throw new SecurityException("Unable to find app for caller "
6600                        + caller
6601                        + " when revoking permission to uri " + uri);
6602            }
6603            if (uri == null) {
6604                Slog.w(TAG, "revokeUriPermission: null uri");
6605                return;
6606            }
6607
6608            if (!Intent.isAccessUriMode(modeFlags)) {
6609                return;
6610            }
6611
6612            final IPackageManager pm = AppGlobals.getPackageManager();
6613            final String authority = uri.getAuthority();
6614            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6615            if (pi == null) {
6616                Slog.w(TAG, "No content provider found for permission revoke: "
6617                        + uri.toSafeString());
6618                return;
6619            }
6620
6621            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6622        }
6623    }
6624
6625    /**
6626     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6627     * given package.
6628     *
6629     * @param packageName Package name to match, or {@code null} to apply to all
6630     *            packages.
6631     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6632     *            to all users.
6633     * @param persistable If persistable grants should be removed.
6634     */
6635    private void removeUriPermissionsForPackageLocked(
6636            String packageName, int userHandle, boolean persistable) {
6637        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6638            throw new IllegalArgumentException("Must narrow by either package or user");
6639        }
6640
6641        boolean persistChanged = false;
6642
6643        int N = mGrantedUriPermissions.size();
6644        for (int i = 0; i < N; i++) {
6645            final int targetUid = mGrantedUriPermissions.keyAt(i);
6646            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6647
6648            // Only inspect grants matching user
6649            if (userHandle == UserHandle.USER_ALL
6650                    || userHandle == UserHandle.getUserId(targetUid)) {
6651                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6652                    final UriPermission perm = it.next();
6653
6654                    // Only inspect grants matching package
6655                    if (packageName == null || perm.sourcePkg.equals(packageName)
6656                            || perm.targetPkg.equals(packageName)) {
6657                        persistChanged |= perm.revokeModes(
6658                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6659
6660                        // Only remove when no modes remain; any persisted grants
6661                        // will keep this alive.
6662                        if (perm.modeFlags == 0) {
6663                            it.remove();
6664                        }
6665                    }
6666                }
6667
6668                if (perms.isEmpty()) {
6669                    mGrantedUriPermissions.remove(targetUid);
6670                    N--;
6671                    i--;
6672                }
6673            }
6674        }
6675
6676        if (persistChanged) {
6677            schedulePersistUriGrants();
6678        }
6679    }
6680
6681    @Override
6682    public IBinder newUriPermissionOwner(String name) {
6683        enforceNotIsolatedCaller("newUriPermissionOwner");
6684        synchronized(this) {
6685            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6686            return owner.getExternalTokenLocked();
6687        }
6688    }
6689
6690    @Override
6691    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6692            final int modeFlags, int userId) {
6693        synchronized(this) {
6694            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6695            if (owner == null) {
6696                throw new IllegalArgumentException("Unknown owner: " + token);
6697            }
6698            if (fromUid != Binder.getCallingUid()) {
6699                if (Binder.getCallingUid() != Process.myUid()) {
6700                    // Only system code can grant URI permissions on behalf
6701                    // of other users.
6702                    throw new SecurityException("nice try");
6703                }
6704            }
6705            if (targetPkg == null) {
6706                throw new IllegalArgumentException("null target");
6707            }
6708            if (uri == null) {
6709                throw new IllegalArgumentException("null uri");
6710            }
6711
6712            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6713                    modeFlags, owner);
6714        }
6715    }
6716
6717    @Override
6718    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6719        synchronized(this) {
6720            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6721            if (owner == null) {
6722                throw new IllegalArgumentException("Unknown owner: " + token);
6723            }
6724
6725            if (uri == null) {
6726                owner.removeUriPermissionsLocked(mode);
6727            } else {
6728                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6729            }
6730        }
6731    }
6732
6733    private void schedulePersistUriGrants() {
6734        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6735            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6736                    10 * DateUtils.SECOND_IN_MILLIS);
6737        }
6738    }
6739
6740    private void writeGrantedUriPermissions() {
6741        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6742
6743        // Snapshot permissions so we can persist without lock
6744        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6745        synchronized (this) {
6746            final int size = mGrantedUriPermissions.size();
6747            for (int i = 0; i < size; i++) {
6748                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6749                for (UriPermission perm : perms.values()) {
6750                    if (perm.persistedModeFlags != 0) {
6751                        persist.add(perm.snapshot());
6752                    }
6753                }
6754            }
6755        }
6756
6757        FileOutputStream fos = null;
6758        try {
6759            fos = mGrantFile.startWrite();
6760
6761            XmlSerializer out = new FastXmlSerializer();
6762            out.setOutput(fos, "utf-8");
6763            out.startDocument(null, true);
6764            out.startTag(null, TAG_URI_GRANTS);
6765            for (UriPermission.Snapshot perm : persist) {
6766                out.startTag(null, TAG_URI_GRANT);
6767                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6768                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6769                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6770                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6771                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6772                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6773                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6774                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6775                out.endTag(null, TAG_URI_GRANT);
6776            }
6777            out.endTag(null, TAG_URI_GRANTS);
6778            out.endDocument();
6779
6780            mGrantFile.finishWrite(fos);
6781        } catch (IOException e) {
6782            if (fos != null) {
6783                mGrantFile.failWrite(fos);
6784            }
6785        }
6786    }
6787
6788    private void readGrantedUriPermissionsLocked() {
6789        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6790
6791        final long now = System.currentTimeMillis();
6792
6793        FileInputStream fis = null;
6794        try {
6795            fis = mGrantFile.openRead();
6796            final XmlPullParser in = Xml.newPullParser();
6797            in.setInput(fis, null);
6798
6799            int type;
6800            while ((type = in.next()) != END_DOCUMENT) {
6801                final String tag = in.getName();
6802                if (type == START_TAG) {
6803                    if (TAG_URI_GRANT.equals(tag)) {
6804                        final int sourceUserId;
6805                        final int targetUserId;
6806                        final int userHandle = readIntAttribute(in,
6807                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6808                        if (userHandle != UserHandle.USER_NULL) {
6809                            // For backwards compatibility.
6810                            sourceUserId = userHandle;
6811                            targetUserId = userHandle;
6812                        } else {
6813                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6814                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6815                        }
6816                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6817                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6818                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6819                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6820                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6821                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6822
6823                        // Sanity check that provider still belongs to source package
6824                        final ProviderInfo pi = getProviderInfoLocked(
6825                                uri.getAuthority(), sourceUserId);
6826                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6827                            int targetUid = -1;
6828                            try {
6829                                targetUid = AppGlobals.getPackageManager()
6830                                        .getPackageUid(targetPkg, targetUserId);
6831                            } catch (RemoteException e) {
6832                            }
6833                            if (targetUid != -1) {
6834                                final UriPermission perm = findOrCreateUriPermissionLocked(
6835                                        sourcePkg, targetPkg, targetUid,
6836                                        new GrantUri(sourceUserId, uri, prefix));
6837                                perm.initPersistedModes(modeFlags, createdTime);
6838                            }
6839                        } else {
6840                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6841                                    + " but instead found " + pi);
6842                        }
6843                    }
6844                }
6845            }
6846        } catch (FileNotFoundException e) {
6847            // Missing grants is okay
6848        } catch (IOException e) {
6849            Log.wtf(TAG, "Failed reading Uri grants", e);
6850        } catch (XmlPullParserException e) {
6851            Log.wtf(TAG, "Failed reading Uri grants", e);
6852        } finally {
6853            IoUtils.closeQuietly(fis);
6854        }
6855    }
6856
6857    @Override
6858    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6859        enforceNotIsolatedCaller("takePersistableUriPermission");
6860
6861        Preconditions.checkFlagsArgument(modeFlags,
6862                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6863
6864        synchronized (this) {
6865            final int callingUid = Binder.getCallingUid();
6866            boolean persistChanged = false;
6867            GrantUri grantUri = new GrantUri(userId, uri, false);
6868
6869            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6870                    new GrantUri(userId, uri, false));
6871            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6872                    new GrantUri(userId, uri, true));
6873
6874            final boolean exactValid = (exactPerm != null)
6875                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6876            final boolean prefixValid = (prefixPerm != null)
6877                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6878
6879            if (!(exactValid || prefixValid)) {
6880                throw new SecurityException("No persistable permission grants found for UID "
6881                        + callingUid + " and Uri " + grantUri.toSafeString());
6882            }
6883
6884            if (exactValid) {
6885                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6886            }
6887            if (prefixValid) {
6888                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6889            }
6890
6891            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6892
6893            if (persistChanged) {
6894                schedulePersistUriGrants();
6895            }
6896        }
6897    }
6898
6899    @Override
6900    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6901        enforceNotIsolatedCaller("releasePersistableUriPermission");
6902
6903        Preconditions.checkFlagsArgument(modeFlags,
6904                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6905
6906        synchronized (this) {
6907            final int callingUid = Binder.getCallingUid();
6908            boolean persistChanged = false;
6909
6910            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6911                    new GrantUri(userId, uri, false));
6912            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6913                    new GrantUri(userId, uri, true));
6914            if (exactPerm == null && prefixPerm == null) {
6915                throw new SecurityException("No permission grants found for UID " + callingUid
6916                        + " and Uri " + uri.toSafeString());
6917            }
6918
6919            if (exactPerm != null) {
6920                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6921                removeUriPermissionIfNeededLocked(exactPerm);
6922            }
6923            if (prefixPerm != null) {
6924                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6925                removeUriPermissionIfNeededLocked(prefixPerm);
6926            }
6927
6928            if (persistChanged) {
6929                schedulePersistUriGrants();
6930            }
6931        }
6932    }
6933
6934    /**
6935     * Prune any older {@link UriPermission} for the given UID until outstanding
6936     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6937     *
6938     * @return if any mutations occured that require persisting.
6939     */
6940    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6941        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6942        if (perms == null) return false;
6943        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6944
6945        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6946        for (UriPermission perm : perms.values()) {
6947            if (perm.persistedModeFlags != 0) {
6948                persisted.add(perm);
6949            }
6950        }
6951
6952        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6953        if (trimCount <= 0) return false;
6954
6955        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6956        for (int i = 0; i < trimCount; i++) {
6957            final UriPermission perm = persisted.get(i);
6958
6959            if (DEBUG_URI_PERMISSION) {
6960                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6961            }
6962
6963            perm.releasePersistableModes(~0);
6964            removeUriPermissionIfNeededLocked(perm);
6965        }
6966
6967        return true;
6968    }
6969
6970    @Override
6971    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6972            String packageName, boolean incoming) {
6973        enforceNotIsolatedCaller("getPersistedUriPermissions");
6974        Preconditions.checkNotNull(packageName, "packageName");
6975
6976        final int callingUid = Binder.getCallingUid();
6977        final IPackageManager pm = AppGlobals.getPackageManager();
6978        try {
6979            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6980            if (packageUid != callingUid) {
6981                throw new SecurityException(
6982                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6983            }
6984        } catch (RemoteException e) {
6985            throw new SecurityException("Failed to verify package name ownership");
6986        }
6987
6988        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6989        synchronized (this) {
6990            if (incoming) {
6991                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6992                        callingUid);
6993                if (perms == null) {
6994                    Slog.w(TAG, "No permission grants found for " + packageName);
6995                } else {
6996                    for (UriPermission perm : perms.values()) {
6997                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6998                            result.add(perm.buildPersistedPublicApiObject());
6999                        }
7000                    }
7001                }
7002            } else {
7003                final int size = mGrantedUriPermissions.size();
7004                for (int i = 0; i < size; i++) {
7005                    final ArrayMap<GrantUri, UriPermission> perms =
7006                            mGrantedUriPermissions.valueAt(i);
7007                    for (UriPermission perm : perms.values()) {
7008                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7009                            result.add(perm.buildPersistedPublicApiObject());
7010                        }
7011                    }
7012                }
7013            }
7014        }
7015        return new ParceledListSlice<android.content.UriPermission>(result);
7016    }
7017
7018    @Override
7019    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7020        synchronized (this) {
7021            ProcessRecord app =
7022                who != null ? getRecordForAppLocked(who) : null;
7023            if (app == null) return;
7024
7025            Message msg = Message.obtain();
7026            msg.what = WAIT_FOR_DEBUGGER_MSG;
7027            msg.obj = app;
7028            msg.arg1 = waiting ? 1 : 0;
7029            mHandler.sendMessage(msg);
7030        }
7031    }
7032
7033    @Override
7034    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7035        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7036        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7037        outInfo.availMem = Process.getFreeMemory();
7038        outInfo.totalMem = Process.getTotalMemory();
7039        outInfo.threshold = homeAppMem;
7040        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7041        outInfo.hiddenAppThreshold = cachedAppMem;
7042        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7043                ProcessList.SERVICE_ADJ);
7044        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7045                ProcessList.VISIBLE_APP_ADJ);
7046        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7047                ProcessList.FOREGROUND_APP_ADJ);
7048    }
7049
7050    // =========================================================
7051    // TASK MANAGEMENT
7052    // =========================================================
7053
7054    @Override
7055    public List<IAppTask> getAppTasks() {
7056        int callingUid = Binder.getCallingUid();
7057        long ident = Binder.clearCallingIdentity();
7058        synchronized(this) {
7059            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7060            try {
7061                if (localLOGV) Slog.v(TAG, "getAppTasks");
7062
7063                final int N = mRecentTasks.size();
7064                for (int i = 0; i < N; i++) {
7065                    TaskRecord tr = mRecentTasks.get(i);
7066                    // Skip tasks that are not created by the caller
7067                    if (tr.creatorUid == callingUid) {
7068                        ActivityManager.RecentTaskInfo taskInfo =
7069                                createRecentTaskInfoFromTaskRecord(tr);
7070                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7071                        list.add(taskImpl);
7072                    }
7073                }
7074            } finally {
7075                Binder.restoreCallingIdentity(ident);
7076            }
7077            return list;
7078        }
7079    }
7080
7081    @Override
7082    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7083        final int callingUid = Binder.getCallingUid();
7084        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7085
7086        synchronized(this) {
7087            if (localLOGV) Slog.v(
7088                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7089
7090            final boolean allowed = checkCallingPermission(
7091                    android.Manifest.permission.GET_TASKS)
7092                    == PackageManager.PERMISSION_GRANTED;
7093            if (!allowed) {
7094                Slog.w(TAG, "getTasks: caller " + callingUid
7095                        + " does not hold GET_TASKS; limiting output");
7096            }
7097
7098            // TODO: Improve with MRU list from all ActivityStacks.
7099            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7100        }
7101
7102        return list;
7103    }
7104
7105    TaskRecord getMostRecentTask() {
7106        return mRecentTasks.get(0);
7107    }
7108
7109    /**
7110     * Creates a new RecentTaskInfo from a TaskRecord.
7111     */
7112    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7113        // Update the task description to reflect any changes in the task stack
7114        tr.updateTaskDescription();
7115
7116        // Compose the recent task info
7117        ActivityManager.RecentTaskInfo rti
7118                = new ActivityManager.RecentTaskInfo();
7119        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7120        rti.persistentId = tr.taskId;
7121        rti.baseIntent = new Intent(tr.getBaseIntent());
7122        rti.origActivity = tr.origActivity;
7123        rti.description = tr.lastDescription;
7124        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7125        rti.userId = tr.userId;
7126        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7127        return rti;
7128    }
7129
7130    @Override
7131    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7132            int flags, int userId) {
7133        final int callingUid = Binder.getCallingUid();
7134        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7135                false, true, "getRecentTasks", null);
7136
7137        synchronized (this) {
7138            final boolean allowed = checkCallingPermission(
7139                    android.Manifest.permission.GET_TASKS)
7140                    == PackageManager.PERMISSION_GRANTED;
7141            if (!allowed) {
7142                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7143                        + " does not hold GET_TASKS; limiting output");
7144            }
7145            final boolean detailed = checkCallingPermission(
7146                    android.Manifest.permission.GET_DETAILED_TASKS)
7147                    == PackageManager.PERMISSION_GRANTED;
7148
7149            IPackageManager pm = AppGlobals.getPackageManager();
7150
7151            final int N = mRecentTasks.size();
7152            ArrayList<ActivityManager.RecentTaskInfo> res
7153                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7154                            maxNum < N ? maxNum : N);
7155
7156            final Set<Integer> includedUsers;
7157            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7158                includedUsers = getProfileIdsLocked(userId);
7159            } else {
7160                includedUsers = new HashSet<Integer>();
7161            }
7162            includedUsers.add(Integer.valueOf(userId));
7163            for (int i=0; i<N && maxNum > 0; i++) {
7164                TaskRecord tr = mRecentTasks.get(i);
7165                // Only add calling user or related users recent tasks
7166                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7167
7168                // Return the entry if desired by the caller.  We always return
7169                // the first entry, because callers always expect this to be the
7170                // foreground app.  We may filter others if the caller has
7171                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7172                // we should exclude the entry.
7173
7174                if (i == 0
7175                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7176                        || (tr.intent == null)
7177                        || ((tr.intent.getFlags()
7178                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7179                    if (!allowed) {
7180                        // If the caller doesn't have the GET_TASKS permission, then only
7181                        // allow them to see a small subset of tasks -- their own and home.
7182                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7183                            continue;
7184                        }
7185                    }
7186
7187                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7188                    if (!detailed) {
7189                        rti.baseIntent.replaceExtras((Bundle)null);
7190                    }
7191
7192                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7193                        // Check whether this activity is currently available.
7194                        try {
7195                            if (rti.origActivity != null) {
7196                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7197                                        == null) {
7198                                    continue;
7199                                }
7200                            } else if (rti.baseIntent != null) {
7201                                if (pm.queryIntentActivities(rti.baseIntent,
7202                                        null, 0, userId) == null) {
7203                                    continue;
7204                                }
7205                            }
7206                        } catch (RemoteException e) {
7207                            // Will never happen.
7208                        }
7209                    }
7210
7211                    res.add(rti);
7212                    maxNum--;
7213                }
7214            }
7215            return res;
7216        }
7217    }
7218
7219    private TaskRecord recentTaskForIdLocked(int id) {
7220        final int N = mRecentTasks.size();
7221            for (int i=0; i<N; i++) {
7222                TaskRecord tr = mRecentTasks.get(i);
7223                if (tr.taskId == id) {
7224                    return tr;
7225                }
7226            }
7227            return null;
7228    }
7229
7230    @Override
7231    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7232        synchronized (this) {
7233            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7234                    "getTaskThumbnails()");
7235            TaskRecord tr = recentTaskForIdLocked(id);
7236            if (tr != null) {
7237                return tr.getTaskThumbnailsLocked();
7238            }
7239        }
7240        return null;
7241    }
7242
7243    @Override
7244    public Bitmap getTaskTopThumbnail(int id) {
7245        synchronized (this) {
7246            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7247                    "getTaskTopThumbnail()");
7248            TaskRecord tr = recentTaskForIdLocked(id);
7249            if (tr != null) {
7250                return tr.getTaskTopThumbnailLocked();
7251            }
7252        }
7253        return null;
7254    }
7255
7256    @Override
7257    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7258        synchronized (this) {
7259            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7260            if (r != null) {
7261                r.taskDescription = td;
7262                r.task.updateTaskDescription();
7263            }
7264        }
7265    }
7266
7267    @Override
7268    public boolean removeSubTask(int taskId, int subTaskIndex) {
7269        synchronized (this) {
7270            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7271                    "removeSubTask()");
7272            long ident = Binder.clearCallingIdentity();
7273            try {
7274                TaskRecord tr = recentTaskForIdLocked(taskId);
7275                if (tr != null) {
7276                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7277                }
7278                return false;
7279            } finally {
7280                Binder.restoreCallingIdentity(ident);
7281            }
7282        }
7283    }
7284
7285    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7286        if (!pr.killedByAm) {
7287            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7288            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7289                    pr.processName, pr.setAdj, reason);
7290            pr.killedByAm = true;
7291            Process.killProcessQuiet(pr.pid);
7292        }
7293    }
7294
7295    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7296        tr.disposeThumbnail();
7297        mRecentTasks.remove(tr);
7298        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7299        Intent baseIntent = new Intent(
7300                tr.intent != null ? tr.intent : tr.affinityIntent);
7301        ComponentName component = baseIntent.getComponent();
7302        if (component == null) {
7303            Slog.w(TAG, "Now component for base intent of task: " + tr);
7304            return;
7305        }
7306
7307        // Find any running services associated with this app.
7308        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7309
7310        if (killProcesses) {
7311            // Find any running processes associated with this app.
7312            final String pkg = component.getPackageName();
7313            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7314            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7315            for (int i=0; i<pmap.size(); i++) {
7316                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7317                for (int j=0; j<uids.size(); j++) {
7318                    ProcessRecord proc = uids.valueAt(j);
7319                    if (proc.userId != tr.userId) {
7320                        continue;
7321                    }
7322                    if (!proc.pkgList.containsKey(pkg)) {
7323                        continue;
7324                    }
7325                    procs.add(proc);
7326                }
7327            }
7328
7329            // Kill the running processes.
7330            for (int i=0; i<procs.size(); i++) {
7331                ProcessRecord pr = procs.get(i);
7332                if (pr == mHomeProcess) {
7333                    // Don't kill the home process along with tasks from the same package.
7334                    continue;
7335                }
7336                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7337                    killUnneededProcessLocked(pr, "remove task");
7338                } else {
7339                    pr.waitingToKill = "remove task";
7340                }
7341            }
7342        }
7343    }
7344
7345    /**
7346     * Removes the task with the specified task id.
7347     *
7348     * @param taskId Identifier of the task to be removed.
7349     * @param flags Additional operational flags.  May be 0 or
7350     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7351     * @return Returns true if the given task was found and removed.
7352     */
7353    private boolean removeTaskByIdLocked(int taskId, int flags) {
7354        TaskRecord tr = recentTaskForIdLocked(taskId);
7355        if (tr != null) {
7356            tr.removeTaskActivitiesLocked(-1, false);
7357            cleanUpRemovedTaskLocked(tr, flags);
7358            if (tr.isPersistable) {
7359                notifyTaskPersisterLocked(tr, true);
7360            }
7361            return true;
7362        }
7363        return false;
7364    }
7365
7366    @Override
7367    public boolean removeTask(int taskId, int flags) {
7368        synchronized (this) {
7369            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7370                    "removeTask()");
7371            long ident = Binder.clearCallingIdentity();
7372            try {
7373                return removeTaskByIdLocked(taskId, flags);
7374            } finally {
7375                Binder.restoreCallingIdentity(ident);
7376            }
7377        }
7378    }
7379
7380    /**
7381     * TODO: Add mController hook
7382     */
7383    @Override
7384    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7385        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7386                "moveTaskToFront()");
7387
7388        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7389        synchronized(this) {
7390            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7391                    Binder.getCallingUid(), "Task to front")) {
7392                ActivityOptions.abort(options);
7393                return;
7394            }
7395            final long origId = Binder.clearCallingIdentity();
7396            try {
7397                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7398                if (task == null) {
7399                    return;
7400                }
7401                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7402                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7403                    return;
7404                }
7405                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7406            } finally {
7407                Binder.restoreCallingIdentity(origId);
7408            }
7409            ActivityOptions.abort(options);
7410        }
7411    }
7412
7413    @Override
7414    public void moveTaskToBack(int taskId) {
7415        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7416                "moveTaskToBack()");
7417
7418        synchronized(this) {
7419            TaskRecord tr = recentTaskForIdLocked(taskId);
7420            if (tr != null) {
7421                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7422                ActivityStack stack = tr.stack;
7423                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7424                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7425                            Binder.getCallingUid(), "Task to back")) {
7426                        return;
7427                    }
7428                }
7429                final long origId = Binder.clearCallingIdentity();
7430                try {
7431                    stack.moveTaskToBackLocked(taskId, null);
7432                } finally {
7433                    Binder.restoreCallingIdentity(origId);
7434                }
7435            }
7436        }
7437    }
7438
7439    /**
7440     * Moves an activity, and all of the other activities within the same task, to the bottom
7441     * of the history stack.  The activity's order within the task is unchanged.
7442     *
7443     * @param token A reference to the activity we wish to move
7444     * @param nonRoot If false then this only works if the activity is the root
7445     *                of a task; if true it will work for any activity in a task.
7446     * @return Returns true if the move completed, false if not.
7447     */
7448    @Override
7449    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7450        enforceNotIsolatedCaller("moveActivityTaskToBack");
7451        synchronized(this) {
7452            final long origId = Binder.clearCallingIdentity();
7453            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7454            if (taskId >= 0) {
7455                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7456            }
7457            Binder.restoreCallingIdentity(origId);
7458        }
7459        return false;
7460    }
7461
7462    @Override
7463    public void moveTaskBackwards(int task) {
7464        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7465                "moveTaskBackwards()");
7466
7467        synchronized(this) {
7468            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7469                    Binder.getCallingUid(), "Task backwards")) {
7470                return;
7471            }
7472            final long origId = Binder.clearCallingIdentity();
7473            moveTaskBackwardsLocked(task);
7474            Binder.restoreCallingIdentity(origId);
7475        }
7476    }
7477
7478    private final void moveTaskBackwardsLocked(int task) {
7479        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7480    }
7481
7482    @Override
7483    public IBinder getHomeActivityToken() throws RemoteException {
7484        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7485                "getHomeActivityToken()");
7486        synchronized (this) {
7487            return mStackSupervisor.getHomeActivityToken();
7488        }
7489    }
7490
7491    @Override
7492    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7493            IActivityContainerCallback callback) throws RemoteException {
7494        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7495                "createActivityContainer()");
7496        synchronized (this) {
7497            if (parentActivityToken == null) {
7498                throw new IllegalArgumentException("parent token must not be null");
7499            }
7500            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7501            if (r == null) {
7502                return null;
7503            }
7504            if (callback == null) {
7505                throw new IllegalArgumentException("callback must not be null");
7506            }
7507            return mStackSupervisor.createActivityContainer(r, callback);
7508        }
7509    }
7510
7511    @Override
7512    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7513        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7514                "deleteActivityContainer()");
7515        synchronized (this) {
7516            mStackSupervisor.deleteActivityContainer(container);
7517        }
7518    }
7519
7520    @Override
7521    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7522            throws RemoteException {
7523        synchronized (this) {
7524            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7525            if (stack != null) {
7526                return stack.mActivityContainer;
7527            }
7528            return null;
7529        }
7530    }
7531
7532    @Override
7533    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7534        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7535                "moveTaskToStack()");
7536        if (stackId == HOME_STACK_ID) {
7537            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7538                    new RuntimeException("here").fillInStackTrace());
7539        }
7540        synchronized (this) {
7541            long ident = Binder.clearCallingIdentity();
7542            try {
7543                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7544                        + stackId + " toTop=" + toTop);
7545                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7546            } finally {
7547                Binder.restoreCallingIdentity(ident);
7548            }
7549        }
7550    }
7551
7552    @Override
7553    public void resizeStack(int stackBoxId, Rect bounds) {
7554        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7555                "resizeStackBox()");
7556        long ident = Binder.clearCallingIdentity();
7557        try {
7558            mWindowManager.resizeStack(stackBoxId, bounds);
7559        } finally {
7560            Binder.restoreCallingIdentity(ident);
7561        }
7562    }
7563
7564    @Override
7565    public List<StackInfo> getAllStackInfos() {
7566        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7567                "getAllStackInfos()");
7568        long ident = Binder.clearCallingIdentity();
7569        try {
7570            synchronized (this) {
7571                return mStackSupervisor.getAllStackInfosLocked();
7572            }
7573        } finally {
7574            Binder.restoreCallingIdentity(ident);
7575        }
7576    }
7577
7578    @Override
7579    public StackInfo getStackInfo(int stackId) {
7580        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7581                "getStackInfo()");
7582        long ident = Binder.clearCallingIdentity();
7583        try {
7584            synchronized (this) {
7585                return mStackSupervisor.getStackInfoLocked(stackId);
7586            }
7587        } finally {
7588            Binder.restoreCallingIdentity(ident);
7589        }
7590    }
7591
7592    @Override
7593    public boolean isInHomeStack(int taskId) {
7594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7595                "getStackInfo()");
7596        long ident = Binder.clearCallingIdentity();
7597        try {
7598            synchronized (this) {
7599                TaskRecord tr = recentTaskForIdLocked(taskId);
7600                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7601            }
7602        } finally {
7603            Binder.restoreCallingIdentity(ident);
7604        }
7605    }
7606
7607    @Override
7608    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7609        synchronized(this) {
7610            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7611        }
7612    }
7613
7614    private boolean isLockTaskAuthorized(ComponentName name) {
7615        final DevicePolicyManager dpm = (DevicePolicyManager)
7616                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7617        return dpm != null && dpm.isLockTaskPermitted(name);
7618    }
7619
7620    private void startLockTaskMode(TaskRecord task) {
7621        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7622            return;
7623        }
7624        long ident = Binder.clearCallingIdentity();
7625        try {
7626            synchronized (this) {
7627                // Since we lost lock on task, make sure it is still there.
7628                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7629                if (task != null) {
7630                    mStackSupervisor.setLockTaskModeLocked(task);
7631                }
7632            }
7633        } finally {
7634            Binder.restoreCallingIdentity(ident);
7635        }
7636    }
7637
7638    @Override
7639    public void startLockTaskMode(int taskId) {
7640        long ident = Binder.clearCallingIdentity();
7641        try {
7642            final TaskRecord task;
7643            synchronized (this) {
7644                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7645            }
7646            if (task != null) {
7647                startLockTaskMode(task);
7648            }
7649        } finally {
7650            Binder.restoreCallingIdentity(ident);
7651        }
7652    }
7653
7654    @Override
7655    public void startLockTaskMode(IBinder token) {
7656        long ident = Binder.clearCallingIdentity();
7657        try {
7658            final TaskRecord task;
7659            synchronized (this) {
7660                final ActivityRecord r = ActivityRecord.forToken(token);
7661                if (r == null) {
7662                    return;
7663                }
7664                task = r.task;
7665            }
7666            if (task != null) {
7667                startLockTaskMode(task);
7668            }
7669        } finally {
7670            Binder.restoreCallingIdentity(ident);
7671        }
7672    }
7673
7674    @Override
7675    public void stopLockTaskMode() {
7676        // Check if the calling task is eligible to use lock task
7677        final int uid = Binder.getCallingUid();
7678        try {
7679            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7680            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7681                return;
7682            }
7683        } catch (RemoteException e) {
7684            Log.d(TAG, "stopLockTaskMode " + e);
7685            return;
7686        }
7687        // Stop lock task
7688        synchronized (this) {
7689            mStackSupervisor.setLockTaskModeLocked(null);
7690        }
7691    }
7692
7693    @Override
7694    public boolean isInLockTaskMode() {
7695        synchronized (this) {
7696            return mStackSupervisor.isInLockTaskMode();
7697        }
7698    }
7699
7700    // =========================================================
7701    // CONTENT PROVIDERS
7702    // =========================================================
7703
7704    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7705        List<ProviderInfo> providers = null;
7706        try {
7707            providers = AppGlobals.getPackageManager().
7708                queryContentProviders(app.processName, app.uid,
7709                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7710        } catch (RemoteException ex) {
7711        }
7712        if (DEBUG_MU)
7713            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7714        int userId = app.userId;
7715        if (providers != null) {
7716            int N = providers.size();
7717            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7718            for (int i=0; i<N; i++) {
7719                ProviderInfo cpi =
7720                    (ProviderInfo)providers.get(i);
7721                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7722                        cpi.name, cpi.flags);
7723                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7724                    // This is a singleton provider, but a user besides the
7725                    // default user is asking to initialize a process it runs
7726                    // in...  well, no, it doesn't actually run in this process,
7727                    // it runs in the process of the default user.  Get rid of it.
7728                    providers.remove(i);
7729                    N--;
7730                    i--;
7731                    continue;
7732                }
7733
7734                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7735                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7736                if (cpr == null) {
7737                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7738                    mProviderMap.putProviderByClass(comp, cpr);
7739                }
7740                if (DEBUG_MU)
7741                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7742                app.pubProviders.put(cpi.name, cpr);
7743                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7744                    // Don't add this if it is a platform component that is marked
7745                    // to run in multiple processes, because this is actually
7746                    // part of the framework so doesn't make sense to track as a
7747                    // separate apk in the process.
7748                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7749                }
7750                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7751            }
7752        }
7753        return providers;
7754    }
7755
7756    /**
7757     * Check if {@link ProcessRecord} has a possible chance at accessing the
7758     * given {@link ProviderInfo}. Final permission checking is always done
7759     * in {@link ContentProvider}.
7760     */
7761    private final String checkContentProviderPermissionLocked(
7762            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7763        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7764        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7765        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7766        // Looking for cross-user grants before to enforce the typical cross-users permissions
7767        if (userId != UserHandle.getUserId(callingUid)) {
7768            if (perms != null) {
7769                for (GrantUri grantUri : perms.keySet()) {
7770                    if (grantUri.sourceUserId == userId) {
7771                        String authority = grantUri.uri.getAuthority();
7772                        if (authority.equals(cpi.authority)) {
7773                            return null;
7774                        }
7775                    }
7776                }
7777            }
7778        }
7779        if (checkUser) {
7780            userId = handleIncomingUser(callingPid, callingUid, userId,
7781                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7782        }
7783        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7784                cpi.applicationInfo.uid, cpi.exported)
7785                == PackageManager.PERMISSION_GRANTED) {
7786            return null;
7787        }
7788        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7789                cpi.applicationInfo.uid, cpi.exported)
7790                == PackageManager.PERMISSION_GRANTED) {
7791            return null;
7792        }
7793
7794        PathPermission[] pps = cpi.pathPermissions;
7795        if (pps != null) {
7796            int i = pps.length;
7797            while (i > 0) {
7798                i--;
7799                PathPermission pp = pps[i];
7800                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7801                        cpi.applicationInfo.uid, cpi.exported)
7802                        == PackageManager.PERMISSION_GRANTED) {
7803                    return null;
7804                }
7805                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7806                        cpi.applicationInfo.uid, cpi.exported)
7807                        == PackageManager.PERMISSION_GRANTED) {
7808                    return null;
7809                }
7810            }
7811        }
7812
7813        if (perms != null) {
7814            for (GrantUri grantUri : perms.keySet()) {
7815                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7816                    return null;
7817                }
7818            }
7819        }
7820
7821        String msg;
7822        if (!cpi.exported) {
7823            msg = "Permission Denial: opening provider " + cpi.name
7824                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7825                    + ", uid=" + callingUid + ") that is not exported from uid "
7826                    + cpi.applicationInfo.uid;
7827        } else {
7828            msg = "Permission Denial: opening provider " + cpi.name
7829                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7830                    + ", uid=" + callingUid + ") requires "
7831                    + cpi.readPermission + " or " + cpi.writePermission;
7832        }
7833        Slog.w(TAG, msg);
7834        return msg;
7835    }
7836
7837    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7838            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7839        if (r != null) {
7840            for (int i=0; i<r.conProviders.size(); i++) {
7841                ContentProviderConnection conn = r.conProviders.get(i);
7842                if (conn.provider == cpr) {
7843                    if (DEBUG_PROVIDER) Slog.v(TAG,
7844                            "Adding provider requested by "
7845                            + r.processName + " from process "
7846                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7847                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7848                    if (stable) {
7849                        conn.stableCount++;
7850                        conn.numStableIncs++;
7851                    } else {
7852                        conn.unstableCount++;
7853                        conn.numUnstableIncs++;
7854                    }
7855                    return conn;
7856                }
7857            }
7858            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7859            if (stable) {
7860                conn.stableCount = 1;
7861                conn.numStableIncs = 1;
7862            } else {
7863                conn.unstableCount = 1;
7864                conn.numUnstableIncs = 1;
7865            }
7866            cpr.connections.add(conn);
7867            r.conProviders.add(conn);
7868            return conn;
7869        }
7870        cpr.addExternalProcessHandleLocked(externalProcessToken);
7871        return null;
7872    }
7873
7874    boolean decProviderCountLocked(ContentProviderConnection conn,
7875            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7876        if (conn != null) {
7877            cpr = conn.provider;
7878            if (DEBUG_PROVIDER) Slog.v(TAG,
7879                    "Removing provider requested by "
7880                    + conn.client.processName + " from process "
7881                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7882                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7883            if (stable) {
7884                conn.stableCount--;
7885            } else {
7886                conn.unstableCount--;
7887            }
7888            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7889                cpr.connections.remove(conn);
7890                conn.client.conProviders.remove(conn);
7891                return true;
7892            }
7893            return false;
7894        }
7895        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7896        return false;
7897    }
7898
7899    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7900            String name, IBinder token, boolean stable, int userId) {
7901        ContentProviderRecord cpr;
7902        ContentProviderConnection conn = null;
7903        ProviderInfo cpi = null;
7904
7905        synchronized(this) {
7906            ProcessRecord r = null;
7907            if (caller != null) {
7908                r = getRecordForAppLocked(caller);
7909                if (r == null) {
7910                    throw new SecurityException(
7911                            "Unable to find app for caller " + caller
7912                          + " (pid=" + Binder.getCallingPid()
7913                          + ") when getting content provider " + name);
7914                }
7915            }
7916
7917            boolean checkCrossUser = true;
7918
7919            // First check if this content provider has been published...
7920            cpr = mProviderMap.getProviderByName(name, userId);
7921            // If that didn't work, check if it exists for user 0 and then
7922            // verify that it's a singleton provider before using it.
7923            if (cpr == null && userId != UserHandle.USER_OWNER) {
7924                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
7925                if (cpr != null) {
7926                    cpi = cpr.info;
7927                    if (isSingleton(cpi.processName, cpi.applicationInfo,
7928                            cpi.name, cpi.flags)
7929                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
7930                        userId = UserHandle.USER_OWNER;
7931                        checkCrossUser = false;
7932                    } else {
7933                        cpr = null;
7934                        cpi = null;
7935                    }
7936                }
7937            }
7938
7939            boolean providerRunning = cpr != null;
7940            if (providerRunning) {
7941                cpi = cpr.info;
7942                String msg;
7943                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
7944                        != null) {
7945                    throw new SecurityException(msg);
7946                }
7947
7948                if (r != null && cpr.canRunHere(r)) {
7949                    // This provider has been published or is in the process
7950                    // of being published...  but it is also allowed to run
7951                    // in the caller's process, so don't make a connection
7952                    // and just let the caller instantiate its own instance.
7953                    ContentProviderHolder holder = cpr.newHolder(null);
7954                    // don't give caller the provider object, it needs
7955                    // to make its own.
7956                    holder.provider = null;
7957                    return holder;
7958                }
7959
7960                final long origId = Binder.clearCallingIdentity();
7961
7962                // In this case the provider instance already exists, so we can
7963                // return it right away.
7964                conn = incProviderCountLocked(r, cpr, token, stable);
7965                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7966                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7967                        // If this is a perceptible app accessing the provider,
7968                        // make sure to count it as being accessed and thus
7969                        // back up on the LRU list.  This is good because
7970                        // content providers are often expensive to start.
7971                        updateLruProcessLocked(cpr.proc, false, null);
7972                    }
7973                }
7974
7975                if (cpr.proc != null) {
7976                    if (false) {
7977                        if (cpr.name.flattenToShortString().equals(
7978                                "com.android.providers.calendar/.CalendarProvider2")) {
7979                            Slog.v(TAG, "****************** KILLING "
7980                                + cpr.name.flattenToShortString());
7981                            Process.killProcess(cpr.proc.pid);
7982                        }
7983                    }
7984                    boolean success = updateOomAdjLocked(cpr.proc);
7985                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7986                    // NOTE: there is still a race here where a signal could be
7987                    // pending on the process even though we managed to update its
7988                    // adj level.  Not sure what to do about this, but at least
7989                    // the race is now smaller.
7990                    if (!success) {
7991                        // Uh oh...  it looks like the provider's process
7992                        // has been killed on us.  We need to wait for a new
7993                        // process to be started, and make sure its death
7994                        // doesn't kill our process.
7995                        Slog.i(TAG,
7996                                "Existing provider " + cpr.name.flattenToShortString()
7997                                + " is crashing; detaching " + r);
7998                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7999                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8000                        if (!lastRef) {
8001                            // This wasn't the last ref our process had on
8002                            // the provider...  we have now been killed, bail.
8003                            return null;
8004                        }
8005                        providerRunning = false;
8006                        conn = null;
8007                    }
8008                }
8009
8010                Binder.restoreCallingIdentity(origId);
8011            }
8012
8013            boolean singleton;
8014            if (!providerRunning) {
8015                try {
8016                    cpi = AppGlobals.getPackageManager().
8017                        resolveContentProvider(name,
8018                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8019                } catch (RemoteException ex) {
8020                }
8021                if (cpi == null) {
8022                    return null;
8023                }
8024                // If the provider is a singleton AND
8025                // (it's a call within the same user || the provider is a
8026                // privileged app)
8027                // Then allow connecting to the singleton provider
8028                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8029                        cpi.name, cpi.flags)
8030                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8031                if (singleton) {
8032                    userId = UserHandle.USER_OWNER;
8033                }
8034                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8035
8036                String msg;
8037                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8038                        != null) {
8039                    throw new SecurityException(msg);
8040                }
8041
8042                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8043                        && !cpi.processName.equals("system")) {
8044                    // If this content provider does not run in the system
8045                    // process, and the system is not yet ready to run other
8046                    // processes, then fail fast instead of hanging.
8047                    throw new IllegalArgumentException(
8048                            "Attempt to launch content provider before system ready");
8049                }
8050
8051                // Make sure that the user who owns this provider is started.  If not,
8052                // we don't want to allow it to run.
8053                if (mStartedUsers.get(userId) == null) {
8054                    Slog.w(TAG, "Unable to launch app "
8055                            + cpi.applicationInfo.packageName + "/"
8056                            + cpi.applicationInfo.uid + " for provider "
8057                            + name + ": user " + userId + " is stopped");
8058                    return null;
8059                }
8060
8061                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8062                cpr = mProviderMap.getProviderByClass(comp, userId);
8063                final boolean firstClass = cpr == null;
8064                if (firstClass) {
8065                    try {
8066                        ApplicationInfo ai =
8067                            AppGlobals.getPackageManager().
8068                                getApplicationInfo(
8069                                        cpi.applicationInfo.packageName,
8070                                        STOCK_PM_FLAGS, userId);
8071                        if (ai == null) {
8072                            Slog.w(TAG, "No package info for content provider "
8073                                    + cpi.name);
8074                            return null;
8075                        }
8076                        ai = getAppInfoForUser(ai, userId);
8077                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8078                    } catch (RemoteException ex) {
8079                        // pm is in same process, this will never happen.
8080                    }
8081                }
8082
8083                if (r != null && cpr.canRunHere(r)) {
8084                    // If this is a multiprocess provider, then just return its
8085                    // info and allow the caller to instantiate it.  Only do
8086                    // this if the provider is the same user as the caller's
8087                    // process, or can run as root (so can be in any process).
8088                    return cpr.newHolder(null);
8089                }
8090
8091                if (DEBUG_PROVIDER) {
8092                    RuntimeException e = new RuntimeException("here");
8093                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8094                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8095                }
8096
8097                // This is single process, and our app is now connecting to it.
8098                // See if we are already in the process of launching this
8099                // provider.
8100                final int N = mLaunchingProviders.size();
8101                int i;
8102                for (i=0; i<N; i++) {
8103                    if (mLaunchingProviders.get(i) == cpr) {
8104                        break;
8105                    }
8106                }
8107
8108                // If the provider is not already being launched, then get it
8109                // started.
8110                if (i >= N) {
8111                    final long origId = Binder.clearCallingIdentity();
8112
8113                    try {
8114                        // Content provider is now in use, its package can't be stopped.
8115                        try {
8116                            AppGlobals.getPackageManager().setPackageStoppedState(
8117                                    cpr.appInfo.packageName, false, userId);
8118                        } catch (RemoteException e) {
8119                        } catch (IllegalArgumentException e) {
8120                            Slog.w(TAG, "Failed trying to unstop package "
8121                                    + cpr.appInfo.packageName + ": " + e);
8122                        }
8123
8124                        // Use existing process if already started
8125                        ProcessRecord proc = getProcessRecordLocked(
8126                                cpi.processName, cpr.appInfo.uid, false);
8127                        if (proc != null && proc.thread != null) {
8128                            if (DEBUG_PROVIDER) {
8129                                Slog.d(TAG, "Installing in existing process " + proc);
8130                            }
8131                            proc.pubProviders.put(cpi.name, cpr);
8132                            try {
8133                                proc.thread.scheduleInstallProvider(cpi);
8134                            } catch (RemoteException e) {
8135                            }
8136                        } else {
8137                            proc = startProcessLocked(cpi.processName,
8138                                    cpr.appInfo, false, 0, "content provider",
8139                                    new ComponentName(cpi.applicationInfo.packageName,
8140                                            cpi.name), false, false, false);
8141                            if (proc == null) {
8142                                Slog.w(TAG, "Unable to launch app "
8143                                        + cpi.applicationInfo.packageName + "/"
8144                                        + cpi.applicationInfo.uid + " for provider "
8145                                        + name + ": process is bad");
8146                                return null;
8147                            }
8148                        }
8149                        cpr.launchingApp = proc;
8150                        mLaunchingProviders.add(cpr);
8151                    } finally {
8152                        Binder.restoreCallingIdentity(origId);
8153                    }
8154                }
8155
8156                // Make sure the provider is published (the same provider class
8157                // may be published under multiple names).
8158                if (firstClass) {
8159                    mProviderMap.putProviderByClass(comp, cpr);
8160                }
8161
8162                mProviderMap.putProviderByName(name, cpr);
8163                conn = incProviderCountLocked(r, cpr, token, stable);
8164                if (conn != null) {
8165                    conn.waiting = true;
8166                }
8167            }
8168        }
8169
8170        // Wait for the provider to be published...
8171        synchronized (cpr) {
8172            while (cpr.provider == null) {
8173                if (cpr.launchingApp == null) {
8174                    Slog.w(TAG, "Unable to launch app "
8175                            + cpi.applicationInfo.packageName + "/"
8176                            + cpi.applicationInfo.uid + " for provider "
8177                            + name + ": launching app became null");
8178                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8179                            UserHandle.getUserId(cpi.applicationInfo.uid),
8180                            cpi.applicationInfo.packageName,
8181                            cpi.applicationInfo.uid, name);
8182                    return null;
8183                }
8184                try {
8185                    if (DEBUG_MU) {
8186                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8187                                + cpr.launchingApp);
8188                    }
8189                    if (conn != null) {
8190                        conn.waiting = true;
8191                    }
8192                    cpr.wait();
8193                } catch (InterruptedException ex) {
8194                } finally {
8195                    if (conn != null) {
8196                        conn.waiting = false;
8197                    }
8198                }
8199            }
8200        }
8201        return cpr != null ? cpr.newHolder(conn) : null;
8202    }
8203
8204    @Override
8205    public final ContentProviderHolder getContentProvider(
8206            IApplicationThread caller, String name, int userId, boolean stable) {
8207        enforceNotIsolatedCaller("getContentProvider");
8208        if (caller == null) {
8209            String msg = "null IApplicationThread when getting content provider "
8210                    + name;
8211            Slog.w(TAG, msg);
8212            throw new SecurityException(msg);
8213        }
8214        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8215        // with cross-user grant.
8216        return getContentProviderImpl(caller, name, null, stable, userId);
8217    }
8218
8219    public ContentProviderHolder getContentProviderExternal(
8220            String name, int userId, IBinder token) {
8221        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8222            "Do not have permission in call getContentProviderExternal()");
8223        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8224                false, true, "getContentProvider", null);
8225        return getContentProviderExternalUnchecked(name, token, userId);
8226    }
8227
8228    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8229            IBinder token, int userId) {
8230        return getContentProviderImpl(null, name, token, true, userId);
8231    }
8232
8233    /**
8234     * Drop a content provider from a ProcessRecord's bookkeeping
8235     */
8236    public void removeContentProvider(IBinder connection, boolean stable) {
8237        enforceNotIsolatedCaller("removeContentProvider");
8238        long ident = Binder.clearCallingIdentity();
8239        try {
8240            synchronized (this) {
8241                ContentProviderConnection conn;
8242                try {
8243                    conn = (ContentProviderConnection)connection;
8244                } catch (ClassCastException e) {
8245                    String msg ="removeContentProvider: " + connection
8246                            + " not a ContentProviderConnection";
8247                    Slog.w(TAG, msg);
8248                    throw new IllegalArgumentException(msg);
8249                }
8250                if (conn == null) {
8251                    throw new NullPointerException("connection is null");
8252                }
8253                if (decProviderCountLocked(conn, null, null, stable)) {
8254                    updateOomAdjLocked();
8255                }
8256            }
8257        } finally {
8258            Binder.restoreCallingIdentity(ident);
8259        }
8260    }
8261
8262    public void removeContentProviderExternal(String name, IBinder token) {
8263        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8264            "Do not have permission in call removeContentProviderExternal()");
8265        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8266    }
8267
8268    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8269        synchronized (this) {
8270            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8271            if(cpr == null) {
8272                //remove from mProvidersByClass
8273                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8274                return;
8275            }
8276
8277            //update content provider record entry info
8278            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8279            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8280            if (localCpr.hasExternalProcessHandles()) {
8281                if (localCpr.removeExternalProcessHandleLocked(token)) {
8282                    updateOomAdjLocked();
8283                } else {
8284                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8285                            + " with no external reference for token: "
8286                            + token + ".");
8287                }
8288            } else {
8289                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8290                        + " with no external references.");
8291            }
8292        }
8293    }
8294
8295    public final void publishContentProviders(IApplicationThread caller,
8296            List<ContentProviderHolder> providers) {
8297        if (providers == null) {
8298            return;
8299        }
8300
8301        enforceNotIsolatedCaller("publishContentProviders");
8302        synchronized (this) {
8303            final ProcessRecord r = getRecordForAppLocked(caller);
8304            if (DEBUG_MU)
8305                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8306            if (r == null) {
8307                throw new SecurityException(
8308                        "Unable to find app for caller " + caller
8309                      + " (pid=" + Binder.getCallingPid()
8310                      + ") when publishing content providers");
8311            }
8312
8313            final long origId = Binder.clearCallingIdentity();
8314
8315            final int N = providers.size();
8316            for (int i=0; i<N; i++) {
8317                ContentProviderHolder src = providers.get(i);
8318                if (src == null || src.info == null || src.provider == null) {
8319                    continue;
8320                }
8321                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8322                if (DEBUG_MU)
8323                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8324                if (dst != null) {
8325                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8326                    mProviderMap.putProviderByClass(comp, dst);
8327                    String names[] = dst.info.authority.split(";");
8328                    for (int j = 0; j < names.length; j++) {
8329                        mProviderMap.putProviderByName(names[j], dst);
8330                    }
8331
8332                    int NL = mLaunchingProviders.size();
8333                    int j;
8334                    for (j=0; j<NL; j++) {
8335                        if (mLaunchingProviders.get(j) == dst) {
8336                            mLaunchingProviders.remove(j);
8337                            j--;
8338                            NL--;
8339                        }
8340                    }
8341                    synchronized (dst) {
8342                        dst.provider = src.provider;
8343                        dst.proc = r;
8344                        dst.notifyAll();
8345                    }
8346                    updateOomAdjLocked(r);
8347                }
8348            }
8349
8350            Binder.restoreCallingIdentity(origId);
8351        }
8352    }
8353
8354    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8355        ContentProviderConnection conn;
8356        try {
8357            conn = (ContentProviderConnection)connection;
8358        } catch (ClassCastException e) {
8359            String msg ="refContentProvider: " + connection
8360                    + " not a ContentProviderConnection";
8361            Slog.w(TAG, msg);
8362            throw new IllegalArgumentException(msg);
8363        }
8364        if (conn == null) {
8365            throw new NullPointerException("connection is null");
8366        }
8367
8368        synchronized (this) {
8369            if (stable > 0) {
8370                conn.numStableIncs += stable;
8371            }
8372            stable = conn.stableCount + stable;
8373            if (stable < 0) {
8374                throw new IllegalStateException("stableCount < 0: " + stable);
8375            }
8376
8377            if (unstable > 0) {
8378                conn.numUnstableIncs += unstable;
8379            }
8380            unstable = conn.unstableCount + unstable;
8381            if (unstable < 0) {
8382                throw new IllegalStateException("unstableCount < 0: " + unstable);
8383            }
8384
8385            if ((stable+unstable) <= 0) {
8386                throw new IllegalStateException("ref counts can't go to zero here: stable="
8387                        + stable + " unstable=" + unstable);
8388            }
8389            conn.stableCount = stable;
8390            conn.unstableCount = unstable;
8391            return !conn.dead;
8392        }
8393    }
8394
8395    public void unstableProviderDied(IBinder connection) {
8396        ContentProviderConnection conn;
8397        try {
8398            conn = (ContentProviderConnection)connection;
8399        } catch (ClassCastException e) {
8400            String msg ="refContentProvider: " + connection
8401                    + " not a ContentProviderConnection";
8402            Slog.w(TAG, msg);
8403            throw new IllegalArgumentException(msg);
8404        }
8405        if (conn == null) {
8406            throw new NullPointerException("connection is null");
8407        }
8408
8409        // Safely retrieve the content provider associated with the connection.
8410        IContentProvider provider;
8411        synchronized (this) {
8412            provider = conn.provider.provider;
8413        }
8414
8415        if (provider == null) {
8416            // Um, yeah, we're way ahead of you.
8417            return;
8418        }
8419
8420        // Make sure the caller is being honest with us.
8421        if (provider.asBinder().pingBinder()) {
8422            // Er, no, still looks good to us.
8423            synchronized (this) {
8424                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8425                        + " says " + conn + " died, but we don't agree");
8426                return;
8427            }
8428        }
8429
8430        // Well look at that!  It's dead!
8431        synchronized (this) {
8432            if (conn.provider.provider != provider) {
8433                // But something changed...  good enough.
8434                return;
8435            }
8436
8437            ProcessRecord proc = conn.provider.proc;
8438            if (proc == null || proc.thread == null) {
8439                // Seems like the process is already cleaned up.
8440                return;
8441            }
8442
8443            // As far as we're concerned, this is just like receiving a
8444            // death notification...  just a bit prematurely.
8445            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8446                    + ") early provider death");
8447            final long ident = Binder.clearCallingIdentity();
8448            try {
8449                appDiedLocked(proc, proc.pid, proc.thread);
8450            } finally {
8451                Binder.restoreCallingIdentity(ident);
8452            }
8453        }
8454    }
8455
8456    @Override
8457    public void appNotRespondingViaProvider(IBinder connection) {
8458        enforceCallingPermission(
8459                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8460
8461        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8462        if (conn == null) {
8463            Slog.w(TAG, "ContentProviderConnection is null");
8464            return;
8465        }
8466
8467        final ProcessRecord host = conn.provider.proc;
8468        if (host == null) {
8469            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8470            return;
8471        }
8472
8473        final long token = Binder.clearCallingIdentity();
8474        try {
8475            appNotResponding(host, null, null, false, "ContentProvider not responding");
8476        } finally {
8477            Binder.restoreCallingIdentity(token);
8478        }
8479    }
8480
8481    public final void installSystemProviders() {
8482        List<ProviderInfo> providers;
8483        synchronized (this) {
8484            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8485            providers = generateApplicationProvidersLocked(app);
8486            if (providers != null) {
8487                for (int i=providers.size()-1; i>=0; i--) {
8488                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8489                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8490                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8491                                + ": not system .apk");
8492                        providers.remove(i);
8493                    }
8494                }
8495            }
8496        }
8497        if (providers != null) {
8498            mSystemThread.installSystemProviders(providers);
8499        }
8500
8501        mCoreSettingsObserver = new CoreSettingsObserver(this);
8502
8503        mUsageStatsService.monitorPackages();
8504    }
8505
8506    /**
8507     * Allows app to retrieve the MIME type of a URI without having permission
8508     * to access its content provider.
8509     *
8510     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8511     *
8512     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8513     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8514     */
8515    public String getProviderMimeType(Uri uri, int userId) {
8516        enforceNotIsolatedCaller("getProviderMimeType");
8517        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8518                userId, false, true, "getProviderMimeType", null);
8519        final String name = uri.getAuthority();
8520        final long ident = Binder.clearCallingIdentity();
8521        ContentProviderHolder holder = null;
8522
8523        try {
8524            holder = getContentProviderExternalUnchecked(name, null, userId);
8525            if (holder != null) {
8526                return holder.provider.getType(uri);
8527            }
8528        } catch (RemoteException e) {
8529            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8530            return null;
8531        } finally {
8532            if (holder != null) {
8533                removeContentProviderExternalUnchecked(name, null, userId);
8534            }
8535            Binder.restoreCallingIdentity(ident);
8536        }
8537
8538        return null;
8539    }
8540
8541    // =========================================================
8542    // GLOBAL MANAGEMENT
8543    // =========================================================
8544
8545    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8546            boolean isolated) {
8547        String proc = customProcess != null ? customProcess : info.processName;
8548        BatteryStatsImpl.Uid.Proc ps = null;
8549        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8550        int uid = info.uid;
8551        if (isolated) {
8552            int userId = UserHandle.getUserId(uid);
8553            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8554            while (true) {
8555                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8556                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8557                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8558                }
8559                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8560                mNextIsolatedProcessUid++;
8561                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8562                    // No process for this uid, use it.
8563                    break;
8564                }
8565                stepsLeft--;
8566                if (stepsLeft <= 0) {
8567                    return null;
8568                }
8569            }
8570        }
8571        return new ProcessRecord(stats, info, proc, uid);
8572    }
8573
8574    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8575            String abiOverride) {
8576        ProcessRecord app;
8577        if (!isolated) {
8578            app = getProcessRecordLocked(info.processName, info.uid, true);
8579        } else {
8580            app = null;
8581        }
8582
8583        if (app == null) {
8584            app = newProcessRecordLocked(info, null, isolated);
8585            mProcessNames.put(info.processName, app.uid, app);
8586            if (isolated) {
8587                mIsolatedProcesses.put(app.uid, app);
8588            }
8589            updateLruProcessLocked(app, false, null);
8590            updateOomAdjLocked();
8591        }
8592
8593        // This package really, really can not be stopped.
8594        try {
8595            AppGlobals.getPackageManager().setPackageStoppedState(
8596                    info.packageName, false, UserHandle.getUserId(app.uid));
8597        } catch (RemoteException e) {
8598        } catch (IllegalArgumentException e) {
8599            Slog.w(TAG, "Failed trying to unstop package "
8600                    + info.packageName + ": " + e);
8601        }
8602
8603        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8604                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8605            app.persistent = true;
8606            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8607        }
8608        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8609            mPersistentStartingProcesses.add(app);
8610            startProcessLocked(app, "added application", app.processName,
8611                    abiOverride);
8612        }
8613
8614        return app;
8615    }
8616
8617    public void unhandledBack() {
8618        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8619                "unhandledBack()");
8620
8621        synchronized(this) {
8622            final long origId = Binder.clearCallingIdentity();
8623            try {
8624                getFocusedStack().unhandledBackLocked();
8625            } finally {
8626                Binder.restoreCallingIdentity(origId);
8627            }
8628        }
8629    }
8630
8631    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8632        enforceNotIsolatedCaller("openContentUri");
8633        final int userId = UserHandle.getCallingUserId();
8634        String name = uri.getAuthority();
8635        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8636        ParcelFileDescriptor pfd = null;
8637        if (cph != null) {
8638            // We record the binder invoker's uid in thread-local storage before
8639            // going to the content provider to open the file.  Later, in the code
8640            // that handles all permissions checks, we look for this uid and use
8641            // that rather than the Activity Manager's own uid.  The effect is that
8642            // we do the check against the caller's permissions even though it looks
8643            // to the content provider like the Activity Manager itself is making
8644            // the request.
8645            sCallerIdentity.set(new Identity(
8646                    Binder.getCallingPid(), Binder.getCallingUid()));
8647            try {
8648                pfd = cph.provider.openFile(null, uri, "r", null);
8649            } catch (FileNotFoundException e) {
8650                // do nothing; pfd will be returned null
8651            } finally {
8652                // Ensure that whatever happens, we clean up the identity state
8653                sCallerIdentity.remove();
8654            }
8655
8656            // We've got the fd now, so we're done with the provider.
8657            removeContentProviderExternalUnchecked(name, null, userId);
8658        } else {
8659            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8660        }
8661        return pfd;
8662    }
8663
8664    // Actually is sleeping or shutting down or whatever else in the future
8665    // is an inactive state.
8666    public boolean isSleepingOrShuttingDown() {
8667        return mSleeping || mShuttingDown;
8668    }
8669
8670    public boolean isSleeping() {
8671        return mSleeping;
8672    }
8673
8674    void goingToSleep() {
8675        synchronized(this) {
8676            mWentToSleep = true;
8677            updateEventDispatchingLocked();
8678            goToSleepIfNeededLocked();
8679        }
8680    }
8681
8682    void finishRunningVoiceLocked() {
8683        if (mRunningVoice) {
8684            mRunningVoice = false;
8685            goToSleepIfNeededLocked();
8686        }
8687    }
8688
8689    void goToSleepIfNeededLocked() {
8690        if (mWentToSleep && !mRunningVoice) {
8691            if (!mSleeping) {
8692                mSleeping = true;
8693                mStackSupervisor.goingToSleepLocked();
8694
8695                // Initialize the wake times of all processes.
8696                checkExcessivePowerUsageLocked(false);
8697                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8698                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8699                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8700            }
8701        }
8702    }
8703
8704    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8705        mTaskPersister.notify(task, flush);
8706    }
8707
8708    @Override
8709    public boolean shutdown(int timeout) {
8710        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8711                != PackageManager.PERMISSION_GRANTED) {
8712            throw new SecurityException("Requires permission "
8713                    + android.Manifest.permission.SHUTDOWN);
8714        }
8715
8716        boolean timedout = false;
8717
8718        synchronized(this) {
8719            mShuttingDown = true;
8720            updateEventDispatchingLocked();
8721            timedout = mStackSupervisor.shutdownLocked(timeout);
8722        }
8723
8724        mAppOpsService.shutdown();
8725        mUsageStatsService.shutdown();
8726        mBatteryStatsService.shutdown();
8727        synchronized (this) {
8728            mProcessStats.shutdownLocked();
8729        }
8730        notifyTaskPersisterLocked(null, true);
8731
8732        return timedout;
8733    }
8734
8735    public final void activitySlept(IBinder token) {
8736        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8737
8738        final long origId = Binder.clearCallingIdentity();
8739
8740        synchronized (this) {
8741            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8742            if (r != null) {
8743                mStackSupervisor.activitySleptLocked(r);
8744            }
8745        }
8746
8747        Binder.restoreCallingIdentity(origId);
8748    }
8749
8750    void logLockScreen(String msg) {
8751        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8752                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8753                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8754                mStackSupervisor.mDismissKeyguardOnNextActivity);
8755    }
8756
8757    private void comeOutOfSleepIfNeededLocked() {
8758        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8759            if (mSleeping) {
8760                mSleeping = false;
8761                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8762            }
8763        }
8764    }
8765
8766    void wakingUp() {
8767        synchronized(this) {
8768            mWentToSleep = false;
8769            updateEventDispatchingLocked();
8770            comeOutOfSleepIfNeededLocked();
8771        }
8772    }
8773
8774    void startRunningVoiceLocked() {
8775        if (!mRunningVoice) {
8776            mRunningVoice = true;
8777            comeOutOfSleepIfNeededLocked();
8778        }
8779    }
8780
8781    private void updateEventDispatchingLocked() {
8782        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8783    }
8784
8785    public void setLockScreenShown(boolean shown) {
8786        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8787                != PackageManager.PERMISSION_GRANTED) {
8788            throw new SecurityException("Requires permission "
8789                    + android.Manifest.permission.DEVICE_POWER);
8790        }
8791
8792        synchronized(this) {
8793            long ident = Binder.clearCallingIdentity();
8794            try {
8795                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8796                mLockScreenShown = shown;
8797                comeOutOfSleepIfNeededLocked();
8798            } finally {
8799                Binder.restoreCallingIdentity(ident);
8800            }
8801        }
8802    }
8803
8804    public void stopAppSwitches() {
8805        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8806                != PackageManager.PERMISSION_GRANTED) {
8807            throw new SecurityException("Requires permission "
8808                    + android.Manifest.permission.STOP_APP_SWITCHES);
8809        }
8810
8811        synchronized(this) {
8812            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8813                    + APP_SWITCH_DELAY_TIME;
8814            mDidAppSwitch = false;
8815            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8816            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8817            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8818        }
8819    }
8820
8821    public void resumeAppSwitches() {
8822        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8823                != PackageManager.PERMISSION_GRANTED) {
8824            throw new SecurityException("Requires permission "
8825                    + android.Manifest.permission.STOP_APP_SWITCHES);
8826        }
8827
8828        synchronized(this) {
8829            // Note that we don't execute any pending app switches... we will
8830            // let those wait until either the timeout, or the next start
8831            // activity request.
8832            mAppSwitchesAllowedTime = 0;
8833        }
8834    }
8835
8836    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8837            String name) {
8838        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8839            return true;
8840        }
8841
8842        final int perm = checkComponentPermission(
8843                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8844                callingUid, -1, true);
8845        if (perm == PackageManager.PERMISSION_GRANTED) {
8846            return true;
8847        }
8848
8849        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8850        return false;
8851    }
8852
8853    public void setDebugApp(String packageName, boolean waitForDebugger,
8854            boolean persistent) {
8855        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8856                "setDebugApp()");
8857
8858        long ident = Binder.clearCallingIdentity();
8859        try {
8860            // Note that this is not really thread safe if there are multiple
8861            // callers into it at the same time, but that's not a situation we
8862            // care about.
8863            if (persistent) {
8864                final ContentResolver resolver = mContext.getContentResolver();
8865                Settings.Global.putString(
8866                    resolver, Settings.Global.DEBUG_APP,
8867                    packageName);
8868                Settings.Global.putInt(
8869                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8870                    waitForDebugger ? 1 : 0);
8871            }
8872
8873            synchronized (this) {
8874                if (!persistent) {
8875                    mOrigDebugApp = mDebugApp;
8876                    mOrigWaitForDebugger = mWaitForDebugger;
8877                }
8878                mDebugApp = packageName;
8879                mWaitForDebugger = waitForDebugger;
8880                mDebugTransient = !persistent;
8881                if (packageName != null) {
8882                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8883                            false, UserHandle.USER_ALL, "set debug app");
8884                }
8885            }
8886        } finally {
8887            Binder.restoreCallingIdentity(ident);
8888        }
8889    }
8890
8891    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8892        synchronized (this) {
8893            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8894            if (!isDebuggable) {
8895                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8896                    throw new SecurityException("Process not debuggable: " + app.packageName);
8897                }
8898            }
8899
8900            mOpenGlTraceApp = processName;
8901        }
8902    }
8903
8904    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8905            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8906        synchronized (this) {
8907            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8908            if (!isDebuggable) {
8909                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8910                    throw new SecurityException("Process not debuggable: " + app.packageName);
8911                }
8912            }
8913            mProfileApp = processName;
8914            mProfileFile = profileFile;
8915            if (mProfileFd != null) {
8916                try {
8917                    mProfileFd.close();
8918                } catch (IOException e) {
8919                }
8920                mProfileFd = null;
8921            }
8922            mProfileFd = profileFd;
8923            mProfileType = 0;
8924            mAutoStopProfiler = autoStopProfiler;
8925        }
8926    }
8927
8928    @Override
8929    public void setAlwaysFinish(boolean enabled) {
8930        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8931                "setAlwaysFinish()");
8932
8933        Settings.Global.putInt(
8934                mContext.getContentResolver(),
8935                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8936
8937        synchronized (this) {
8938            mAlwaysFinishActivities = enabled;
8939        }
8940    }
8941
8942    @Override
8943    public void setActivityController(IActivityController controller) {
8944        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8945                "setActivityController()");
8946        synchronized (this) {
8947            mController = controller;
8948            Watchdog.getInstance().setActivityController(controller);
8949        }
8950    }
8951
8952    @Override
8953    public void setUserIsMonkey(boolean userIsMonkey) {
8954        synchronized (this) {
8955            synchronized (mPidsSelfLocked) {
8956                final int callingPid = Binder.getCallingPid();
8957                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8958                if (precessRecord == null) {
8959                    throw new SecurityException("Unknown process: " + callingPid);
8960                }
8961                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8962                    throw new SecurityException("Only an instrumentation process "
8963                            + "with a UiAutomation can call setUserIsMonkey");
8964                }
8965            }
8966            mUserIsMonkey = userIsMonkey;
8967        }
8968    }
8969
8970    @Override
8971    public boolean isUserAMonkey() {
8972        synchronized (this) {
8973            // If there is a controller also implies the user is a monkey.
8974            return (mUserIsMonkey || mController != null);
8975        }
8976    }
8977
8978    public void requestBugReport() {
8979        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8980        SystemProperties.set("ctl.start", "bugreport");
8981    }
8982
8983    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8984        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8985    }
8986
8987    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8988        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8989            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8990        }
8991        return KEY_DISPATCHING_TIMEOUT;
8992    }
8993
8994    @Override
8995    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8996        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8997                != PackageManager.PERMISSION_GRANTED) {
8998            throw new SecurityException("Requires permission "
8999                    + android.Manifest.permission.FILTER_EVENTS);
9000        }
9001        ProcessRecord proc;
9002        long timeout;
9003        synchronized (this) {
9004            synchronized (mPidsSelfLocked) {
9005                proc = mPidsSelfLocked.get(pid);
9006            }
9007            timeout = getInputDispatchingTimeoutLocked(proc);
9008        }
9009
9010        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9011            return -1;
9012        }
9013
9014        return timeout;
9015    }
9016
9017    /**
9018     * Handle input dispatching timeouts.
9019     * Returns whether input dispatching should be aborted or not.
9020     */
9021    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9022            final ActivityRecord activity, final ActivityRecord parent,
9023            final boolean aboveSystem, String reason) {
9024        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9025                != PackageManager.PERMISSION_GRANTED) {
9026            throw new SecurityException("Requires permission "
9027                    + android.Manifest.permission.FILTER_EVENTS);
9028        }
9029
9030        final String annotation;
9031        if (reason == null) {
9032            annotation = "Input dispatching timed out";
9033        } else {
9034            annotation = "Input dispatching timed out (" + reason + ")";
9035        }
9036
9037        if (proc != null) {
9038            synchronized (this) {
9039                if (proc.debugging) {
9040                    return false;
9041                }
9042
9043                if (mDidDexOpt) {
9044                    // Give more time since we were dexopting.
9045                    mDidDexOpt = false;
9046                    return false;
9047                }
9048
9049                if (proc.instrumentationClass != null) {
9050                    Bundle info = new Bundle();
9051                    info.putString("shortMsg", "keyDispatchingTimedOut");
9052                    info.putString("longMsg", annotation);
9053                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9054                    return true;
9055                }
9056            }
9057            mHandler.post(new Runnable() {
9058                @Override
9059                public void run() {
9060                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9061                }
9062            });
9063        }
9064
9065        return true;
9066    }
9067
9068    public Bundle getAssistContextExtras(int requestType) {
9069        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9070                "getAssistContextExtras()");
9071        PendingAssistExtras pae;
9072        Bundle extras = new Bundle();
9073        synchronized (this) {
9074            ActivityRecord activity = getFocusedStack().mResumedActivity;
9075            if (activity == null) {
9076                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9077                return null;
9078            }
9079            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9080            if (activity.app == null || activity.app.thread == null) {
9081                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9082                return extras;
9083            }
9084            if (activity.app.pid == Binder.getCallingPid()) {
9085                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9086                return extras;
9087            }
9088            pae = new PendingAssistExtras(activity);
9089            try {
9090                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9091                        requestType);
9092                mPendingAssistExtras.add(pae);
9093                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9094            } catch (RemoteException e) {
9095                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9096                return extras;
9097            }
9098        }
9099        synchronized (pae) {
9100            while (!pae.haveResult) {
9101                try {
9102                    pae.wait();
9103                } catch (InterruptedException e) {
9104                }
9105            }
9106            if (pae.result != null) {
9107                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9108            }
9109        }
9110        synchronized (this) {
9111            mPendingAssistExtras.remove(pae);
9112            mHandler.removeCallbacks(pae);
9113        }
9114        return extras;
9115    }
9116
9117    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9118        PendingAssistExtras pae = (PendingAssistExtras)token;
9119        synchronized (pae) {
9120            pae.result = extras;
9121            pae.haveResult = true;
9122            pae.notifyAll();
9123        }
9124    }
9125
9126    public void registerProcessObserver(IProcessObserver observer) {
9127        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9128                "registerProcessObserver()");
9129        synchronized (this) {
9130            mProcessObservers.register(observer);
9131        }
9132    }
9133
9134    @Override
9135    public void unregisterProcessObserver(IProcessObserver observer) {
9136        synchronized (this) {
9137            mProcessObservers.unregister(observer);
9138        }
9139    }
9140
9141    @Override
9142    public boolean convertFromTranslucent(IBinder token) {
9143        final long origId = Binder.clearCallingIdentity();
9144        try {
9145            synchronized (this) {
9146                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9147                if (r == null) {
9148                    return false;
9149                }
9150                if (r.changeWindowTranslucency(true)) {
9151                    mWindowManager.setAppFullscreen(token, true);
9152                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9153                    return true;
9154                }
9155                return false;
9156            }
9157        } finally {
9158            Binder.restoreCallingIdentity(origId);
9159        }
9160    }
9161
9162    @Override
9163    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9164        final long origId = Binder.clearCallingIdentity();
9165        try {
9166            synchronized (this) {
9167                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9168                if (r == null) {
9169                    return false;
9170                }
9171                if (r.changeWindowTranslucency(false)) {
9172                    r.task.stack.convertToTranslucent(r, options);
9173                    mWindowManager.setAppFullscreen(token, false);
9174                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9175                    return true;
9176                }
9177                return false;
9178            }
9179        } finally {
9180            Binder.restoreCallingIdentity(origId);
9181        }
9182    }
9183
9184    @Override
9185    public ActivityOptions getActivityOptions(IBinder token) {
9186        final long origId = Binder.clearCallingIdentity();
9187        try {
9188            synchronized (this) {
9189                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9190                if (r != null) {
9191                    final ActivityOptions activityOptions = r.pendingOptions;
9192                    r.pendingOptions = null;
9193                    return activityOptions;
9194                }
9195                return null;
9196            }
9197        } finally {
9198            Binder.restoreCallingIdentity(origId);
9199        }
9200    }
9201
9202    @Override
9203    public void setImmersive(IBinder token, boolean immersive) {
9204        synchronized(this) {
9205            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9206            if (r == null) {
9207                throw new IllegalArgumentException();
9208            }
9209            r.immersive = immersive;
9210
9211            // update associated state if we're frontmost
9212            if (r == mFocusedActivity) {
9213                if (DEBUG_IMMERSIVE) {
9214                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9215                }
9216                applyUpdateLockStateLocked(r);
9217            }
9218        }
9219    }
9220
9221    @Override
9222    public boolean isImmersive(IBinder token) {
9223        synchronized (this) {
9224            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9225            if (r == null) {
9226                throw new IllegalArgumentException();
9227            }
9228            return r.immersive;
9229        }
9230    }
9231
9232    public boolean isTopActivityImmersive() {
9233        enforceNotIsolatedCaller("startActivity");
9234        synchronized (this) {
9235            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9236            return (r != null) ? r.immersive : false;
9237        }
9238    }
9239
9240    public final void enterSafeMode() {
9241        synchronized(this) {
9242            // It only makes sense to do this before the system is ready
9243            // and started launching other packages.
9244            if (!mSystemReady) {
9245                try {
9246                    AppGlobals.getPackageManager().enterSafeMode();
9247                } catch (RemoteException e) {
9248                }
9249            }
9250
9251            mSafeMode = true;
9252        }
9253    }
9254
9255    public final void showSafeModeOverlay() {
9256        View v = LayoutInflater.from(mContext).inflate(
9257                com.android.internal.R.layout.safe_mode, null);
9258        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9259        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9260        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9261        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9262        lp.gravity = Gravity.BOTTOM | Gravity.START;
9263        lp.format = v.getBackground().getOpacity();
9264        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9265                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9266        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9267        ((WindowManager)mContext.getSystemService(
9268                Context.WINDOW_SERVICE)).addView(v, lp);
9269    }
9270
9271    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9272        if (!(sender instanceof PendingIntentRecord)) {
9273            return;
9274        }
9275        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9276        synchronized (stats) {
9277            if (mBatteryStatsService.isOnBattery()) {
9278                mBatteryStatsService.enforceCallingPermission();
9279                PendingIntentRecord rec = (PendingIntentRecord)sender;
9280                int MY_UID = Binder.getCallingUid();
9281                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9282                BatteryStatsImpl.Uid.Pkg pkg =
9283                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9284                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9285                pkg.incWakeupsLocked();
9286            }
9287        }
9288    }
9289
9290    public boolean killPids(int[] pids, String pReason, boolean secure) {
9291        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9292            throw new SecurityException("killPids only available to the system");
9293        }
9294        String reason = (pReason == null) ? "Unknown" : pReason;
9295        // XXX Note: don't acquire main activity lock here, because the window
9296        // manager calls in with its locks held.
9297
9298        boolean killed = false;
9299        synchronized (mPidsSelfLocked) {
9300            int[] types = new int[pids.length];
9301            int worstType = 0;
9302            for (int i=0; i<pids.length; i++) {
9303                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9304                if (proc != null) {
9305                    int type = proc.setAdj;
9306                    types[i] = type;
9307                    if (type > worstType) {
9308                        worstType = type;
9309                    }
9310                }
9311            }
9312
9313            // If the worst oom_adj is somewhere in the cached proc LRU range,
9314            // then constrain it so we will kill all cached procs.
9315            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9316                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9317                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9318            }
9319
9320            // If this is not a secure call, don't let it kill processes that
9321            // are important.
9322            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9323                worstType = ProcessList.SERVICE_ADJ;
9324            }
9325
9326            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9327            for (int i=0; i<pids.length; i++) {
9328                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9329                if (proc == null) {
9330                    continue;
9331                }
9332                int adj = proc.setAdj;
9333                if (adj >= worstType && !proc.killedByAm) {
9334                    killUnneededProcessLocked(proc, reason);
9335                    killed = true;
9336                }
9337            }
9338        }
9339        return killed;
9340    }
9341
9342    @Override
9343    public void killUid(int uid, String reason) {
9344        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9345            throw new SecurityException("killUid only available to the system");
9346        }
9347        synchronized (this) {
9348            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9349                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9350                    reason != null ? reason : "kill uid");
9351        }
9352    }
9353
9354    @Override
9355    public boolean killProcessesBelowForeground(String reason) {
9356        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9357            throw new SecurityException("killProcessesBelowForeground() only available to system");
9358        }
9359
9360        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9361    }
9362
9363    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9364        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9365            throw new SecurityException("killProcessesBelowAdj() only available to system");
9366        }
9367
9368        boolean killed = false;
9369        synchronized (mPidsSelfLocked) {
9370            final int size = mPidsSelfLocked.size();
9371            for (int i = 0; i < size; i++) {
9372                final int pid = mPidsSelfLocked.keyAt(i);
9373                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9374                if (proc == null) continue;
9375
9376                final int adj = proc.setAdj;
9377                if (adj > belowAdj && !proc.killedByAm) {
9378                    killUnneededProcessLocked(proc, reason);
9379                    killed = true;
9380                }
9381            }
9382        }
9383        return killed;
9384    }
9385
9386    @Override
9387    public void hang(final IBinder who, boolean allowRestart) {
9388        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9389                != PackageManager.PERMISSION_GRANTED) {
9390            throw new SecurityException("Requires permission "
9391                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9392        }
9393
9394        final IBinder.DeathRecipient death = new DeathRecipient() {
9395            @Override
9396            public void binderDied() {
9397                synchronized (this) {
9398                    notifyAll();
9399                }
9400            }
9401        };
9402
9403        try {
9404            who.linkToDeath(death, 0);
9405        } catch (RemoteException e) {
9406            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9407            return;
9408        }
9409
9410        synchronized (this) {
9411            Watchdog.getInstance().setAllowRestart(allowRestart);
9412            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9413            synchronized (death) {
9414                while (who.isBinderAlive()) {
9415                    try {
9416                        death.wait();
9417                    } catch (InterruptedException e) {
9418                    }
9419                }
9420            }
9421            Watchdog.getInstance().setAllowRestart(true);
9422        }
9423    }
9424
9425    @Override
9426    public void restart() {
9427        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9428                != PackageManager.PERMISSION_GRANTED) {
9429            throw new SecurityException("Requires permission "
9430                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9431        }
9432
9433        Log.i(TAG, "Sending shutdown broadcast...");
9434
9435        BroadcastReceiver br = new BroadcastReceiver() {
9436            @Override public void onReceive(Context context, Intent intent) {
9437                // Now the broadcast is done, finish up the low-level shutdown.
9438                Log.i(TAG, "Shutting down activity manager...");
9439                shutdown(10000);
9440                Log.i(TAG, "Shutdown complete, restarting!");
9441                Process.killProcess(Process.myPid());
9442                System.exit(10);
9443            }
9444        };
9445
9446        // First send the high-level shut down broadcast.
9447        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9448        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9449        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9450        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9451        mContext.sendOrderedBroadcastAsUser(intent,
9452                UserHandle.ALL, null, br, mHandler, 0, null, null);
9453        */
9454        br.onReceive(mContext, intent);
9455    }
9456
9457    private long getLowRamTimeSinceIdle(long now) {
9458        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9459    }
9460
9461    @Override
9462    public void performIdleMaintenance() {
9463        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9464                != PackageManager.PERMISSION_GRANTED) {
9465            throw new SecurityException("Requires permission "
9466                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9467        }
9468
9469        synchronized (this) {
9470            final long now = SystemClock.uptimeMillis();
9471            final long timeSinceLastIdle = now - mLastIdleTime;
9472            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9473            mLastIdleTime = now;
9474            mLowRamTimeSinceLastIdle = 0;
9475            if (mLowRamStartTime != 0) {
9476                mLowRamStartTime = now;
9477            }
9478
9479            StringBuilder sb = new StringBuilder(128);
9480            sb.append("Idle maintenance over ");
9481            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9482            sb.append(" low RAM for ");
9483            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9484            Slog.i(TAG, sb.toString());
9485
9486            // If at least 1/3 of our time since the last idle period has been spent
9487            // with RAM low, then we want to kill processes.
9488            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9489
9490            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9491                ProcessRecord proc = mLruProcesses.get(i);
9492                if (proc.notCachedSinceIdle) {
9493                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9494                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9495                        if (doKilling && proc.initialIdlePss != 0
9496                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9497                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9498                                    + " from " + proc.initialIdlePss + ")");
9499                        }
9500                    }
9501                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9502                    proc.notCachedSinceIdle = true;
9503                    proc.initialIdlePss = 0;
9504                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9505                            isSleeping(), now);
9506                }
9507            }
9508
9509            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9510            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9511        }
9512    }
9513
9514    private void retrieveSettings() {
9515        final ContentResolver resolver = mContext.getContentResolver();
9516        String debugApp = Settings.Global.getString(
9517            resolver, Settings.Global.DEBUG_APP);
9518        boolean waitForDebugger = Settings.Global.getInt(
9519            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9520        boolean alwaysFinishActivities = Settings.Global.getInt(
9521            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9522        boolean forceRtl = Settings.Global.getInt(
9523                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9524        // Transfer any global setting for forcing RTL layout, into a System Property
9525        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9526
9527        Configuration configuration = new Configuration();
9528        Settings.System.getConfiguration(resolver, configuration);
9529        if (forceRtl) {
9530            // This will take care of setting the correct layout direction flags
9531            configuration.setLayoutDirection(configuration.locale);
9532        }
9533
9534        synchronized (this) {
9535            mDebugApp = mOrigDebugApp = debugApp;
9536            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9537            mAlwaysFinishActivities = alwaysFinishActivities;
9538            // This happens before any activities are started, so we can
9539            // change mConfiguration in-place.
9540            updateConfigurationLocked(configuration, null, false, true);
9541            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9542        }
9543    }
9544
9545    public boolean testIsSystemReady() {
9546        // no need to synchronize(this) just to read & return the value
9547        return mSystemReady;
9548    }
9549
9550    private static File getCalledPreBootReceiversFile() {
9551        File dataDir = Environment.getDataDirectory();
9552        File systemDir = new File(dataDir, "system");
9553        File fname = new File(systemDir, "called_pre_boots.dat");
9554        return fname;
9555    }
9556
9557    static final int LAST_DONE_VERSION = 10000;
9558
9559    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9560        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9561        File file = getCalledPreBootReceiversFile();
9562        FileInputStream fis = null;
9563        try {
9564            fis = new FileInputStream(file);
9565            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9566            int fvers = dis.readInt();
9567            if (fvers == LAST_DONE_VERSION) {
9568                String vers = dis.readUTF();
9569                String codename = dis.readUTF();
9570                String build = dis.readUTF();
9571                if (android.os.Build.VERSION.RELEASE.equals(vers)
9572                        && android.os.Build.VERSION.CODENAME.equals(codename)
9573                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9574                    int num = dis.readInt();
9575                    while (num > 0) {
9576                        num--;
9577                        String pkg = dis.readUTF();
9578                        String cls = dis.readUTF();
9579                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9580                    }
9581                }
9582            }
9583        } catch (FileNotFoundException e) {
9584        } catch (IOException e) {
9585            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9586        } finally {
9587            if (fis != null) {
9588                try {
9589                    fis.close();
9590                } catch (IOException e) {
9591                }
9592            }
9593        }
9594        return lastDoneReceivers;
9595    }
9596
9597    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9598        File file = getCalledPreBootReceiversFile();
9599        FileOutputStream fos = null;
9600        DataOutputStream dos = null;
9601        try {
9602            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9603            fos = new FileOutputStream(file);
9604            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9605            dos.writeInt(LAST_DONE_VERSION);
9606            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9607            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9608            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9609            dos.writeInt(list.size());
9610            for (int i=0; i<list.size(); i++) {
9611                dos.writeUTF(list.get(i).getPackageName());
9612                dos.writeUTF(list.get(i).getClassName());
9613            }
9614        } catch (IOException e) {
9615            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9616            file.delete();
9617        } finally {
9618            FileUtils.sync(fos);
9619            if (dos != null) {
9620                try {
9621                    dos.close();
9622                } catch (IOException e) {
9623                    // TODO Auto-generated catch block
9624                    e.printStackTrace();
9625                }
9626            }
9627        }
9628    }
9629
9630    public void systemReady(final Runnable goingCallback) {
9631        synchronized(this) {
9632            if (mSystemReady) {
9633                if (goingCallback != null) goingCallback.run();
9634                return;
9635            }
9636
9637            if (mRecentTasks == null) {
9638                mRecentTasks = mTaskPersister.restoreTasksLocked();
9639                if (!mRecentTasks.isEmpty()) {
9640                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9641                }
9642                mTaskPersister.startPersisting();
9643            }
9644
9645            // Check to see if there are any update receivers to run.
9646            if (!mDidUpdate) {
9647                if (mWaitingUpdate) {
9648                    return;
9649                }
9650                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9651                List<ResolveInfo> ris = null;
9652                try {
9653                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9654                            intent, null, 0, 0);
9655                } catch (RemoteException e) {
9656                }
9657                if (ris != null) {
9658                    for (int i=ris.size()-1; i>=0; i--) {
9659                        if ((ris.get(i).activityInfo.applicationInfo.flags
9660                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9661                            ris.remove(i);
9662                        }
9663                    }
9664                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9665
9666                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9667
9668                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9669                    for (int i=0; i<ris.size(); i++) {
9670                        ActivityInfo ai = ris.get(i).activityInfo;
9671                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9672                        if (lastDoneReceivers.contains(comp)) {
9673                            // We already did the pre boot receiver for this app with the current
9674                            // platform version, so don't do it again...
9675                            ris.remove(i);
9676                            i--;
9677                            // ...however, do keep it as one that has been done, so we don't
9678                            // forget about it when rewriting the file of last done receivers.
9679                            doneReceivers.add(comp);
9680                        }
9681                    }
9682
9683                    final int[] users = getUsersLocked();
9684                    for (int i=0; i<ris.size(); i++) {
9685                        ActivityInfo ai = ris.get(i).activityInfo;
9686                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9687                        doneReceivers.add(comp);
9688                        intent.setComponent(comp);
9689                        for (int j=0; j<users.length; j++) {
9690                            IIntentReceiver finisher = null;
9691                            if (i == ris.size()-1 && j == users.length-1) {
9692                                finisher = new IIntentReceiver.Stub() {
9693                                    public void performReceive(Intent intent, int resultCode,
9694                                            String data, Bundle extras, boolean ordered,
9695                                            boolean sticky, int sendingUser) {
9696                                        // The raw IIntentReceiver interface is called
9697                                        // with the AM lock held, so redispatch to
9698                                        // execute our code without the lock.
9699                                        mHandler.post(new Runnable() {
9700                                            public void run() {
9701                                                synchronized (ActivityManagerService.this) {
9702                                                    mDidUpdate = true;
9703                                                }
9704                                                writeLastDonePreBootReceivers(doneReceivers);
9705                                                showBootMessage(mContext.getText(
9706                                                        R.string.android_upgrading_complete),
9707                                                        false);
9708                                                systemReady(goingCallback);
9709                                            }
9710                                        });
9711                                    }
9712                                };
9713                            }
9714                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9715                                    + " for user " + users[j]);
9716                            broadcastIntentLocked(null, null, intent, null, finisher,
9717                                    0, null, null, null, AppOpsManager.OP_NONE,
9718                                    true, false, MY_PID, Process.SYSTEM_UID,
9719                                    users[j]);
9720                            if (finisher != null) {
9721                                mWaitingUpdate = true;
9722                            }
9723                        }
9724                    }
9725                }
9726                if (mWaitingUpdate) {
9727                    return;
9728                }
9729                mDidUpdate = true;
9730            }
9731
9732            mAppOpsService.systemReady();
9733            mUsageStatsService.systemReady();
9734            mSystemReady = true;
9735        }
9736
9737        ArrayList<ProcessRecord> procsToKill = null;
9738        synchronized(mPidsSelfLocked) {
9739            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9740                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9741                if (!isAllowedWhileBooting(proc.info)){
9742                    if (procsToKill == null) {
9743                        procsToKill = new ArrayList<ProcessRecord>();
9744                    }
9745                    procsToKill.add(proc);
9746                }
9747            }
9748        }
9749
9750        synchronized(this) {
9751            if (procsToKill != null) {
9752                for (int i=procsToKill.size()-1; i>=0; i--) {
9753                    ProcessRecord proc = procsToKill.get(i);
9754                    Slog.i(TAG, "Removing system update proc: " + proc);
9755                    removeProcessLocked(proc, true, false, "system update done");
9756                }
9757            }
9758
9759            // Now that we have cleaned up any update processes, we
9760            // are ready to start launching real processes and know that
9761            // we won't trample on them any more.
9762            mProcessesReady = true;
9763        }
9764
9765        Slog.i(TAG, "System now ready");
9766        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9767            SystemClock.uptimeMillis());
9768
9769        synchronized(this) {
9770            // Make sure we have no pre-ready processes sitting around.
9771
9772            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9773                ResolveInfo ri = mContext.getPackageManager()
9774                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9775                                STOCK_PM_FLAGS);
9776                CharSequence errorMsg = null;
9777                if (ri != null) {
9778                    ActivityInfo ai = ri.activityInfo;
9779                    ApplicationInfo app = ai.applicationInfo;
9780                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9781                        mTopAction = Intent.ACTION_FACTORY_TEST;
9782                        mTopData = null;
9783                        mTopComponent = new ComponentName(app.packageName,
9784                                ai.name);
9785                    } else {
9786                        errorMsg = mContext.getResources().getText(
9787                                com.android.internal.R.string.factorytest_not_system);
9788                    }
9789                } else {
9790                    errorMsg = mContext.getResources().getText(
9791                            com.android.internal.R.string.factorytest_no_action);
9792                }
9793                if (errorMsg != null) {
9794                    mTopAction = null;
9795                    mTopData = null;
9796                    mTopComponent = null;
9797                    Message msg = Message.obtain();
9798                    msg.what = SHOW_FACTORY_ERROR_MSG;
9799                    msg.getData().putCharSequence("msg", errorMsg);
9800                    mHandler.sendMessage(msg);
9801                }
9802            }
9803        }
9804
9805        retrieveSettings();
9806
9807        synchronized (this) {
9808            readGrantedUriPermissionsLocked();
9809        }
9810
9811        if (goingCallback != null) goingCallback.run();
9812
9813        mSystemServiceManager.startUser(mCurrentUserId);
9814
9815        synchronized (this) {
9816            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9817                try {
9818                    List apps = AppGlobals.getPackageManager().
9819                        getPersistentApplications(STOCK_PM_FLAGS);
9820                    if (apps != null) {
9821                        int N = apps.size();
9822                        int i;
9823                        for (i=0; i<N; i++) {
9824                            ApplicationInfo info
9825                                = (ApplicationInfo)apps.get(i);
9826                            if (info != null &&
9827                                    !info.packageName.equals("android")) {
9828                                addAppLocked(info, false, null /* ABI override */);
9829                            }
9830                        }
9831                    }
9832                } catch (RemoteException ex) {
9833                    // pm is in same process, this will never happen.
9834                }
9835            }
9836
9837            // Start up initial activity.
9838            mBooting = true;
9839
9840            try {
9841                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9842                    Message msg = Message.obtain();
9843                    msg.what = SHOW_UID_ERROR_MSG;
9844                    mHandler.sendMessage(msg);
9845                }
9846            } catch (RemoteException e) {
9847            }
9848
9849            long ident = Binder.clearCallingIdentity();
9850            try {
9851                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9852                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9853                        | Intent.FLAG_RECEIVER_FOREGROUND);
9854                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9855                broadcastIntentLocked(null, null, intent,
9856                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9857                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9858                intent = new Intent(Intent.ACTION_USER_STARTING);
9859                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9860                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9861                broadcastIntentLocked(null, null, intent,
9862                        null, new IIntentReceiver.Stub() {
9863                            @Override
9864                            public void performReceive(Intent intent, int resultCode, String data,
9865                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9866                                    throws RemoteException {
9867                            }
9868                        }, 0, null, null,
9869                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9870                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9871            } catch (Throwable t) {
9872                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9873            } finally {
9874                Binder.restoreCallingIdentity(ident);
9875            }
9876            mStackSupervisor.resumeTopActivitiesLocked();
9877            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9878        }
9879    }
9880
9881    private boolean makeAppCrashingLocked(ProcessRecord app,
9882            String shortMsg, String longMsg, String stackTrace) {
9883        app.crashing = true;
9884        app.crashingReport = generateProcessError(app,
9885                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9886        startAppProblemLocked(app);
9887        app.stopFreezingAllLocked();
9888        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9889    }
9890
9891    private void makeAppNotRespondingLocked(ProcessRecord app,
9892            String activity, String shortMsg, String longMsg) {
9893        app.notResponding = true;
9894        app.notRespondingReport = generateProcessError(app,
9895                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9896                activity, shortMsg, longMsg, null);
9897        startAppProblemLocked(app);
9898        app.stopFreezingAllLocked();
9899    }
9900
9901    /**
9902     * Generate a process error record, suitable for attachment to a ProcessRecord.
9903     *
9904     * @param app The ProcessRecord in which the error occurred.
9905     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9906     *                      ActivityManager.AppErrorStateInfo
9907     * @param activity The activity associated with the crash, if known.
9908     * @param shortMsg Short message describing the crash.
9909     * @param longMsg Long message describing the crash.
9910     * @param stackTrace Full crash stack trace, may be null.
9911     *
9912     * @return Returns a fully-formed AppErrorStateInfo record.
9913     */
9914    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9915            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9916        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9917
9918        report.condition = condition;
9919        report.processName = app.processName;
9920        report.pid = app.pid;
9921        report.uid = app.info.uid;
9922        report.tag = activity;
9923        report.shortMsg = shortMsg;
9924        report.longMsg = longMsg;
9925        report.stackTrace = stackTrace;
9926
9927        return report;
9928    }
9929
9930    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9931        synchronized (this) {
9932            app.crashing = false;
9933            app.crashingReport = null;
9934            app.notResponding = false;
9935            app.notRespondingReport = null;
9936            if (app.anrDialog == fromDialog) {
9937                app.anrDialog = null;
9938            }
9939            if (app.waitDialog == fromDialog) {
9940                app.waitDialog = null;
9941            }
9942            if (app.pid > 0 && app.pid != MY_PID) {
9943                handleAppCrashLocked(app, null, null, null);
9944                killUnneededProcessLocked(app, "user request after error");
9945            }
9946        }
9947    }
9948
9949    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9950            String stackTrace) {
9951        long now = SystemClock.uptimeMillis();
9952
9953        Long crashTime;
9954        if (!app.isolated) {
9955            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9956        } else {
9957            crashTime = null;
9958        }
9959        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9960            // This process loses!
9961            Slog.w(TAG, "Process " + app.info.processName
9962                    + " has crashed too many times: killing!");
9963            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9964                    app.userId, app.info.processName, app.uid);
9965            mStackSupervisor.handleAppCrashLocked(app);
9966            if (!app.persistent) {
9967                // We don't want to start this process again until the user
9968                // explicitly does so...  but for persistent process, we really
9969                // need to keep it running.  If a persistent process is actually
9970                // repeatedly crashing, then badness for everyone.
9971                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9972                        app.info.processName);
9973                if (!app.isolated) {
9974                    // XXX We don't have a way to mark isolated processes
9975                    // as bad, since they don't have a peristent identity.
9976                    mBadProcesses.put(app.info.processName, app.uid,
9977                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9978                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9979                }
9980                app.bad = true;
9981                app.removed = true;
9982                // Don't let services in this process be restarted and potentially
9983                // annoy the user repeatedly.  Unless it is persistent, since those
9984                // processes run critical code.
9985                removeProcessLocked(app, false, false, "crash");
9986                mStackSupervisor.resumeTopActivitiesLocked();
9987                return false;
9988            }
9989            mStackSupervisor.resumeTopActivitiesLocked();
9990        } else {
9991            mStackSupervisor.finishTopRunningActivityLocked(app);
9992        }
9993
9994        // Bump up the crash count of any services currently running in the proc.
9995        for (int i=app.services.size()-1; i>=0; i--) {
9996            // Any services running in the application need to be placed
9997            // back in the pending list.
9998            ServiceRecord sr = app.services.valueAt(i);
9999            sr.crashCount++;
10000        }
10001
10002        // If the crashing process is what we consider to be the "home process" and it has been
10003        // replaced by a third-party app, clear the package preferred activities from packages
10004        // with a home activity running in the process to prevent a repeatedly crashing app
10005        // from blocking the user to manually clear the list.
10006        final ArrayList<ActivityRecord> activities = app.activities;
10007        if (app == mHomeProcess && activities.size() > 0
10008                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10009            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10010                final ActivityRecord r = activities.get(activityNdx);
10011                if (r.isHomeActivity()) {
10012                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10013                    try {
10014                        ActivityThread.getPackageManager()
10015                                .clearPackagePreferredActivities(r.packageName);
10016                    } catch (RemoteException c) {
10017                        // pm is in same process, this will never happen.
10018                    }
10019                }
10020            }
10021        }
10022
10023        if (!app.isolated) {
10024            // XXX Can't keep track of crash times for isolated processes,
10025            // because they don't have a perisistent identity.
10026            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10027        }
10028
10029        return true;
10030    }
10031
10032    void startAppProblemLocked(ProcessRecord app) {
10033        if (app.userId == mCurrentUserId) {
10034            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10035                    mContext, app.info.packageName, app.info.flags);
10036        } else {
10037            // If this app is not running under the current user, then we
10038            // can't give it a report button because that would require
10039            // launching the report UI under a different user.
10040            app.errorReportReceiver = null;
10041        }
10042        skipCurrentReceiverLocked(app);
10043    }
10044
10045    void skipCurrentReceiverLocked(ProcessRecord app) {
10046        for (BroadcastQueue queue : mBroadcastQueues) {
10047            queue.skipCurrentReceiverLocked(app);
10048        }
10049    }
10050
10051    /**
10052     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10053     * The application process will exit immediately after this call returns.
10054     * @param app object of the crashing app, null for the system server
10055     * @param crashInfo describing the exception
10056     */
10057    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10058        ProcessRecord r = findAppProcess(app, "Crash");
10059        final String processName = app == null ? "system_server"
10060                : (r == null ? "unknown" : r.processName);
10061
10062        handleApplicationCrashInner("crash", r, processName, crashInfo);
10063    }
10064
10065    /* Native crash reporting uses this inner version because it needs to be somewhat
10066     * decoupled from the AM-managed cleanup lifecycle
10067     */
10068    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10069            ApplicationErrorReport.CrashInfo crashInfo) {
10070        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10071                UserHandle.getUserId(Binder.getCallingUid()), processName,
10072                r == null ? -1 : r.info.flags,
10073                crashInfo.exceptionClassName,
10074                crashInfo.exceptionMessage,
10075                crashInfo.throwFileName,
10076                crashInfo.throwLineNumber);
10077
10078        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10079
10080        crashApplication(r, crashInfo);
10081    }
10082
10083    public void handleApplicationStrictModeViolation(
10084            IBinder app,
10085            int violationMask,
10086            StrictMode.ViolationInfo info) {
10087        ProcessRecord r = findAppProcess(app, "StrictMode");
10088        if (r == null) {
10089            return;
10090        }
10091
10092        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10093            Integer stackFingerprint = info.hashCode();
10094            boolean logIt = true;
10095            synchronized (mAlreadyLoggedViolatedStacks) {
10096                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10097                    logIt = false;
10098                    // TODO: sub-sample into EventLog for these, with
10099                    // the info.durationMillis?  Then we'd get
10100                    // the relative pain numbers, without logging all
10101                    // the stack traces repeatedly.  We'd want to do
10102                    // likewise in the client code, which also does
10103                    // dup suppression, before the Binder call.
10104                } else {
10105                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10106                        mAlreadyLoggedViolatedStacks.clear();
10107                    }
10108                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10109                }
10110            }
10111            if (logIt) {
10112                logStrictModeViolationToDropBox(r, info);
10113            }
10114        }
10115
10116        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10117            AppErrorResult result = new AppErrorResult();
10118            synchronized (this) {
10119                final long origId = Binder.clearCallingIdentity();
10120
10121                Message msg = Message.obtain();
10122                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10123                HashMap<String, Object> data = new HashMap<String, Object>();
10124                data.put("result", result);
10125                data.put("app", r);
10126                data.put("violationMask", violationMask);
10127                data.put("info", info);
10128                msg.obj = data;
10129                mHandler.sendMessage(msg);
10130
10131                Binder.restoreCallingIdentity(origId);
10132            }
10133            int res = result.get();
10134            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10135        }
10136    }
10137
10138    // Depending on the policy in effect, there could be a bunch of
10139    // these in quick succession so we try to batch these together to
10140    // minimize disk writes, number of dropbox entries, and maximize
10141    // compression, by having more fewer, larger records.
10142    private void logStrictModeViolationToDropBox(
10143            ProcessRecord process,
10144            StrictMode.ViolationInfo info) {
10145        if (info == null) {
10146            return;
10147        }
10148        final boolean isSystemApp = process == null ||
10149                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10150                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10151        final String processName = process == null ? "unknown" : process.processName;
10152        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10153        final DropBoxManager dbox = (DropBoxManager)
10154                mContext.getSystemService(Context.DROPBOX_SERVICE);
10155
10156        // Exit early if the dropbox isn't configured to accept this report type.
10157        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10158
10159        boolean bufferWasEmpty;
10160        boolean needsFlush;
10161        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10162        synchronized (sb) {
10163            bufferWasEmpty = sb.length() == 0;
10164            appendDropBoxProcessHeaders(process, processName, sb);
10165            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10166            sb.append("System-App: ").append(isSystemApp).append("\n");
10167            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10168            if (info.violationNumThisLoop != 0) {
10169                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10170            }
10171            if (info.numAnimationsRunning != 0) {
10172                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10173            }
10174            if (info.broadcastIntentAction != null) {
10175                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10176            }
10177            if (info.durationMillis != -1) {
10178                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10179            }
10180            if (info.numInstances != -1) {
10181                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10182            }
10183            if (info.tags != null) {
10184                for (String tag : info.tags) {
10185                    sb.append("Span-Tag: ").append(tag).append("\n");
10186                }
10187            }
10188            sb.append("\n");
10189            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10190                sb.append(info.crashInfo.stackTrace);
10191            }
10192            sb.append("\n");
10193
10194            // Only buffer up to ~64k.  Various logging bits truncate
10195            // things at 128k.
10196            needsFlush = (sb.length() > 64 * 1024);
10197        }
10198
10199        // Flush immediately if the buffer's grown too large, or this
10200        // is a non-system app.  Non-system apps are isolated with a
10201        // different tag & policy and not batched.
10202        //
10203        // Batching is useful during internal testing with
10204        // StrictMode settings turned up high.  Without batching,
10205        // thousands of separate files could be created on boot.
10206        if (!isSystemApp || needsFlush) {
10207            new Thread("Error dump: " + dropboxTag) {
10208                @Override
10209                public void run() {
10210                    String report;
10211                    synchronized (sb) {
10212                        report = sb.toString();
10213                        sb.delete(0, sb.length());
10214                        sb.trimToSize();
10215                    }
10216                    if (report.length() != 0) {
10217                        dbox.addText(dropboxTag, report);
10218                    }
10219                }
10220            }.start();
10221            return;
10222        }
10223
10224        // System app batching:
10225        if (!bufferWasEmpty) {
10226            // An existing dropbox-writing thread is outstanding, so
10227            // we don't need to start it up.  The existing thread will
10228            // catch the buffer appends we just did.
10229            return;
10230        }
10231
10232        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10233        // (After this point, we shouldn't access AMS internal data structures.)
10234        new Thread("Error dump: " + dropboxTag) {
10235            @Override
10236            public void run() {
10237                // 5 second sleep to let stacks arrive and be batched together
10238                try {
10239                    Thread.sleep(5000);  // 5 seconds
10240                } catch (InterruptedException e) {}
10241
10242                String errorReport;
10243                synchronized (mStrictModeBuffer) {
10244                    errorReport = mStrictModeBuffer.toString();
10245                    if (errorReport.length() == 0) {
10246                        return;
10247                    }
10248                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10249                    mStrictModeBuffer.trimToSize();
10250                }
10251                dbox.addText(dropboxTag, errorReport);
10252            }
10253        }.start();
10254    }
10255
10256    /**
10257     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10258     * @param app object of the crashing app, null for the system server
10259     * @param tag reported by the caller
10260     * @param crashInfo describing the context of the error
10261     * @return true if the process should exit immediately (WTF is fatal)
10262     */
10263    public boolean handleApplicationWtf(IBinder app, String tag,
10264            ApplicationErrorReport.CrashInfo crashInfo) {
10265        ProcessRecord r = findAppProcess(app, "WTF");
10266        final String processName = app == null ? "system_server"
10267                : (r == null ? "unknown" : r.processName);
10268
10269        EventLog.writeEvent(EventLogTags.AM_WTF,
10270                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10271                processName,
10272                r == null ? -1 : r.info.flags,
10273                tag, crashInfo.exceptionMessage);
10274
10275        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10276
10277        if (r != null && r.pid != Process.myPid() &&
10278                Settings.Global.getInt(mContext.getContentResolver(),
10279                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10280            crashApplication(r, crashInfo);
10281            return true;
10282        } else {
10283            return false;
10284        }
10285    }
10286
10287    /**
10288     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10289     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10290     */
10291    private ProcessRecord findAppProcess(IBinder app, String reason) {
10292        if (app == null) {
10293            return null;
10294        }
10295
10296        synchronized (this) {
10297            final int NP = mProcessNames.getMap().size();
10298            for (int ip=0; ip<NP; ip++) {
10299                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10300                final int NA = apps.size();
10301                for (int ia=0; ia<NA; ia++) {
10302                    ProcessRecord p = apps.valueAt(ia);
10303                    if (p.thread != null && p.thread.asBinder() == app) {
10304                        return p;
10305                    }
10306                }
10307            }
10308
10309            Slog.w(TAG, "Can't find mystery application for " + reason
10310                    + " from pid=" + Binder.getCallingPid()
10311                    + " uid=" + Binder.getCallingUid() + ": " + app);
10312            return null;
10313        }
10314    }
10315
10316    /**
10317     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10318     * to append various headers to the dropbox log text.
10319     */
10320    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10321            StringBuilder sb) {
10322        // Watchdog thread ends up invoking this function (with
10323        // a null ProcessRecord) to add the stack file to dropbox.
10324        // Do not acquire a lock on this (am) in such cases, as it
10325        // could cause a potential deadlock, if and when watchdog
10326        // is invoked due to unavailability of lock on am and it
10327        // would prevent watchdog from killing system_server.
10328        if (process == null) {
10329            sb.append("Process: ").append(processName).append("\n");
10330            return;
10331        }
10332        // Note: ProcessRecord 'process' is guarded by the service
10333        // instance.  (notably process.pkgList, which could otherwise change
10334        // concurrently during execution of this method)
10335        synchronized (this) {
10336            sb.append("Process: ").append(processName).append("\n");
10337            int flags = process.info.flags;
10338            IPackageManager pm = AppGlobals.getPackageManager();
10339            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10340            for (int ip=0; ip<process.pkgList.size(); ip++) {
10341                String pkg = process.pkgList.keyAt(ip);
10342                sb.append("Package: ").append(pkg);
10343                try {
10344                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10345                    if (pi != null) {
10346                        sb.append(" v").append(pi.versionCode);
10347                        if (pi.versionName != null) {
10348                            sb.append(" (").append(pi.versionName).append(")");
10349                        }
10350                    }
10351                } catch (RemoteException e) {
10352                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10353                }
10354                sb.append("\n");
10355            }
10356        }
10357    }
10358
10359    private static String processClass(ProcessRecord process) {
10360        if (process == null || process.pid == MY_PID) {
10361            return "system_server";
10362        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10363            return "system_app";
10364        } else {
10365            return "data_app";
10366        }
10367    }
10368
10369    /**
10370     * Write a description of an error (crash, WTF, ANR) to the drop box.
10371     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10372     * @param process which caused the error, null means the system server
10373     * @param activity which triggered the error, null if unknown
10374     * @param parent activity related to the error, null if unknown
10375     * @param subject line related to the error, null if absent
10376     * @param report in long form describing the error, null if absent
10377     * @param logFile to include in the report, null if none
10378     * @param crashInfo giving an application stack trace, null if absent
10379     */
10380    public void addErrorToDropBox(String eventType,
10381            ProcessRecord process, String processName, ActivityRecord activity,
10382            ActivityRecord parent, String subject,
10383            final String report, final File logFile,
10384            final ApplicationErrorReport.CrashInfo crashInfo) {
10385        // NOTE -- this must never acquire the ActivityManagerService lock,
10386        // otherwise the watchdog may be prevented from resetting the system.
10387
10388        final String dropboxTag = processClass(process) + "_" + eventType;
10389        final DropBoxManager dbox = (DropBoxManager)
10390                mContext.getSystemService(Context.DROPBOX_SERVICE);
10391
10392        // Exit early if the dropbox isn't configured to accept this report type.
10393        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10394
10395        final StringBuilder sb = new StringBuilder(1024);
10396        appendDropBoxProcessHeaders(process, processName, sb);
10397        if (activity != null) {
10398            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10399        }
10400        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10401            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10402        }
10403        if (parent != null && parent != activity) {
10404            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10405        }
10406        if (subject != null) {
10407            sb.append("Subject: ").append(subject).append("\n");
10408        }
10409        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10410        if (Debug.isDebuggerConnected()) {
10411            sb.append("Debugger: Connected\n");
10412        }
10413        sb.append("\n");
10414
10415        // Do the rest in a worker thread to avoid blocking the caller on I/O
10416        // (After this point, we shouldn't access AMS internal data structures.)
10417        Thread worker = new Thread("Error dump: " + dropboxTag) {
10418            @Override
10419            public void run() {
10420                if (report != null) {
10421                    sb.append(report);
10422                }
10423                if (logFile != null) {
10424                    try {
10425                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10426                                    "\n\n[[TRUNCATED]]"));
10427                    } catch (IOException e) {
10428                        Slog.e(TAG, "Error reading " + logFile, e);
10429                    }
10430                }
10431                if (crashInfo != null && crashInfo.stackTrace != null) {
10432                    sb.append(crashInfo.stackTrace);
10433                }
10434
10435                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10436                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10437                if (lines > 0) {
10438                    sb.append("\n");
10439
10440                    // Merge several logcat streams, and take the last N lines
10441                    InputStreamReader input = null;
10442                    try {
10443                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10444                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10445                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10446
10447                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10448                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10449                        input = new InputStreamReader(logcat.getInputStream());
10450
10451                        int num;
10452                        char[] buf = new char[8192];
10453                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10454                    } catch (IOException e) {
10455                        Slog.e(TAG, "Error running logcat", e);
10456                    } finally {
10457                        if (input != null) try { input.close(); } catch (IOException e) {}
10458                    }
10459                }
10460
10461                dbox.addText(dropboxTag, sb.toString());
10462            }
10463        };
10464
10465        if (process == null) {
10466            // If process is null, we are being called from some internal code
10467            // and may be about to die -- run this synchronously.
10468            worker.run();
10469        } else {
10470            worker.start();
10471        }
10472    }
10473
10474    /**
10475     * Bring up the "unexpected error" dialog box for a crashing app.
10476     * Deal with edge cases (intercepts from instrumented applications,
10477     * ActivityController, error intent receivers, that sort of thing).
10478     * @param r the application crashing
10479     * @param crashInfo describing the failure
10480     */
10481    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10482        long timeMillis = System.currentTimeMillis();
10483        String shortMsg = crashInfo.exceptionClassName;
10484        String longMsg = crashInfo.exceptionMessage;
10485        String stackTrace = crashInfo.stackTrace;
10486        if (shortMsg != null && longMsg != null) {
10487            longMsg = shortMsg + ": " + longMsg;
10488        } else if (shortMsg != null) {
10489            longMsg = shortMsg;
10490        }
10491
10492        AppErrorResult result = new AppErrorResult();
10493        synchronized (this) {
10494            if (mController != null) {
10495                try {
10496                    String name = r != null ? r.processName : null;
10497                    int pid = r != null ? r.pid : Binder.getCallingPid();
10498                    if (!mController.appCrashed(name, pid,
10499                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10500                        Slog.w(TAG, "Force-killing crashed app " + name
10501                                + " at watcher's request");
10502                        Process.killProcess(pid);
10503                        return;
10504                    }
10505                } catch (RemoteException e) {
10506                    mController = null;
10507                    Watchdog.getInstance().setActivityController(null);
10508                }
10509            }
10510
10511            final long origId = Binder.clearCallingIdentity();
10512
10513            // If this process is running instrumentation, finish it.
10514            if (r != null && r.instrumentationClass != null) {
10515                Slog.w(TAG, "Error in app " + r.processName
10516                      + " running instrumentation " + r.instrumentationClass + ":");
10517                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10518                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10519                Bundle info = new Bundle();
10520                info.putString("shortMsg", shortMsg);
10521                info.putString("longMsg", longMsg);
10522                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10523                Binder.restoreCallingIdentity(origId);
10524                return;
10525            }
10526
10527            // If we can't identify the process or it's already exceeded its crash quota,
10528            // quit right away without showing a crash dialog.
10529            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10530                Binder.restoreCallingIdentity(origId);
10531                return;
10532            }
10533
10534            Message msg = Message.obtain();
10535            msg.what = SHOW_ERROR_MSG;
10536            HashMap data = new HashMap();
10537            data.put("result", result);
10538            data.put("app", r);
10539            msg.obj = data;
10540            mHandler.sendMessage(msg);
10541
10542            Binder.restoreCallingIdentity(origId);
10543        }
10544
10545        int res = result.get();
10546
10547        Intent appErrorIntent = null;
10548        synchronized (this) {
10549            if (r != null && !r.isolated) {
10550                // XXX Can't keep track of crash time for isolated processes,
10551                // since they don't have a persistent identity.
10552                mProcessCrashTimes.put(r.info.processName, r.uid,
10553                        SystemClock.uptimeMillis());
10554            }
10555            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10556                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10557            }
10558        }
10559
10560        if (appErrorIntent != null) {
10561            try {
10562                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10563            } catch (ActivityNotFoundException e) {
10564                Slog.w(TAG, "bug report receiver dissappeared", e);
10565            }
10566        }
10567    }
10568
10569    Intent createAppErrorIntentLocked(ProcessRecord r,
10570            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10571        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10572        if (report == null) {
10573            return null;
10574        }
10575        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10576        result.setComponent(r.errorReportReceiver);
10577        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10578        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10579        return result;
10580    }
10581
10582    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10583            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10584        if (r.errorReportReceiver == null) {
10585            return null;
10586        }
10587
10588        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10589            return null;
10590        }
10591
10592        ApplicationErrorReport report = new ApplicationErrorReport();
10593        report.packageName = r.info.packageName;
10594        report.installerPackageName = r.errorReportReceiver.getPackageName();
10595        report.processName = r.processName;
10596        report.time = timeMillis;
10597        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10598
10599        if (r.crashing || r.forceCrashReport) {
10600            report.type = ApplicationErrorReport.TYPE_CRASH;
10601            report.crashInfo = crashInfo;
10602        } else if (r.notResponding) {
10603            report.type = ApplicationErrorReport.TYPE_ANR;
10604            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10605
10606            report.anrInfo.activity = r.notRespondingReport.tag;
10607            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10608            report.anrInfo.info = r.notRespondingReport.longMsg;
10609        }
10610
10611        return report;
10612    }
10613
10614    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10615        enforceNotIsolatedCaller("getProcessesInErrorState");
10616        // assume our apps are happy - lazy create the list
10617        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10618
10619        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10620                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10621        int userId = UserHandle.getUserId(Binder.getCallingUid());
10622
10623        synchronized (this) {
10624
10625            // iterate across all processes
10626            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10627                ProcessRecord app = mLruProcesses.get(i);
10628                if (!allUsers && app.userId != userId) {
10629                    continue;
10630                }
10631                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10632                    // This one's in trouble, so we'll generate a report for it
10633                    // crashes are higher priority (in case there's a crash *and* an anr)
10634                    ActivityManager.ProcessErrorStateInfo report = null;
10635                    if (app.crashing) {
10636                        report = app.crashingReport;
10637                    } else if (app.notResponding) {
10638                        report = app.notRespondingReport;
10639                    }
10640
10641                    if (report != null) {
10642                        if (errList == null) {
10643                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10644                        }
10645                        errList.add(report);
10646                    } else {
10647                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10648                                " crashing = " + app.crashing +
10649                                " notResponding = " + app.notResponding);
10650                    }
10651                }
10652            }
10653        }
10654
10655        return errList;
10656    }
10657
10658    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10659        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10660            if (currApp != null) {
10661                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10662            }
10663            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10664        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10665            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10666        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10667            if (currApp != null) {
10668                currApp.lru = 0;
10669            }
10670            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10671        } else if (adj >= ProcessList.SERVICE_ADJ) {
10672            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10673        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10674            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10675        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10676            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10677        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10678            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10679        } else {
10680            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10681        }
10682    }
10683
10684    private void fillInProcMemInfo(ProcessRecord app,
10685            ActivityManager.RunningAppProcessInfo outInfo) {
10686        outInfo.pid = app.pid;
10687        outInfo.uid = app.info.uid;
10688        if (mHeavyWeightProcess == app) {
10689            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10690        }
10691        if (app.persistent) {
10692            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10693        }
10694        if (app.activities.size() > 0) {
10695            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10696        }
10697        outInfo.lastTrimLevel = app.trimMemoryLevel;
10698        int adj = app.curAdj;
10699        outInfo.importance = oomAdjToImportance(adj, outInfo);
10700        outInfo.importanceReasonCode = app.adjTypeCode;
10701        outInfo.processState = app.curProcState;
10702    }
10703
10704    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10705        enforceNotIsolatedCaller("getRunningAppProcesses");
10706        // Lazy instantiation of list
10707        List<ActivityManager.RunningAppProcessInfo> runList = null;
10708        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10709                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10710        int userId = UserHandle.getUserId(Binder.getCallingUid());
10711        synchronized (this) {
10712            // Iterate across all processes
10713            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10714                ProcessRecord app = mLruProcesses.get(i);
10715                if (!allUsers && app.userId != userId) {
10716                    continue;
10717                }
10718                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10719                    // Generate process state info for running application
10720                    ActivityManager.RunningAppProcessInfo currApp =
10721                        new ActivityManager.RunningAppProcessInfo(app.processName,
10722                                app.pid, app.getPackageList());
10723                    fillInProcMemInfo(app, currApp);
10724                    if (app.adjSource instanceof ProcessRecord) {
10725                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10726                        currApp.importanceReasonImportance = oomAdjToImportance(
10727                                app.adjSourceOom, null);
10728                    } else if (app.adjSource instanceof ActivityRecord) {
10729                        ActivityRecord r = (ActivityRecord)app.adjSource;
10730                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10731                    }
10732                    if (app.adjTarget instanceof ComponentName) {
10733                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10734                    }
10735                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10736                    //        + " lru=" + currApp.lru);
10737                    if (runList == null) {
10738                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10739                    }
10740                    runList.add(currApp);
10741                }
10742            }
10743        }
10744        return runList;
10745    }
10746
10747    public List<ApplicationInfo> getRunningExternalApplications() {
10748        enforceNotIsolatedCaller("getRunningExternalApplications");
10749        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10750        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10751        if (runningApps != null && runningApps.size() > 0) {
10752            Set<String> extList = new HashSet<String>();
10753            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10754                if (app.pkgList != null) {
10755                    for (String pkg : app.pkgList) {
10756                        extList.add(pkg);
10757                    }
10758                }
10759            }
10760            IPackageManager pm = AppGlobals.getPackageManager();
10761            for (String pkg : extList) {
10762                try {
10763                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10764                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10765                        retList.add(info);
10766                    }
10767                } catch (RemoteException e) {
10768                }
10769            }
10770        }
10771        return retList;
10772    }
10773
10774    @Override
10775    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10776        enforceNotIsolatedCaller("getMyMemoryState");
10777        synchronized (this) {
10778            ProcessRecord proc;
10779            synchronized (mPidsSelfLocked) {
10780                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10781            }
10782            fillInProcMemInfo(proc, outInfo);
10783        }
10784    }
10785
10786    @Override
10787    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10788        if (checkCallingPermission(android.Manifest.permission.DUMP)
10789                != PackageManager.PERMISSION_GRANTED) {
10790            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10791                    + Binder.getCallingPid()
10792                    + ", uid=" + Binder.getCallingUid()
10793                    + " without permission "
10794                    + android.Manifest.permission.DUMP);
10795            return;
10796        }
10797
10798        boolean dumpAll = false;
10799        boolean dumpClient = false;
10800        String dumpPackage = null;
10801
10802        int opti = 0;
10803        while (opti < args.length) {
10804            String opt = args[opti];
10805            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10806                break;
10807            }
10808            opti++;
10809            if ("-a".equals(opt)) {
10810                dumpAll = true;
10811            } else if ("-c".equals(opt)) {
10812                dumpClient = true;
10813            } else if ("-h".equals(opt)) {
10814                pw.println("Activity manager dump options:");
10815                pw.println("  [-a] [-c] [-h] [cmd] ...");
10816                pw.println("  cmd may be one of:");
10817                pw.println("    a[ctivities]: activity stack state");
10818                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10819                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10820                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10821                pw.println("    o[om]: out of memory management");
10822                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10823                pw.println("    provider [COMP_SPEC]: provider client-side state");
10824                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10825                pw.println("    service [COMP_SPEC]: service client-side state");
10826                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10827                pw.println("    all: dump all activities");
10828                pw.println("    top: dump the top activity");
10829                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10830                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10831                pw.println("    a partial substring in a component name, a");
10832                pw.println("    hex object identifier.");
10833                pw.println("  -a: include all available server state.");
10834                pw.println("  -c: include client state.");
10835                return;
10836            } else {
10837                pw.println("Unknown argument: " + opt + "; use -h for help");
10838            }
10839        }
10840
10841        long origId = Binder.clearCallingIdentity();
10842        boolean more = false;
10843        // Is the caller requesting to dump a particular piece of data?
10844        if (opti < args.length) {
10845            String cmd = args[opti];
10846            opti++;
10847            if ("activities".equals(cmd) || "a".equals(cmd)) {
10848                synchronized (this) {
10849                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10850                }
10851            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10852                String[] newArgs;
10853                String name;
10854                if (opti >= args.length) {
10855                    name = null;
10856                    newArgs = EMPTY_STRING_ARRAY;
10857                } else {
10858                    name = args[opti];
10859                    opti++;
10860                    newArgs = new String[args.length - opti];
10861                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10862                            args.length - opti);
10863                }
10864                synchronized (this) {
10865                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10866                }
10867            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10868                String[] newArgs;
10869                String name;
10870                if (opti >= args.length) {
10871                    name = null;
10872                    newArgs = EMPTY_STRING_ARRAY;
10873                } else {
10874                    name = args[opti];
10875                    opti++;
10876                    newArgs = new String[args.length - opti];
10877                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10878                            args.length - opti);
10879                }
10880                synchronized (this) {
10881                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10882                }
10883            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10884                String[] newArgs;
10885                String name;
10886                if (opti >= args.length) {
10887                    name = null;
10888                    newArgs = EMPTY_STRING_ARRAY;
10889                } else {
10890                    name = args[opti];
10891                    opti++;
10892                    newArgs = new String[args.length - opti];
10893                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10894                            args.length - opti);
10895                }
10896                synchronized (this) {
10897                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10898                }
10899            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10900                synchronized (this) {
10901                    dumpOomLocked(fd, pw, args, opti, true);
10902                }
10903            } else if ("provider".equals(cmd)) {
10904                String[] newArgs;
10905                String name;
10906                if (opti >= args.length) {
10907                    name = null;
10908                    newArgs = EMPTY_STRING_ARRAY;
10909                } else {
10910                    name = args[opti];
10911                    opti++;
10912                    newArgs = new String[args.length - opti];
10913                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10914                }
10915                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10916                    pw.println("No providers match: " + name);
10917                    pw.println("Use -h for help.");
10918                }
10919            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10920                synchronized (this) {
10921                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10922                }
10923            } else if ("service".equals(cmd)) {
10924                String[] newArgs;
10925                String name;
10926                if (opti >= args.length) {
10927                    name = null;
10928                    newArgs = EMPTY_STRING_ARRAY;
10929                } else {
10930                    name = args[opti];
10931                    opti++;
10932                    newArgs = new String[args.length - opti];
10933                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10934                            args.length - opti);
10935                }
10936                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10937                    pw.println("No services match: " + name);
10938                    pw.println("Use -h for help.");
10939                }
10940            } else if ("package".equals(cmd)) {
10941                String[] newArgs;
10942                if (opti >= args.length) {
10943                    pw.println("package: no package name specified");
10944                    pw.println("Use -h for help.");
10945                } else {
10946                    dumpPackage = args[opti];
10947                    opti++;
10948                    newArgs = new String[args.length - opti];
10949                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10950                            args.length - opti);
10951                    args = newArgs;
10952                    opti = 0;
10953                    more = true;
10954                }
10955            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10956                synchronized (this) {
10957                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10958                }
10959            } else {
10960                // Dumping a single activity?
10961                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10962                    pw.println("Bad activity command, or no activities match: " + cmd);
10963                    pw.println("Use -h for help.");
10964                }
10965            }
10966            if (!more) {
10967                Binder.restoreCallingIdentity(origId);
10968                return;
10969            }
10970        }
10971
10972        // No piece of data specified, dump everything.
10973        synchronized (this) {
10974            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10975            pw.println();
10976            if (dumpAll) {
10977                pw.println("-------------------------------------------------------------------------------");
10978            }
10979            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10980            pw.println();
10981            if (dumpAll) {
10982                pw.println("-------------------------------------------------------------------------------");
10983            }
10984            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10985            pw.println();
10986            if (dumpAll) {
10987                pw.println("-------------------------------------------------------------------------------");
10988            }
10989            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10990            pw.println();
10991            if (dumpAll) {
10992                pw.println("-------------------------------------------------------------------------------");
10993            }
10994            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10995            pw.println();
10996            if (dumpAll) {
10997                pw.println("-------------------------------------------------------------------------------");
10998            }
10999            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11000        }
11001        Binder.restoreCallingIdentity(origId);
11002    }
11003
11004    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11005            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11006        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11007
11008        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11009                dumpPackage);
11010        boolean needSep = printedAnything;
11011
11012        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11013                dumpPackage, needSep, "  mFocusedActivity: ");
11014        if (printed) {
11015            printedAnything = true;
11016            needSep = false;
11017        }
11018
11019        if (dumpPackage == null) {
11020            if (needSep) {
11021                pw.println();
11022            }
11023            needSep = true;
11024            printedAnything = true;
11025            mStackSupervisor.dump(pw, "  ");
11026        }
11027
11028        if (mRecentTasks.size() > 0) {
11029            boolean printedHeader = false;
11030
11031            final int N = mRecentTasks.size();
11032            for (int i=0; i<N; i++) {
11033                TaskRecord tr = mRecentTasks.get(i);
11034                if (dumpPackage != null) {
11035                    if (tr.realActivity == null ||
11036                            !dumpPackage.equals(tr.realActivity)) {
11037                        continue;
11038                    }
11039                }
11040                if (!printedHeader) {
11041                    if (needSep) {
11042                        pw.println();
11043                    }
11044                    pw.println("  Recent tasks:");
11045                    printedHeader = true;
11046                    printedAnything = true;
11047                }
11048                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11049                        pw.println(tr);
11050                if (dumpAll) {
11051                    mRecentTasks.get(i).dump(pw, "    ");
11052                }
11053            }
11054        }
11055
11056        if (!printedAnything) {
11057            pw.println("  (nothing)");
11058        }
11059    }
11060
11061    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11062            int opti, boolean dumpAll, String dumpPackage) {
11063        boolean needSep = false;
11064        boolean printedAnything = false;
11065        int numPers = 0;
11066
11067        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11068
11069        if (dumpAll) {
11070            final int NP = mProcessNames.getMap().size();
11071            for (int ip=0; ip<NP; ip++) {
11072                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11073                final int NA = procs.size();
11074                for (int ia=0; ia<NA; ia++) {
11075                    ProcessRecord r = procs.valueAt(ia);
11076                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11077                        continue;
11078                    }
11079                    if (!needSep) {
11080                        pw.println("  All known processes:");
11081                        needSep = true;
11082                        printedAnything = true;
11083                    }
11084                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11085                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11086                        pw.print(" "); pw.println(r);
11087                    r.dump(pw, "    ");
11088                    if (r.persistent) {
11089                        numPers++;
11090                    }
11091                }
11092            }
11093        }
11094
11095        if (mIsolatedProcesses.size() > 0) {
11096            boolean printed = false;
11097            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11098                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11099                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11100                    continue;
11101                }
11102                if (!printed) {
11103                    if (needSep) {
11104                        pw.println();
11105                    }
11106                    pw.println("  Isolated process list (sorted by uid):");
11107                    printedAnything = true;
11108                    printed = true;
11109                    needSep = true;
11110                }
11111                pw.println(String.format("%sIsolated #%2d: %s",
11112                        "    ", i, r.toString()));
11113            }
11114        }
11115
11116        if (mLruProcesses.size() > 0) {
11117            if (needSep) {
11118                pw.println();
11119            }
11120            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11121                    pw.print(" total, non-act at ");
11122                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11123                    pw.print(", non-svc at ");
11124                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11125                    pw.println("):");
11126            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11127            needSep = true;
11128            printedAnything = true;
11129        }
11130
11131        if (dumpAll || dumpPackage != null) {
11132            synchronized (mPidsSelfLocked) {
11133                boolean printed = false;
11134                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11135                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11136                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11137                        continue;
11138                    }
11139                    if (!printed) {
11140                        if (needSep) pw.println();
11141                        needSep = true;
11142                        pw.println("  PID mappings:");
11143                        printed = true;
11144                        printedAnything = true;
11145                    }
11146                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11147                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11148                }
11149            }
11150        }
11151
11152        if (mForegroundProcesses.size() > 0) {
11153            synchronized (mPidsSelfLocked) {
11154                boolean printed = false;
11155                for (int i=0; i<mForegroundProcesses.size(); i++) {
11156                    ProcessRecord r = mPidsSelfLocked.get(
11157                            mForegroundProcesses.valueAt(i).pid);
11158                    if (dumpPackage != null && (r == null
11159                            || !r.pkgList.containsKey(dumpPackage))) {
11160                        continue;
11161                    }
11162                    if (!printed) {
11163                        if (needSep) pw.println();
11164                        needSep = true;
11165                        pw.println("  Foreground Processes:");
11166                        printed = true;
11167                        printedAnything = true;
11168                    }
11169                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11170                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11171                }
11172            }
11173        }
11174
11175        if (mPersistentStartingProcesses.size() > 0) {
11176            if (needSep) pw.println();
11177            needSep = true;
11178            printedAnything = true;
11179            pw.println("  Persisent processes that are starting:");
11180            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11181                    "Starting Norm", "Restarting PERS", dumpPackage);
11182        }
11183
11184        if (mRemovedProcesses.size() > 0) {
11185            if (needSep) pw.println();
11186            needSep = true;
11187            printedAnything = true;
11188            pw.println("  Processes that are being removed:");
11189            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11190                    "Removed Norm", "Removed PERS", dumpPackage);
11191        }
11192
11193        if (mProcessesOnHold.size() > 0) {
11194            if (needSep) pw.println();
11195            needSep = true;
11196            printedAnything = true;
11197            pw.println("  Processes that are on old until the system is ready:");
11198            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11199                    "OnHold Norm", "OnHold PERS", dumpPackage);
11200        }
11201
11202        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11203
11204        if (mProcessCrashTimes.getMap().size() > 0) {
11205            boolean printed = false;
11206            long now = SystemClock.uptimeMillis();
11207            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11208            final int NP = pmap.size();
11209            for (int ip=0; ip<NP; ip++) {
11210                String pname = pmap.keyAt(ip);
11211                SparseArray<Long> uids = pmap.valueAt(ip);
11212                final int N = uids.size();
11213                for (int i=0; i<N; i++) {
11214                    int puid = uids.keyAt(i);
11215                    ProcessRecord r = mProcessNames.get(pname, puid);
11216                    if (dumpPackage != null && (r == null
11217                            || !r.pkgList.containsKey(dumpPackage))) {
11218                        continue;
11219                    }
11220                    if (!printed) {
11221                        if (needSep) pw.println();
11222                        needSep = true;
11223                        pw.println("  Time since processes crashed:");
11224                        printed = true;
11225                        printedAnything = true;
11226                    }
11227                    pw.print("    Process "); pw.print(pname);
11228                            pw.print(" uid "); pw.print(puid);
11229                            pw.print(": last crashed ");
11230                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11231                            pw.println(" ago");
11232                }
11233            }
11234        }
11235
11236        if (mBadProcesses.getMap().size() > 0) {
11237            boolean printed = false;
11238            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11239            final int NP = pmap.size();
11240            for (int ip=0; ip<NP; ip++) {
11241                String pname = pmap.keyAt(ip);
11242                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11243                final int N = uids.size();
11244                for (int i=0; i<N; i++) {
11245                    int puid = uids.keyAt(i);
11246                    ProcessRecord r = mProcessNames.get(pname, puid);
11247                    if (dumpPackage != null && (r == null
11248                            || !r.pkgList.containsKey(dumpPackage))) {
11249                        continue;
11250                    }
11251                    if (!printed) {
11252                        if (needSep) pw.println();
11253                        needSep = true;
11254                        pw.println("  Bad processes:");
11255                        printedAnything = true;
11256                    }
11257                    BadProcessInfo info = uids.valueAt(i);
11258                    pw.print("    Bad process "); pw.print(pname);
11259                            pw.print(" uid "); pw.print(puid);
11260                            pw.print(": crashed at time "); pw.println(info.time);
11261                    if (info.shortMsg != null) {
11262                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11263                    }
11264                    if (info.longMsg != null) {
11265                        pw.print("      Long msg: "); pw.println(info.longMsg);
11266                    }
11267                    if (info.stack != null) {
11268                        pw.println("      Stack:");
11269                        int lastPos = 0;
11270                        for (int pos=0; pos<info.stack.length(); pos++) {
11271                            if (info.stack.charAt(pos) == '\n') {
11272                                pw.print("        ");
11273                                pw.write(info.stack, lastPos, pos-lastPos);
11274                                pw.println();
11275                                lastPos = pos+1;
11276                            }
11277                        }
11278                        if (lastPos < info.stack.length()) {
11279                            pw.print("        ");
11280                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11281                            pw.println();
11282                        }
11283                    }
11284                }
11285            }
11286        }
11287
11288        if (dumpPackage == null) {
11289            pw.println();
11290            needSep = false;
11291            pw.println("  mStartedUsers:");
11292            for (int i=0; i<mStartedUsers.size(); i++) {
11293                UserStartedState uss = mStartedUsers.valueAt(i);
11294                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11295                        pw.print(": "); uss.dump("", pw);
11296            }
11297            pw.print("  mStartedUserArray: [");
11298            for (int i=0; i<mStartedUserArray.length; i++) {
11299                if (i > 0) pw.print(", ");
11300                pw.print(mStartedUserArray[i]);
11301            }
11302            pw.println("]");
11303            pw.print("  mUserLru: [");
11304            for (int i=0; i<mUserLru.size(); i++) {
11305                if (i > 0) pw.print(", ");
11306                pw.print(mUserLru.get(i));
11307            }
11308            pw.println("]");
11309            if (dumpAll) {
11310                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11311            }
11312        }
11313        if (mHomeProcess != null && (dumpPackage == null
11314                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11315            if (needSep) {
11316                pw.println();
11317                needSep = false;
11318            }
11319            pw.println("  mHomeProcess: " + mHomeProcess);
11320        }
11321        if (mPreviousProcess != null && (dumpPackage == null
11322                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11323            if (needSep) {
11324                pw.println();
11325                needSep = false;
11326            }
11327            pw.println("  mPreviousProcess: " + mPreviousProcess);
11328        }
11329        if (dumpAll) {
11330            StringBuilder sb = new StringBuilder(128);
11331            sb.append("  mPreviousProcessVisibleTime: ");
11332            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11333            pw.println(sb);
11334        }
11335        if (mHeavyWeightProcess != null && (dumpPackage == null
11336                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11337            if (needSep) {
11338                pw.println();
11339                needSep = false;
11340            }
11341            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11342        }
11343        if (dumpPackage == null) {
11344            pw.println("  mConfiguration: " + mConfiguration);
11345        }
11346        if (dumpAll) {
11347            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11348            if (mCompatModePackages.getPackages().size() > 0) {
11349                boolean printed = false;
11350                for (Map.Entry<String, Integer> entry
11351                        : mCompatModePackages.getPackages().entrySet()) {
11352                    String pkg = entry.getKey();
11353                    int mode = entry.getValue();
11354                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11355                        continue;
11356                    }
11357                    if (!printed) {
11358                        pw.println("  mScreenCompatPackages:");
11359                        printed = true;
11360                    }
11361                    pw.print("    "); pw.print(pkg); pw.print(": ");
11362                            pw.print(mode); pw.println();
11363                }
11364            }
11365        }
11366        if (dumpPackage == null) {
11367            if (mSleeping || mWentToSleep || mLockScreenShown) {
11368                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11369                        + " mLockScreenShown " + mLockScreenShown);
11370            }
11371            if (mShuttingDown || mRunningVoice) {
11372                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11373            }
11374        }
11375        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11376                || mOrigWaitForDebugger) {
11377            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11378                    || dumpPackage.equals(mOrigDebugApp)) {
11379                if (needSep) {
11380                    pw.println();
11381                    needSep = false;
11382                }
11383                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11384                        + " mDebugTransient=" + mDebugTransient
11385                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11386            }
11387        }
11388        if (mOpenGlTraceApp != null) {
11389            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11390                if (needSep) {
11391                    pw.println();
11392                    needSep = false;
11393                }
11394                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11395            }
11396        }
11397        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11398                || mProfileFd != null) {
11399            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11400                if (needSep) {
11401                    pw.println();
11402                    needSep = false;
11403                }
11404                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11405                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11406                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11407                        + mAutoStopProfiler);
11408            }
11409        }
11410        if (dumpPackage == null) {
11411            if (mAlwaysFinishActivities || mController != null) {
11412                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11413                        + " mController=" + mController);
11414            }
11415            if (dumpAll) {
11416                pw.println("  Total persistent processes: " + numPers);
11417                pw.println("  mProcessesReady=" + mProcessesReady
11418                        + " mSystemReady=" + mSystemReady);
11419                pw.println("  mBooting=" + mBooting
11420                        + " mBooted=" + mBooted
11421                        + " mFactoryTest=" + mFactoryTest);
11422                pw.print("  mLastPowerCheckRealtime=");
11423                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11424                        pw.println("");
11425                pw.print("  mLastPowerCheckUptime=");
11426                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11427                        pw.println("");
11428                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11429                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11430                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11431                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11432                        + " (" + mLruProcesses.size() + " total)"
11433                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11434                        + " mNumServiceProcs=" + mNumServiceProcs
11435                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11436                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11437                        + " mLastMemoryLevel" + mLastMemoryLevel
11438                        + " mLastNumProcesses" + mLastNumProcesses);
11439                long now = SystemClock.uptimeMillis();
11440                pw.print("  mLastIdleTime=");
11441                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11442                        pw.print(" mLowRamSinceLastIdle=");
11443                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11444                        pw.println();
11445            }
11446        }
11447
11448        if (!printedAnything) {
11449            pw.println("  (nothing)");
11450        }
11451    }
11452
11453    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11454            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11455        if (mProcessesToGc.size() > 0) {
11456            boolean printed = false;
11457            long now = SystemClock.uptimeMillis();
11458            for (int i=0; i<mProcessesToGc.size(); i++) {
11459                ProcessRecord proc = mProcessesToGc.get(i);
11460                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11461                    continue;
11462                }
11463                if (!printed) {
11464                    if (needSep) pw.println();
11465                    needSep = true;
11466                    pw.println("  Processes that are waiting to GC:");
11467                    printed = true;
11468                }
11469                pw.print("    Process "); pw.println(proc);
11470                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11471                        pw.print(", last gced=");
11472                        pw.print(now-proc.lastRequestedGc);
11473                        pw.print(" ms ago, last lowMem=");
11474                        pw.print(now-proc.lastLowMemory);
11475                        pw.println(" ms ago");
11476
11477            }
11478        }
11479        return needSep;
11480    }
11481
11482    void printOomLevel(PrintWriter pw, String name, int adj) {
11483        pw.print("    ");
11484        if (adj >= 0) {
11485            pw.print(' ');
11486            if (adj < 10) pw.print(' ');
11487        } else {
11488            if (adj > -10) pw.print(' ');
11489        }
11490        pw.print(adj);
11491        pw.print(": ");
11492        pw.print(name);
11493        pw.print(" (");
11494        pw.print(mProcessList.getMemLevel(adj)/1024);
11495        pw.println(" kB)");
11496    }
11497
11498    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11499            int opti, boolean dumpAll) {
11500        boolean needSep = false;
11501
11502        if (mLruProcesses.size() > 0) {
11503            if (needSep) pw.println();
11504            needSep = true;
11505            pw.println("  OOM levels:");
11506            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11507            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11508            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11509            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11510            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11511            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11512            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11513            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11514            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11515            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11516            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11517            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11518            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11519
11520            if (needSep) pw.println();
11521            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11522                    pw.print(" total, non-act at ");
11523                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11524                    pw.print(", non-svc at ");
11525                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11526                    pw.println("):");
11527            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11528            needSep = true;
11529        }
11530
11531        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11532
11533        pw.println();
11534        pw.println("  mHomeProcess: " + mHomeProcess);
11535        pw.println("  mPreviousProcess: " + mPreviousProcess);
11536        if (mHeavyWeightProcess != null) {
11537            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11538        }
11539
11540        return true;
11541    }
11542
11543    /**
11544     * There are three ways to call this:
11545     *  - no provider specified: dump all the providers
11546     *  - a flattened component name that matched an existing provider was specified as the
11547     *    first arg: dump that one provider
11548     *  - the first arg isn't the flattened component name of an existing provider:
11549     *    dump all providers whose component contains the first arg as a substring
11550     */
11551    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11552            int opti, boolean dumpAll) {
11553        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11554    }
11555
11556    static class ItemMatcher {
11557        ArrayList<ComponentName> components;
11558        ArrayList<String> strings;
11559        ArrayList<Integer> objects;
11560        boolean all;
11561
11562        ItemMatcher() {
11563            all = true;
11564        }
11565
11566        void build(String name) {
11567            ComponentName componentName = ComponentName.unflattenFromString(name);
11568            if (componentName != null) {
11569                if (components == null) {
11570                    components = new ArrayList<ComponentName>();
11571                }
11572                components.add(componentName);
11573                all = false;
11574            } else {
11575                int objectId = 0;
11576                // Not a '/' separated full component name; maybe an object ID?
11577                try {
11578                    objectId = Integer.parseInt(name, 16);
11579                    if (objects == null) {
11580                        objects = new ArrayList<Integer>();
11581                    }
11582                    objects.add(objectId);
11583                    all = false;
11584                } catch (RuntimeException e) {
11585                    // Not an integer; just do string match.
11586                    if (strings == null) {
11587                        strings = new ArrayList<String>();
11588                    }
11589                    strings.add(name);
11590                    all = false;
11591                }
11592            }
11593        }
11594
11595        int build(String[] args, int opti) {
11596            for (; opti<args.length; opti++) {
11597                String name = args[opti];
11598                if ("--".equals(name)) {
11599                    return opti+1;
11600                }
11601                build(name);
11602            }
11603            return opti;
11604        }
11605
11606        boolean match(Object object, ComponentName comp) {
11607            if (all) {
11608                return true;
11609            }
11610            if (components != null) {
11611                for (int i=0; i<components.size(); i++) {
11612                    if (components.get(i).equals(comp)) {
11613                        return true;
11614                    }
11615                }
11616            }
11617            if (objects != null) {
11618                for (int i=0; i<objects.size(); i++) {
11619                    if (System.identityHashCode(object) == objects.get(i)) {
11620                        return true;
11621                    }
11622                }
11623            }
11624            if (strings != null) {
11625                String flat = comp.flattenToString();
11626                for (int i=0; i<strings.size(); i++) {
11627                    if (flat.contains(strings.get(i))) {
11628                        return true;
11629                    }
11630                }
11631            }
11632            return false;
11633        }
11634    }
11635
11636    /**
11637     * There are three things that cmd can be:
11638     *  - a flattened component name that matches an existing activity
11639     *  - the cmd arg isn't the flattened component name of an existing activity:
11640     *    dump all activity whose component contains the cmd as a substring
11641     *  - A hex number of the ActivityRecord object instance.
11642     */
11643    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11644            int opti, boolean dumpAll) {
11645        ArrayList<ActivityRecord> activities;
11646
11647        synchronized (this) {
11648            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11649        }
11650
11651        if (activities.size() <= 0) {
11652            return false;
11653        }
11654
11655        String[] newArgs = new String[args.length - opti];
11656        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11657
11658        TaskRecord lastTask = null;
11659        boolean needSep = false;
11660        for (int i=activities.size()-1; i>=0; i--) {
11661            ActivityRecord r = activities.get(i);
11662            if (needSep) {
11663                pw.println();
11664            }
11665            needSep = true;
11666            synchronized (this) {
11667                if (lastTask != r.task) {
11668                    lastTask = r.task;
11669                    pw.print("TASK "); pw.print(lastTask.affinity);
11670                            pw.print(" id="); pw.println(lastTask.taskId);
11671                    if (dumpAll) {
11672                        lastTask.dump(pw, "  ");
11673                    }
11674                }
11675            }
11676            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11677        }
11678        return true;
11679    }
11680
11681    /**
11682     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11683     * there is a thread associated with the activity.
11684     */
11685    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11686            final ActivityRecord r, String[] args, boolean dumpAll) {
11687        String innerPrefix = prefix + "  ";
11688        synchronized (this) {
11689            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11690                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11691                    pw.print(" pid=");
11692                    if (r.app != null) pw.println(r.app.pid);
11693                    else pw.println("(not running)");
11694            if (dumpAll) {
11695                r.dump(pw, innerPrefix);
11696            }
11697        }
11698        if (r.app != null && r.app.thread != null) {
11699            // flush anything that is already in the PrintWriter since the thread is going
11700            // to write to the file descriptor directly
11701            pw.flush();
11702            try {
11703                TransferPipe tp = new TransferPipe();
11704                try {
11705                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11706                            r.appToken, innerPrefix, args);
11707                    tp.go(fd);
11708                } finally {
11709                    tp.kill();
11710                }
11711            } catch (IOException e) {
11712                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11713            } catch (RemoteException e) {
11714                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11715            }
11716        }
11717    }
11718
11719    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11720            int opti, boolean dumpAll, String dumpPackage) {
11721        boolean needSep = false;
11722        boolean onlyHistory = false;
11723        boolean printedAnything = false;
11724
11725        if ("history".equals(dumpPackage)) {
11726            if (opti < args.length && "-s".equals(args[opti])) {
11727                dumpAll = false;
11728            }
11729            onlyHistory = true;
11730            dumpPackage = null;
11731        }
11732
11733        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11734        if (!onlyHistory && dumpAll) {
11735            if (mRegisteredReceivers.size() > 0) {
11736                boolean printed = false;
11737                Iterator it = mRegisteredReceivers.values().iterator();
11738                while (it.hasNext()) {
11739                    ReceiverList r = (ReceiverList)it.next();
11740                    if (dumpPackage != null && (r.app == null ||
11741                            !dumpPackage.equals(r.app.info.packageName))) {
11742                        continue;
11743                    }
11744                    if (!printed) {
11745                        pw.println("  Registered Receivers:");
11746                        needSep = true;
11747                        printed = true;
11748                        printedAnything = true;
11749                    }
11750                    pw.print("  * "); pw.println(r);
11751                    r.dump(pw, "    ");
11752                }
11753            }
11754
11755            if (mReceiverResolver.dump(pw, needSep ?
11756                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11757                    "    ", dumpPackage, false)) {
11758                needSep = true;
11759                printedAnything = true;
11760            }
11761        }
11762
11763        for (BroadcastQueue q : mBroadcastQueues) {
11764            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11765            printedAnything |= needSep;
11766        }
11767
11768        needSep = true;
11769
11770        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11771            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11772                if (needSep) {
11773                    pw.println();
11774                }
11775                needSep = true;
11776                printedAnything = true;
11777                pw.print("  Sticky broadcasts for user ");
11778                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11779                StringBuilder sb = new StringBuilder(128);
11780                for (Map.Entry<String, ArrayList<Intent>> ent
11781                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11782                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11783                    if (dumpAll) {
11784                        pw.println(":");
11785                        ArrayList<Intent> intents = ent.getValue();
11786                        final int N = intents.size();
11787                        for (int i=0; i<N; i++) {
11788                            sb.setLength(0);
11789                            sb.append("    Intent: ");
11790                            intents.get(i).toShortString(sb, false, true, false, false);
11791                            pw.println(sb.toString());
11792                            Bundle bundle = intents.get(i).getExtras();
11793                            if (bundle != null) {
11794                                pw.print("      ");
11795                                pw.println(bundle.toString());
11796                            }
11797                        }
11798                    } else {
11799                        pw.println("");
11800                    }
11801                }
11802            }
11803        }
11804
11805        if (!onlyHistory && dumpAll) {
11806            pw.println();
11807            for (BroadcastQueue queue : mBroadcastQueues) {
11808                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11809                        + queue.mBroadcastsScheduled);
11810            }
11811            pw.println("  mHandler:");
11812            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11813            needSep = true;
11814            printedAnything = true;
11815        }
11816
11817        if (!printedAnything) {
11818            pw.println("  (nothing)");
11819        }
11820    }
11821
11822    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11823            int opti, boolean dumpAll, String dumpPackage) {
11824        boolean needSep;
11825        boolean printedAnything = false;
11826
11827        ItemMatcher matcher = new ItemMatcher();
11828        matcher.build(args, opti);
11829
11830        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11831
11832        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11833        printedAnything |= needSep;
11834
11835        if (mLaunchingProviders.size() > 0) {
11836            boolean printed = false;
11837            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11838                ContentProviderRecord r = mLaunchingProviders.get(i);
11839                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11840                    continue;
11841                }
11842                if (!printed) {
11843                    if (needSep) pw.println();
11844                    needSep = true;
11845                    pw.println("  Launching content providers:");
11846                    printed = true;
11847                    printedAnything = true;
11848                }
11849                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11850                        pw.println(r);
11851            }
11852        }
11853
11854        if (mGrantedUriPermissions.size() > 0) {
11855            boolean printed = false;
11856            int dumpUid = -2;
11857            if (dumpPackage != null) {
11858                try {
11859                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11860                } catch (NameNotFoundException e) {
11861                    dumpUid = -1;
11862                }
11863            }
11864            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11865                int uid = mGrantedUriPermissions.keyAt(i);
11866                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11867                    continue;
11868                }
11869                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11870                if (!printed) {
11871                    if (needSep) pw.println();
11872                    needSep = true;
11873                    pw.println("  Granted Uri Permissions:");
11874                    printed = true;
11875                    printedAnything = true;
11876                }
11877                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11878                for (UriPermission perm : perms.values()) {
11879                    pw.print("    "); pw.println(perm);
11880                    if (dumpAll) {
11881                        perm.dump(pw, "      ");
11882                    }
11883                }
11884            }
11885        }
11886
11887        if (!printedAnything) {
11888            pw.println("  (nothing)");
11889        }
11890    }
11891
11892    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11893            int opti, boolean dumpAll, String dumpPackage) {
11894        boolean printed = false;
11895
11896        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11897
11898        if (mIntentSenderRecords.size() > 0) {
11899            Iterator<WeakReference<PendingIntentRecord>> it
11900                    = mIntentSenderRecords.values().iterator();
11901            while (it.hasNext()) {
11902                WeakReference<PendingIntentRecord> ref = it.next();
11903                PendingIntentRecord rec = ref != null ? ref.get(): null;
11904                if (dumpPackage != null && (rec == null
11905                        || !dumpPackage.equals(rec.key.packageName))) {
11906                    continue;
11907                }
11908                printed = true;
11909                if (rec != null) {
11910                    pw.print("  * "); pw.println(rec);
11911                    if (dumpAll) {
11912                        rec.dump(pw, "    ");
11913                    }
11914                } else {
11915                    pw.print("  * "); pw.println(ref);
11916                }
11917            }
11918        }
11919
11920        if (!printed) {
11921            pw.println("  (nothing)");
11922        }
11923    }
11924
11925    private static final int dumpProcessList(PrintWriter pw,
11926            ActivityManagerService service, List list,
11927            String prefix, String normalLabel, String persistentLabel,
11928            String dumpPackage) {
11929        int numPers = 0;
11930        final int N = list.size()-1;
11931        for (int i=N; i>=0; i--) {
11932            ProcessRecord r = (ProcessRecord)list.get(i);
11933            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11934                continue;
11935            }
11936            pw.println(String.format("%s%s #%2d: %s",
11937                    prefix, (r.persistent ? persistentLabel : normalLabel),
11938                    i, r.toString()));
11939            if (r.persistent) {
11940                numPers++;
11941            }
11942        }
11943        return numPers;
11944    }
11945
11946    private static final boolean dumpProcessOomList(PrintWriter pw,
11947            ActivityManagerService service, List<ProcessRecord> origList,
11948            String prefix, String normalLabel, String persistentLabel,
11949            boolean inclDetails, String dumpPackage) {
11950
11951        ArrayList<Pair<ProcessRecord, Integer>> list
11952                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11953        for (int i=0; i<origList.size(); i++) {
11954            ProcessRecord r = origList.get(i);
11955            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11956                continue;
11957            }
11958            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11959        }
11960
11961        if (list.size() <= 0) {
11962            return false;
11963        }
11964
11965        Comparator<Pair<ProcessRecord, Integer>> comparator
11966                = new Comparator<Pair<ProcessRecord, Integer>>() {
11967            @Override
11968            public int compare(Pair<ProcessRecord, Integer> object1,
11969                    Pair<ProcessRecord, Integer> object2) {
11970                if (object1.first.setAdj != object2.first.setAdj) {
11971                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11972                }
11973                if (object1.second.intValue() != object2.second.intValue()) {
11974                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11975                }
11976                return 0;
11977            }
11978        };
11979
11980        Collections.sort(list, comparator);
11981
11982        final long curRealtime = SystemClock.elapsedRealtime();
11983        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11984        final long curUptime = SystemClock.uptimeMillis();
11985        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11986
11987        for (int i=list.size()-1; i>=0; i--) {
11988            ProcessRecord r = list.get(i).first;
11989            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11990            char schedGroup;
11991            switch (r.setSchedGroup) {
11992                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11993                    schedGroup = 'B';
11994                    break;
11995                case Process.THREAD_GROUP_DEFAULT:
11996                    schedGroup = 'F';
11997                    break;
11998                default:
11999                    schedGroup = '?';
12000                    break;
12001            }
12002            char foreground;
12003            if (r.foregroundActivities) {
12004                foreground = 'A';
12005            } else if (r.foregroundServices) {
12006                foreground = 'S';
12007            } else {
12008                foreground = ' ';
12009            }
12010            String procState = ProcessList.makeProcStateString(r.curProcState);
12011            pw.print(prefix);
12012            pw.print(r.persistent ? persistentLabel : normalLabel);
12013            pw.print(" #");
12014            int num = (origList.size()-1)-list.get(i).second;
12015            if (num < 10) pw.print(' ');
12016            pw.print(num);
12017            pw.print(": ");
12018            pw.print(oomAdj);
12019            pw.print(' ');
12020            pw.print(schedGroup);
12021            pw.print('/');
12022            pw.print(foreground);
12023            pw.print('/');
12024            pw.print(procState);
12025            pw.print(" trm:");
12026            if (r.trimMemoryLevel < 10) pw.print(' ');
12027            pw.print(r.trimMemoryLevel);
12028            pw.print(' ');
12029            pw.print(r.toShortString());
12030            pw.print(" (");
12031            pw.print(r.adjType);
12032            pw.println(')');
12033            if (r.adjSource != null || r.adjTarget != null) {
12034                pw.print(prefix);
12035                pw.print("    ");
12036                if (r.adjTarget instanceof ComponentName) {
12037                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12038                } else if (r.adjTarget != null) {
12039                    pw.print(r.adjTarget.toString());
12040                } else {
12041                    pw.print("{null}");
12042                }
12043                pw.print("<=");
12044                if (r.adjSource instanceof ProcessRecord) {
12045                    pw.print("Proc{");
12046                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12047                    pw.println("}");
12048                } else if (r.adjSource != null) {
12049                    pw.println(r.adjSource.toString());
12050                } else {
12051                    pw.println("{null}");
12052                }
12053            }
12054            if (inclDetails) {
12055                pw.print(prefix);
12056                pw.print("    ");
12057                pw.print("oom: max="); pw.print(r.maxAdj);
12058                pw.print(" curRaw="); pw.print(r.curRawAdj);
12059                pw.print(" setRaw="); pw.print(r.setRawAdj);
12060                pw.print(" cur="); pw.print(r.curAdj);
12061                pw.print(" set="); pw.println(r.setAdj);
12062                pw.print(prefix);
12063                pw.print("    ");
12064                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12065                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12066                pw.print(" lastPss="); pw.print(r.lastPss);
12067                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12068                pw.print(prefix);
12069                pw.print("    ");
12070                pw.print("keeping="); pw.print(r.keeping);
12071                pw.print(" cached="); pw.print(r.cached);
12072                pw.print(" empty="); pw.print(r.empty);
12073                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12074
12075                if (!r.keeping) {
12076                    if (r.lastWakeTime != 0) {
12077                        long wtime;
12078                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12079                        synchronized (stats) {
12080                            wtime = stats.getProcessWakeTime(r.info.uid,
12081                                    r.pid, curRealtime);
12082                        }
12083                        long timeUsed = wtime - r.lastWakeTime;
12084                        pw.print(prefix);
12085                        pw.print("    ");
12086                        pw.print("keep awake over ");
12087                        TimeUtils.formatDuration(realtimeSince, pw);
12088                        pw.print(" used ");
12089                        TimeUtils.formatDuration(timeUsed, pw);
12090                        pw.print(" (");
12091                        pw.print((timeUsed*100)/realtimeSince);
12092                        pw.println("%)");
12093                    }
12094                    if (r.lastCpuTime != 0) {
12095                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12096                        pw.print(prefix);
12097                        pw.print("    ");
12098                        pw.print("run cpu over ");
12099                        TimeUtils.formatDuration(uptimeSince, pw);
12100                        pw.print(" used ");
12101                        TimeUtils.formatDuration(timeUsed, pw);
12102                        pw.print(" (");
12103                        pw.print((timeUsed*100)/uptimeSince);
12104                        pw.println("%)");
12105                    }
12106                }
12107            }
12108        }
12109        return true;
12110    }
12111
12112    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12113        ArrayList<ProcessRecord> procs;
12114        synchronized (this) {
12115            if (args != null && args.length > start
12116                    && args[start].charAt(0) != '-') {
12117                procs = new ArrayList<ProcessRecord>();
12118                int pid = -1;
12119                try {
12120                    pid = Integer.parseInt(args[start]);
12121                } catch (NumberFormatException e) {
12122                }
12123                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12124                    ProcessRecord proc = mLruProcesses.get(i);
12125                    if (proc.pid == pid) {
12126                        procs.add(proc);
12127                    } else if (proc.processName.equals(args[start])) {
12128                        procs.add(proc);
12129                    }
12130                }
12131                if (procs.size() <= 0) {
12132                    return null;
12133                }
12134            } else {
12135                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12136            }
12137        }
12138        return procs;
12139    }
12140
12141    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12142            PrintWriter pw, String[] args) {
12143        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12144        if (procs == null) {
12145            pw.println("No process found for: " + args[0]);
12146            return;
12147        }
12148
12149        long uptime = SystemClock.uptimeMillis();
12150        long realtime = SystemClock.elapsedRealtime();
12151        pw.println("Applications Graphics Acceleration Info:");
12152        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12153
12154        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12155            ProcessRecord r = procs.get(i);
12156            if (r.thread != null) {
12157                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12158                pw.flush();
12159                try {
12160                    TransferPipe tp = new TransferPipe();
12161                    try {
12162                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12163                        tp.go(fd);
12164                    } finally {
12165                        tp.kill();
12166                    }
12167                } catch (IOException e) {
12168                    pw.println("Failure while dumping the app: " + r);
12169                    pw.flush();
12170                } catch (RemoteException e) {
12171                    pw.println("Got a RemoteException while dumping the app " + r);
12172                    pw.flush();
12173                }
12174            }
12175        }
12176    }
12177
12178    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12179        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12180        if (procs == null) {
12181            pw.println("No process found for: " + args[0]);
12182            return;
12183        }
12184
12185        pw.println("Applications Database Info:");
12186
12187        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12188            ProcessRecord r = procs.get(i);
12189            if (r.thread != null) {
12190                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12191                pw.flush();
12192                try {
12193                    TransferPipe tp = new TransferPipe();
12194                    try {
12195                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12196                        tp.go(fd);
12197                    } finally {
12198                        tp.kill();
12199                    }
12200                } catch (IOException e) {
12201                    pw.println("Failure while dumping the app: " + r);
12202                    pw.flush();
12203                } catch (RemoteException e) {
12204                    pw.println("Got a RemoteException while dumping the app " + r);
12205                    pw.flush();
12206                }
12207            }
12208        }
12209    }
12210
12211    final static class MemItem {
12212        final boolean isProc;
12213        final String label;
12214        final String shortLabel;
12215        final long pss;
12216        final int id;
12217        final boolean hasActivities;
12218        ArrayList<MemItem> subitems;
12219
12220        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12221                boolean _hasActivities) {
12222            isProc = true;
12223            label = _label;
12224            shortLabel = _shortLabel;
12225            pss = _pss;
12226            id = _id;
12227            hasActivities = _hasActivities;
12228        }
12229
12230        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12231            isProc = false;
12232            label = _label;
12233            shortLabel = _shortLabel;
12234            pss = _pss;
12235            id = _id;
12236            hasActivities = false;
12237        }
12238    }
12239
12240    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12241            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12242        if (sort && !isCompact) {
12243            Collections.sort(items, new Comparator<MemItem>() {
12244                @Override
12245                public int compare(MemItem lhs, MemItem rhs) {
12246                    if (lhs.pss < rhs.pss) {
12247                        return 1;
12248                    } else if (lhs.pss > rhs.pss) {
12249                        return -1;
12250                    }
12251                    return 0;
12252                }
12253            });
12254        }
12255
12256        for (int i=0; i<items.size(); i++) {
12257            MemItem mi = items.get(i);
12258            if (!isCompact) {
12259                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12260            } else if (mi.isProc) {
12261                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12262                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12263                pw.println(mi.hasActivities ? ",a" : ",e");
12264            } else {
12265                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12266                pw.println(mi.pss);
12267            }
12268            if (mi.subitems != null) {
12269                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12270                        true, isCompact);
12271            }
12272        }
12273    }
12274
12275    // These are in KB.
12276    static final long[] DUMP_MEM_BUCKETS = new long[] {
12277        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12278        120*1024, 160*1024, 200*1024,
12279        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12280        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12281    };
12282
12283    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12284            boolean stackLike) {
12285        int start = label.lastIndexOf('.');
12286        if (start >= 0) start++;
12287        else start = 0;
12288        int end = label.length();
12289        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12290            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12291                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12292                out.append(bucket);
12293                out.append(stackLike ? "MB." : "MB ");
12294                out.append(label, start, end);
12295                return;
12296            }
12297        }
12298        out.append(memKB/1024);
12299        out.append(stackLike ? "MB." : "MB ");
12300        out.append(label, start, end);
12301    }
12302
12303    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12304            ProcessList.NATIVE_ADJ,
12305            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12306            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12307            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12308            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12309            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12310    };
12311    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12312            "Native",
12313            "System", "Persistent", "Foreground",
12314            "Visible", "Perceptible",
12315            "Heavy Weight", "Backup",
12316            "A Services", "Home",
12317            "Previous", "B Services", "Cached"
12318    };
12319    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12320            "native",
12321            "sys", "pers", "fore",
12322            "vis", "percept",
12323            "heavy", "backup",
12324            "servicea", "home",
12325            "prev", "serviceb", "cached"
12326    };
12327
12328    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12329            long realtime, boolean isCheckinRequest, boolean isCompact) {
12330        if (isCheckinRequest || isCompact) {
12331            // short checkin version
12332            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12333        } else {
12334            pw.println("Applications Memory Usage (kB):");
12335            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12336        }
12337    }
12338
12339    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12340            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12341        boolean dumpDetails = false;
12342        boolean dumpFullDetails = false;
12343        boolean dumpDalvik = false;
12344        boolean oomOnly = false;
12345        boolean isCompact = false;
12346        boolean localOnly = false;
12347
12348        int opti = 0;
12349        while (opti < args.length) {
12350            String opt = args[opti];
12351            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12352                break;
12353            }
12354            opti++;
12355            if ("-a".equals(opt)) {
12356                dumpDetails = true;
12357                dumpFullDetails = true;
12358                dumpDalvik = true;
12359            } else if ("-d".equals(opt)) {
12360                dumpDalvik = true;
12361            } else if ("-c".equals(opt)) {
12362                isCompact = true;
12363            } else if ("--oom".equals(opt)) {
12364                oomOnly = true;
12365            } else if ("--local".equals(opt)) {
12366                localOnly = true;
12367            } else if ("-h".equals(opt)) {
12368                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12369                pw.println("  -a: include all available information for each process.");
12370                pw.println("  -d: include dalvik details when dumping process details.");
12371                pw.println("  -c: dump in a compact machine-parseable representation.");
12372                pw.println("  --oom: only show processes organized by oom adj.");
12373                pw.println("  --local: only collect details locally, don't call process.");
12374                pw.println("If [process] is specified it can be the name or ");
12375                pw.println("pid of a specific process to dump.");
12376                return;
12377            } else {
12378                pw.println("Unknown argument: " + opt + "; use -h for help");
12379            }
12380        }
12381
12382        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12383        long uptime = SystemClock.uptimeMillis();
12384        long realtime = SystemClock.elapsedRealtime();
12385        final long[] tmpLong = new long[1];
12386
12387        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12388        if (procs == null) {
12389            // No Java processes.  Maybe they want to print a native process.
12390            if (args != null && args.length > opti
12391                    && args[opti].charAt(0) != '-') {
12392                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12393                        = new ArrayList<ProcessCpuTracker.Stats>();
12394                updateCpuStatsNow();
12395                int findPid = -1;
12396                try {
12397                    findPid = Integer.parseInt(args[opti]);
12398                } catch (NumberFormatException e) {
12399                }
12400                synchronized (mProcessCpuThread) {
12401                    final int N = mProcessCpuTracker.countStats();
12402                    for (int i=0; i<N; i++) {
12403                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12404                        if (st.pid == findPid || (st.baseName != null
12405                                && st.baseName.equals(args[opti]))) {
12406                            nativeProcs.add(st);
12407                        }
12408                    }
12409                }
12410                if (nativeProcs.size() > 0) {
12411                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12412                            isCompact);
12413                    Debug.MemoryInfo mi = null;
12414                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12415                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12416                        final int pid = r.pid;
12417                        if (!isCheckinRequest && dumpDetails) {
12418                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12419                        }
12420                        if (mi == null) {
12421                            mi = new Debug.MemoryInfo();
12422                        }
12423                        if (dumpDetails || (!brief && !oomOnly)) {
12424                            Debug.getMemoryInfo(pid, mi);
12425                        } else {
12426                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12427                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12428                        }
12429                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12430                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12431                        if (isCheckinRequest) {
12432                            pw.println();
12433                        }
12434                    }
12435                    return;
12436                }
12437            }
12438            pw.println("No process found for: " + args[opti]);
12439            return;
12440        }
12441
12442        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12443            dumpDetails = true;
12444        }
12445
12446        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12447
12448        String[] innerArgs = new String[args.length-opti];
12449        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12450
12451        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12452        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12453        long nativePss=0, dalvikPss=0, otherPss=0;
12454        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12455
12456        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12457        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12458                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12459
12460        long totalPss = 0;
12461        long cachedPss = 0;
12462
12463        Debug.MemoryInfo mi = null;
12464        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12465            final ProcessRecord r = procs.get(i);
12466            final IApplicationThread thread;
12467            final int pid;
12468            final int oomAdj;
12469            final boolean hasActivities;
12470            synchronized (this) {
12471                thread = r.thread;
12472                pid = r.pid;
12473                oomAdj = r.getSetAdjWithServices();
12474                hasActivities = r.activities.size() > 0;
12475            }
12476            if (thread != null) {
12477                if (!isCheckinRequest && dumpDetails) {
12478                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12479                }
12480                if (mi == null) {
12481                    mi = new Debug.MemoryInfo();
12482                }
12483                if (dumpDetails || (!brief && !oomOnly)) {
12484                    Debug.getMemoryInfo(pid, mi);
12485                } else {
12486                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12487                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12488                }
12489                if (dumpDetails) {
12490                    if (localOnly) {
12491                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12492                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12493                        if (isCheckinRequest) {
12494                            pw.println();
12495                        }
12496                    } else {
12497                        try {
12498                            pw.flush();
12499                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12500                                    dumpDalvik, innerArgs);
12501                        } catch (RemoteException e) {
12502                            if (!isCheckinRequest) {
12503                                pw.println("Got RemoteException!");
12504                                pw.flush();
12505                            }
12506                        }
12507                    }
12508                }
12509
12510                final long myTotalPss = mi.getTotalPss();
12511                final long myTotalUss = mi.getTotalUss();
12512
12513                synchronized (this) {
12514                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12515                        // Record this for posterity if the process has been stable.
12516                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12517                    }
12518                }
12519
12520                if (!isCheckinRequest && mi != null) {
12521                    totalPss += myTotalPss;
12522                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12523                            (hasActivities ? " / activities)" : ")"),
12524                            r.processName, myTotalPss, pid, hasActivities);
12525                    procMems.add(pssItem);
12526                    procMemsMap.put(pid, pssItem);
12527
12528                    nativePss += mi.nativePss;
12529                    dalvikPss += mi.dalvikPss;
12530                    otherPss += mi.otherPss;
12531                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12532                        long mem = mi.getOtherPss(j);
12533                        miscPss[j] += mem;
12534                        otherPss -= mem;
12535                    }
12536
12537                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12538                        cachedPss += myTotalPss;
12539                    }
12540
12541                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12542                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12543                                || oomIndex == (oomPss.length-1)) {
12544                            oomPss[oomIndex] += myTotalPss;
12545                            if (oomProcs[oomIndex] == null) {
12546                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12547                            }
12548                            oomProcs[oomIndex].add(pssItem);
12549                            break;
12550                        }
12551                    }
12552                }
12553            }
12554        }
12555
12556        if (!isCheckinRequest && procs.size() > 1) {
12557            // If we are showing aggregations, also look for native processes to
12558            // include so that our aggregations are more accurate.
12559            updateCpuStatsNow();
12560            synchronized (mProcessCpuThread) {
12561                final int N = mProcessCpuTracker.countStats();
12562                for (int i=0; i<N; i++) {
12563                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12564                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12565                        if (mi == null) {
12566                            mi = new Debug.MemoryInfo();
12567                        }
12568                        if (!brief && !oomOnly) {
12569                            Debug.getMemoryInfo(st.pid, mi);
12570                        } else {
12571                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12572                            mi.nativePrivateDirty = (int)tmpLong[0];
12573                        }
12574
12575                        final long myTotalPss = mi.getTotalPss();
12576                        totalPss += myTotalPss;
12577
12578                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12579                                st.name, myTotalPss, st.pid, false);
12580                        procMems.add(pssItem);
12581
12582                        nativePss += mi.nativePss;
12583                        dalvikPss += mi.dalvikPss;
12584                        otherPss += mi.otherPss;
12585                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12586                            long mem = mi.getOtherPss(j);
12587                            miscPss[j] += mem;
12588                            otherPss -= mem;
12589                        }
12590                        oomPss[0] += myTotalPss;
12591                        if (oomProcs[0] == null) {
12592                            oomProcs[0] = new ArrayList<MemItem>();
12593                        }
12594                        oomProcs[0].add(pssItem);
12595                    }
12596                }
12597            }
12598
12599            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12600
12601            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12602            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12603            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12604            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12605                String label = Debug.MemoryInfo.getOtherLabel(j);
12606                catMems.add(new MemItem(label, label, miscPss[j], j));
12607            }
12608
12609            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12610            for (int j=0; j<oomPss.length; j++) {
12611                if (oomPss[j] != 0) {
12612                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12613                            : DUMP_MEM_OOM_LABEL[j];
12614                    MemItem item = new MemItem(label, label, oomPss[j],
12615                            DUMP_MEM_OOM_ADJ[j]);
12616                    item.subitems = oomProcs[j];
12617                    oomMems.add(item);
12618                }
12619            }
12620
12621            if (!brief && !oomOnly && !isCompact) {
12622                pw.println();
12623                pw.println("Total PSS by process:");
12624                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12625                pw.println();
12626            }
12627            if (!isCompact) {
12628                pw.println("Total PSS by OOM adjustment:");
12629            }
12630            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12631            if (!brief && !oomOnly) {
12632                PrintWriter out = categoryPw != null ? categoryPw : pw;
12633                if (!isCompact) {
12634                    out.println();
12635                    out.println("Total PSS by category:");
12636                }
12637                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12638            }
12639            if (!isCompact) {
12640                pw.println();
12641            }
12642            MemInfoReader memInfo = new MemInfoReader();
12643            memInfo.readMemInfo();
12644            if (!brief) {
12645                if (!isCompact) {
12646                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12647                    pw.print(" kB (status ");
12648                    switch (mLastMemoryLevel) {
12649                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12650                            pw.println("normal)");
12651                            break;
12652                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12653                            pw.println("moderate)");
12654                            break;
12655                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12656                            pw.println("low)");
12657                            break;
12658                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12659                            pw.println("critical)");
12660                            break;
12661                        default:
12662                            pw.print(mLastMemoryLevel);
12663                            pw.println(")");
12664                            break;
12665                    }
12666                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12667                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12668                            pw.print(cachedPss); pw.print(" cached pss + ");
12669                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12670                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12671                } else {
12672                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12673                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12674                            + memInfo.getFreeSizeKb()); pw.print(",");
12675                    pw.println(totalPss - cachedPss);
12676                }
12677            }
12678            if (!isCompact) {
12679                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12680                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12681                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12682                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12683                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12684                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12685                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12686                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12687                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12688                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12689                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12690            }
12691            if (!brief) {
12692                if (memInfo.getZramTotalSizeKb() != 0) {
12693                    if (!isCompact) {
12694                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12695                                pw.print(" kB physical used for ");
12696                                pw.print(memInfo.getSwapTotalSizeKb()
12697                                        - memInfo.getSwapFreeSizeKb());
12698                                pw.print(" kB in swap (");
12699                                pw.print(memInfo.getSwapTotalSizeKb());
12700                                pw.println(" kB total swap)");
12701                    } else {
12702                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12703                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12704                                pw.println(memInfo.getSwapFreeSizeKb());
12705                    }
12706                }
12707                final int[] SINGLE_LONG_FORMAT = new int[] {
12708                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12709                };
12710                long[] longOut = new long[1];
12711                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12712                        SINGLE_LONG_FORMAT, null, longOut, null);
12713                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12714                longOut[0] = 0;
12715                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12716                        SINGLE_LONG_FORMAT, null, longOut, null);
12717                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12718                longOut[0] = 0;
12719                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12720                        SINGLE_LONG_FORMAT, null, longOut, null);
12721                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12722                longOut[0] = 0;
12723                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12724                        SINGLE_LONG_FORMAT, null, longOut, null);
12725                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12726                if (!isCompact) {
12727                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12728                        pw.print("      KSM: "); pw.print(sharing);
12729                                pw.print(" kB saved from shared ");
12730                                pw.print(shared); pw.println(" kB");
12731                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12732                                pw.print(voltile); pw.println(" kB volatile");
12733                    }
12734                    pw.print("   Tuning: ");
12735                    pw.print(ActivityManager.staticGetMemoryClass());
12736                    pw.print(" (large ");
12737                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12738                    pw.print("), oom ");
12739                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12740                    pw.print(" kB");
12741                    pw.print(", restore limit ");
12742                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12743                    pw.print(" kB");
12744                    if (ActivityManager.isLowRamDeviceStatic()) {
12745                        pw.print(" (low-ram)");
12746                    }
12747                    if (ActivityManager.isHighEndGfx()) {
12748                        pw.print(" (high-end-gfx)");
12749                    }
12750                    pw.println();
12751                } else {
12752                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12753                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12754                    pw.println(voltile);
12755                    pw.print("tuning,");
12756                    pw.print(ActivityManager.staticGetMemoryClass());
12757                    pw.print(',');
12758                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12759                    pw.print(',');
12760                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12761                    if (ActivityManager.isLowRamDeviceStatic()) {
12762                        pw.print(",low-ram");
12763                    }
12764                    if (ActivityManager.isHighEndGfx()) {
12765                        pw.print(",high-end-gfx");
12766                    }
12767                    pw.println();
12768                }
12769            }
12770        }
12771    }
12772
12773    /**
12774     * Searches array of arguments for the specified string
12775     * @param args array of argument strings
12776     * @param value value to search for
12777     * @return true if the value is contained in the array
12778     */
12779    private static boolean scanArgs(String[] args, String value) {
12780        if (args != null) {
12781            for (String arg : args) {
12782                if (value.equals(arg)) {
12783                    return true;
12784                }
12785            }
12786        }
12787        return false;
12788    }
12789
12790    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12791            ContentProviderRecord cpr, boolean always) {
12792        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12793
12794        if (!inLaunching || always) {
12795            synchronized (cpr) {
12796                cpr.launchingApp = null;
12797                cpr.notifyAll();
12798            }
12799            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12800            String names[] = cpr.info.authority.split(";");
12801            for (int j = 0; j < names.length; j++) {
12802                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12803            }
12804        }
12805
12806        for (int i=0; i<cpr.connections.size(); i++) {
12807            ContentProviderConnection conn = cpr.connections.get(i);
12808            if (conn.waiting) {
12809                // If this connection is waiting for the provider, then we don't
12810                // need to mess with its process unless we are always removing
12811                // or for some reason the provider is not currently launching.
12812                if (inLaunching && !always) {
12813                    continue;
12814                }
12815            }
12816            ProcessRecord capp = conn.client;
12817            conn.dead = true;
12818            if (conn.stableCount > 0) {
12819                if (!capp.persistent && capp.thread != null
12820                        && capp.pid != 0
12821                        && capp.pid != MY_PID) {
12822                    killUnneededProcessLocked(capp, "depends on provider "
12823                            + cpr.name.flattenToShortString()
12824                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12825                }
12826            } else if (capp.thread != null && conn.provider.provider != null) {
12827                try {
12828                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12829                } catch (RemoteException e) {
12830                }
12831                // In the protocol here, we don't expect the client to correctly
12832                // clean up this connection, we'll just remove it.
12833                cpr.connections.remove(i);
12834                conn.client.conProviders.remove(conn);
12835            }
12836        }
12837
12838        if (inLaunching && always) {
12839            mLaunchingProviders.remove(cpr);
12840        }
12841        return inLaunching;
12842    }
12843
12844    /**
12845     * Main code for cleaning up a process when it has gone away.  This is
12846     * called both as a result of the process dying, or directly when stopping
12847     * a process when running in single process mode.
12848     */
12849    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12850            boolean restarting, boolean allowRestart, int index) {
12851        if (index >= 0) {
12852            removeLruProcessLocked(app);
12853            ProcessList.remove(app.pid);
12854        }
12855
12856        mProcessesToGc.remove(app);
12857        mPendingPssProcesses.remove(app);
12858
12859        // Dismiss any open dialogs.
12860        if (app.crashDialog != null && !app.forceCrashReport) {
12861            app.crashDialog.dismiss();
12862            app.crashDialog = null;
12863        }
12864        if (app.anrDialog != null) {
12865            app.anrDialog.dismiss();
12866            app.anrDialog = null;
12867        }
12868        if (app.waitDialog != null) {
12869            app.waitDialog.dismiss();
12870            app.waitDialog = null;
12871        }
12872
12873        app.crashing = false;
12874        app.notResponding = false;
12875
12876        app.resetPackageList(mProcessStats);
12877        app.unlinkDeathRecipient();
12878        app.makeInactive(mProcessStats);
12879        app.forcingToForeground = null;
12880        updateProcessForegroundLocked(app, false, false);
12881        app.foregroundActivities = false;
12882        app.hasShownUi = false;
12883        app.treatLikeActivity = false;
12884        app.hasAboveClient = false;
12885        app.hasClientActivities = false;
12886
12887        mServices.killServicesLocked(app, allowRestart);
12888
12889        boolean restart = false;
12890
12891        // Remove published content providers.
12892        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12893            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12894            final boolean always = app.bad || !allowRestart;
12895            if (removeDyingProviderLocked(app, cpr, always) || always) {
12896                // We left the provider in the launching list, need to
12897                // restart it.
12898                restart = true;
12899            }
12900
12901            cpr.provider = null;
12902            cpr.proc = null;
12903        }
12904        app.pubProviders.clear();
12905
12906        // Take care of any launching providers waiting for this process.
12907        if (checkAppInLaunchingProvidersLocked(app, false)) {
12908            restart = true;
12909        }
12910
12911        // Unregister from connected content providers.
12912        if (!app.conProviders.isEmpty()) {
12913            for (int i=0; i<app.conProviders.size(); i++) {
12914                ContentProviderConnection conn = app.conProviders.get(i);
12915                conn.provider.connections.remove(conn);
12916            }
12917            app.conProviders.clear();
12918        }
12919
12920        // At this point there may be remaining entries in mLaunchingProviders
12921        // where we were the only one waiting, so they are no longer of use.
12922        // Look for these and clean up if found.
12923        // XXX Commented out for now.  Trying to figure out a way to reproduce
12924        // the actual situation to identify what is actually going on.
12925        if (false) {
12926            for (int i=0; i<mLaunchingProviders.size(); i++) {
12927                ContentProviderRecord cpr = (ContentProviderRecord)
12928                        mLaunchingProviders.get(i);
12929                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12930                    synchronized (cpr) {
12931                        cpr.launchingApp = null;
12932                        cpr.notifyAll();
12933                    }
12934                }
12935            }
12936        }
12937
12938        skipCurrentReceiverLocked(app);
12939
12940        // Unregister any receivers.
12941        for (int i=app.receivers.size()-1; i>=0; i--) {
12942            removeReceiverLocked(app.receivers.valueAt(i));
12943        }
12944        app.receivers.clear();
12945
12946        // If the app is undergoing backup, tell the backup manager about it
12947        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12948            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12949                    + mBackupTarget.appInfo + " died during backup");
12950            try {
12951                IBackupManager bm = IBackupManager.Stub.asInterface(
12952                        ServiceManager.getService(Context.BACKUP_SERVICE));
12953                bm.agentDisconnected(app.info.packageName);
12954            } catch (RemoteException e) {
12955                // can't happen; backup manager is local
12956            }
12957        }
12958
12959        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12960            ProcessChangeItem item = mPendingProcessChanges.get(i);
12961            if (item.pid == app.pid) {
12962                mPendingProcessChanges.remove(i);
12963                mAvailProcessChanges.add(item);
12964            }
12965        }
12966        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12967
12968        // If the caller is restarting this app, then leave it in its
12969        // current lists and let the caller take care of it.
12970        if (restarting) {
12971            return;
12972        }
12973
12974        if (!app.persistent || app.isolated) {
12975            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12976                    "Removing non-persistent process during cleanup: " + app);
12977            mProcessNames.remove(app.processName, app.uid);
12978            mIsolatedProcesses.remove(app.uid);
12979            if (mHeavyWeightProcess == app) {
12980                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12981                        mHeavyWeightProcess.userId, 0));
12982                mHeavyWeightProcess = null;
12983            }
12984        } else if (!app.removed) {
12985            // This app is persistent, so we need to keep its record around.
12986            // If it is not already on the pending app list, add it there
12987            // and start a new process for it.
12988            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12989                mPersistentStartingProcesses.add(app);
12990                restart = true;
12991            }
12992        }
12993        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12994                "Clean-up removing on hold: " + app);
12995        mProcessesOnHold.remove(app);
12996
12997        if (app == mHomeProcess) {
12998            mHomeProcess = null;
12999        }
13000        if (app == mPreviousProcess) {
13001            mPreviousProcess = null;
13002        }
13003
13004        if (restart && !app.isolated) {
13005            // We have components that still need to be running in the
13006            // process, so re-launch it.
13007            mProcessNames.put(app.processName, app.uid, app);
13008            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13009        } else if (app.pid > 0 && app.pid != MY_PID) {
13010            // Goodbye!
13011            boolean removed;
13012            synchronized (mPidsSelfLocked) {
13013                mPidsSelfLocked.remove(app.pid);
13014                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13015            }
13016            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13017                    app.processName, app.info.uid);
13018            if (app.isolated) {
13019                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13020            }
13021            app.setPid(0);
13022        }
13023    }
13024
13025    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13026        // Look through the content providers we are waiting to have launched,
13027        // and if any run in this process then either schedule a restart of
13028        // the process or kill the client waiting for it if this process has
13029        // gone bad.
13030        int NL = mLaunchingProviders.size();
13031        boolean restart = false;
13032        for (int i=0; i<NL; i++) {
13033            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13034            if (cpr.launchingApp == app) {
13035                if (!alwaysBad && !app.bad) {
13036                    restart = true;
13037                } else {
13038                    removeDyingProviderLocked(app, cpr, true);
13039                    // cpr should have been removed from mLaunchingProviders
13040                    NL = mLaunchingProviders.size();
13041                    i--;
13042                }
13043            }
13044        }
13045        return restart;
13046    }
13047
13048    // =========================================================
13049    // SERVICES
13050    // =========================================================
13051
13052    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13053            int flags) {
13054        enforceNotIsolatedCaller("getServices");
13055        synchronized (this) {
13056            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13057        }
13058    }
13059
13060    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13061        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13062        synchronized (this) {
13063            return mServices.getRunningServiceControlPanelLocked(name);
13064        }
13065    }
13066
13067    public ComponentName startService(IApplicationThread caller, Intent service,
13068            String resolvedType, int userId) {
13069        enforceNotIsolatedCaller("startService");
13070        // Refuse possible leaked file descriptors
13071        if (service != null && service.hasFileDescriptors() == true) {
13072            throw new IllegalArgumentException("File descriptors passed in Intent");
13073        }
13074
13075        if (DEBUG_SERVICE)
13076            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13077        synchronized(this) {
13078            final int callingPid = Binder.getCallingPid();
13079            final int callingUid = Binder.getCallingUid();
13080            final long origId = Binder.clearCallingIdentity();
13081            ComponentName res = mServices.startServiceLocked(caller, service,
13082                    resolvedType, callingPid, callingUid, userId);
13083            Binder.restoreCallingIdentity(origId);
13084            return res;
13085        }
13086    }
13087
13088    ComponentName startServiceInPackage(int uid,
13089            Intent service, String resolvedType, int userId) {
13090        synchronized(this) {
13091            if (DEBUG_SERVICE)
13092                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13093            final long origId = Binder.clearCallingIdentity();
13094            ComponentName res = mServices.startServiceLocked(null, service,
13095                    resolvedType, -1, uid, userId);
13096            Binder.restoreCallingIdentity(origId);
13097            return res;
13098        }
13099    }
13100
13101    public int stopService(IApplicationThread caller, Intent service,
13102            String resolvedType, int userId) {
13103        enforceNotIsolatedCaller("stopService");
13104        // Refuse possible leaked file descriptors
13105        if (service != null && service.hasFileDescriptors() == true) {
13106            throw new IllegalArgumentException("File descriptors passed in Intent");
13107        }
13108
13109        synchronized(this) {
13110            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13111        }
13112    }
13113
13114    public IBinder peekService(Intent service, String resolvedType) {
13115        enforceNotIsolatedCaller("peekService");
13116        // Refuse possible leaked file descriptors
13117        if (service != null && service.hasFileDescriptors() == true) {
13118            throw new IllegalArgumentException("File descriptors passed in Intent");
13119        }
13120        synchronized(this) {
13121            return mServices.peekServiceLocked(service, resolvedType);
13122        }
13123    }
13124
13125    public boolean stopServiceToken(ComponentName className, IBinder token,
13126            int startId) {
13127        synchronized(this) {
13128            return mServices.stopServiceTokenLocked(className, token, startId);
13129        }
13130    }
13131
13132    public void setServiceForeground(ComponentName className, IBinder token,
13133            int id, Notification notification, boolean removeNotification) {
13134        synchronized(this) {
13135            mServices.setServiceForegroundLocked(className, token, id, notification,
13136                    removeNotification);
13137        }
13138    }
13139
13140    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13141            boolean requireFull, String name, String callerPackage) {
13142        final int callingUserId = UserHandle.getUserId(callingUid);
13143        if (callingUserId != userId) {
13144            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13145                if ((requireFull || checkComponentPermission(
13146                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13147                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13148                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13149                                callingPid, callingUid, -1, true)
13150                                != PackageManager.PERMISSION_GRANTED) {
13151                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13152                        // In this case, they would like to just execute as their
13153                        // owner user instead of failing.
13154                        userId = callingUserId;
13155                    } else {
13156                        StringBuilder builder = new StringBuilder(128);
13157                        builder.append("Permission Denial: ");
13158                        builder.append(name);
13159                        if (callerPackage != null) {
13160                            builder.append(" from ");
13161                            builder.append(callerPackage);
13162                        }
13163                        builder.append(" asks to run as user ");
13164                        builder.append(userId);
13165                        builder.append(" but is calling from user ");
13166                        builder.append(UserHandle.getUserId(callingUid));
13167                        builder.append("; this requires ");
13168                        builder.append(INTERACT_ACROSS_USERS_FULL);
13169                        if (!requireFull) {
13170                            builder.append(" or ");
13171                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13172                        }
13173                        String msg = builder.toString();
13174                        Slog.w(TAG, msg);
13175                        throw new SecurityException(msg);
13176                    }
13177                }
13178            }
13179            if (userId == UserHandle.USER_CURRENT
13180                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13181                // Note that we may be accessing this outside of a lock...
13182                // shouldn't be a big deal, if this is being called outside
13183                // of a locked context there is intrinsically a race with
13184                // the value the caller will receive and someone else changing it.
13185                userId = mCurrentUserId;
13186            }
13187            if (!allowAll && userId < 0) {
13188                throw new IllegalArgumentException(
13189                        "Call does not support special user #" + userId);
13190            }
13191        }
13192        return userId;
13193    }
13194
13195    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13196            String className, int flags) {
13197        boolean result = false;
13198        // For apps that don't have pre-defined UIDs, check for permission
13199        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13200            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13201                if (ActivityManager.checkUidPermission(
13202                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13203                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13204                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13205                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13206                            + " requests FLAG_SINGLE_USER, but app does not hold "
13207                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13208                    Slog.w(TAG, msg);
13209                    throw new SecurityException(msg);
13210                }
13211                // Permission passed
13212                result = true;
13213            }
13214        } else if ("system".equals(componentProcessName)) {
13215            result = true;
13216        } else {
13217            // App with pre-defined UID, check if it's a persistent app
13218            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13219        }
13220        if (DEBUG_MU) {
13221            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13222                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13223        }
13224        return result;
13225    }
13226
13227    /**
13228     * Checks to see if the caller is in the same app as the singleton
13229     * component, or the component is in a special app. It allows special apps
13230     * to export singleton components but prevents exporting singleton
13231     * components for regular apps.
13232     */
13233    boolean isValidSingletonCall(int callingUid, int componentUid) {
13234        int componentAppId = UserHandle.getAppId(componentUid);
13235        return UserHandle.isSameApp(callingUid, componentUid)
13236                || componentAppId == Process.SYSTEM_UID
13237                || componentAppId == Process.PHONE_UID
13238                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13239                        == PackageManager.PERMISSION_GRANTED;
13240    }
13241
13242    public int bindService(IApplicationThread caller, IBinder token,
13243            Intent service, String resolvedType,
13244            IServiceConnection connection, int flags, int userId) {
13245        enforceNotIsolatedCaller("bindService");
13246        // Refuse possible leaked file descriptors
13247        if (service != null && service.hasFileDescriptors() == true) {
13248            throw new IllegalArgumentException("File descriptors passed in Intent");
13249        }
13250
13251        synchronized(this) {
13252            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13253                    connection, flags, userId);
13254        }
13255    }
13256
13257    public boolean unbindService(IServiceConnection connection) {
13258        synchronized (this) {
13259            return mServices.unbindServiceLocked(connection);
13260        }
13261    }
13262
13263    public void publishService(IBinder token, Intent intent, IBinder service) {
13264        // Refuse possible leaked file descriptors
13265        if (intent != null && intent.hasFileDescriptors() == true) {
13266            throw new IllegalArgumentException("File descriptors passed in Intent");
13267        }
13268
13269        synchronized(this) {
13270            if (!(token instanceof ServiceRecord)) {
13271                throw new IllegalArgumentException("Invalid service token");
13272            }
13273            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13274        }
13275    }
13276
13277    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13278        // Refuse possible leaked file descriptors
13279        if (intent != null && intent.hasFileDescriptors() == true) {
13280            throw new IllegalArgumentException("File descriptors passed in Intent");
13281        }
13282
13283        synchronized(this) {
13284            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13285        }
13286    }
13287
13288    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13289        synchronized(this) {
13290            if (!(token instanceof ServiceRecord)) {
13291                throw new IllegalArgumentException("Invalid service token");
13292            }
13293            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13294        }
13295    }
13296
13297    // =========================================================
13298    // BACKUP AND RESTORE
13299    // =========================================================
13300
13301    // Cause the target app to be launched if necessary and its backup agent
13302    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13303    // activity manager to announce its creation.
13304    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13305        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13306        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13307
13308        synchronized(this) {
13309            // !!! TODO: currently no check here that we're already bound
13310            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13311            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13312            synchronized (stats) {
13313                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13314            }
13315
13316            // Backup agent is now in use, its package can't be stopped.
13317            try {
13318                AppGlobals.getPackageManager().setPackageStoppedState(
13319                        app.packageName, false, UserHandle.getUserId(app.uid));
13320            } catch (RemoteException e) {
13321            } catch (IllegalArgumentException e) {
13322                Slog.w(TAG, "Failed trying to unstop package "
13323                        + app.packageName + ": " + e);
13324            }
13325
13326            BackupRecord r = new BackupRecord(ss, app, backupMode);
13327            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13328                    ? new ComponentName(app.packageName, app.backupAgentName)
13329                    : new ComponentName("android", "FullBackupAgent");
13330            // startProcessLocked() returns existing proc's record if it's already running
13331            ProcessRecord proc = startProcessLocked(app.processName, app,
13332                    false, 0, "backup", hostingName, false, false, false);
13333            if (proc == null) {
13334                Slog.e(TAG, "Unable to start backup agent process " + r);
13335                return false;
13336            }
13337
13338            r.app = proc;
13339            mBackupTarget = r;
13340            mBackupAppName = app.packageName;
13341
13342            // Try not to kill the process during backup
13343            updateOomAdjLocked(proc);
13344
13345            // If the process is already attached, schedule the creation of the backup agent now.
13346            // If it is not yet live, this will be done when it attaches to the framework.
13347            if (proc.thread != null) {
13348                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13349                try {
13350                    proc.thread.scheduleCreateBackupAgent(app,
13351                            compatibilityInfoForPackageLocked(app), backupMode);
13352                } catch (RemoteException e) {
13353                    // Will time out on the backup manager side
13354                }
13355            } else {
13356                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13357            }
13358            // Invariants: at this point, the target app process exists and the application
13359            // is either already running or in the process of coming up.  mBackupTarget and
13360            // mBackupAppName describe the app, so that when it binds back to the AM we
13361            // know that it's scheduled for a backup-agent operation.
13362        }
13363
13364        return true;
13365    }
13366
13367    @Override
13368    public void clearPendingBackup() {
13369        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13370        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13371
13372        synchronized (this) {
13373            mBackupTarget = null;
13374            mBackupAppName = null;
13375        }
13376    }
13377
13378    // A backup agent has just come up
13379    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13380        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13381                + " = " + agent);
13382
13383        synchronized(this) {
13384            if (!agentPackageName.equals(mBackupAppName)) {
13385                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13386                return;
13387            }
13388        }
13389
13390        long oldIdent = Binder.clearCallingIdentity();
13391        try {
13392            IBackupManager bm = IBackupManager.Stub.asInterface(
13393                    ServiceManager.getService(Context.BACKUP_SERVICE));
13394            bm.agentConnected(agentPackageName, agent);
13395        } catch (RemoteException e) {
13396            // can't happen; the backup manager service is local
13397        } catch (Exception e) {
13398            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13399            e.printStackTrace();
13400        } finally {
13401            Binder.restoreCallingIdentity(oldIdent);
13402        }
13403    }
13404
13405    // done with this agent
13406    public void unbindBackupAgent(ApplicationInfo appInfo) {
13407        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13408        if (appInfo == null) {
13409            Slog.w(TAG, "unbind backup agent for null app");
13410            return;
13411        }
13412
13413        synchronized(this) {
13414            try {
13415                if (mBackupAppName == null) {
13416                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13417                    return;
13418                }
13419
13420                if (!mBackupAppName.equals(appInfo.packageName)) {
13421                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13422                    return;
13423                }
13424
13425                // Not backing this app up any more; reset its OOM adjustment
13426                final ProcessRecord proc = mBackupTarget.app;
13427                updateOomAdjLocked(proc);
13428
13429                // If the app crashed during backup, 'thread' will be null here
13430                if (proc.thread != null) {
13431                    try {
13432                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13433                                compatibilityInfoForPackageLocked(appInfo));
13434                    } catch (Exception e) {
13435                        Slog.e(TAG, "Exception when unbinding backup agent:");
13436                        e.printStackTrace();
13437                    }
13438                }
13439            } finally {
13440                mBackupTarget = null;
13441                mBackupAppName = null;
13442            }
13443        }
13444    }
13445    // =========================================================
13446    // BROADCASTS
13447    // =========================================================
13448
13449    private final List getStickiesLocked(String action, IntentFilter filter,
13450            List cur, int userId) {
13451        final ContentResolver resolver = mContext.getContentResolver();
13452        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13453        if (stickies == null) {
13454            return cur;
13455        }
13456        final ArrayList<Intent> list = stickies.get(action);
13457        if (list == null) {
13458            return cur;
13459        }
13460        int N = list.size();
13461        for (int i=0; i<N; i++) {
13462            Intent intent = list.get(i);
13463            if (filter.match(resolver, intent, true, TAG) >= 0) {
13464                if (cur == null) {
13465                    cur = new ArrayList<Intent>();
13466                }
13467                cur.add(intent);
13468            }
13469        }
13470        return cur;
13471    }
13472
13473    boolean isPendingBroadcastProcessLocked(int pid) {
13474        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13475                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13476    }
13477
13478    void skipPendingBroadcastLocked(int pid) {
13479            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13480            for (BroadcastQueue queue : mBroadcastQueues) {
13481                queue.skipPendingBroadcastLocked(pid);
13482            }
13483    }
13484
13485    // The app just attached; send any pending broadcasts that it should receive
13486    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13487        boolean didSomething = false;
13488        for (BroadcastQueue queue : mBroadcastQueues) {
13489            didSomething |= queue.sendPendingBroadcastsLocked(app);
13490        }
13491        return didSomething;
13492    }
13493
13494    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13495            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13496        enforceNotIsolatedCaller("registerReceiver");
13497        int callingUid;
13498        int callingPid;
13499        synchronized(this) {
13500            ProcessRecord callerApp = null;
13501            if (caller != null) {
13502                callerApp = getRecordForAppLocked(caller);
13503                if (callerApp == null) {
13504                    throw new SecurityException(
13505                            "Unable to find app for caller " + caller
13506                            + " (pid=" + Binder.getCallingPid()
13507                            + ") when registering receiver " + receiver);
13508                }
13509                if (callerApp.info.uid != Process.SYSTEM_UID &&
13510                        !callerApp.pkgList.containsKey(callerPackage) &&
13511                        !"android".equals(callerPackage)) {
13512                    throw new SecurityException("Given caller package " + callerPackage
13513                            + " is not running in process " + callerApp);
13514                }
13515                callingUid = callerApp.info.uid;
13516                callingPid = callerApp.pid;
13517            } else {
13518                callerPackage = null;
13519                callingUid = Binder.getCallingUid();
13520                callingPid = Binder.getCallingPid();
13521            }
13522
13523            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13524                    true, true, "registerReceiver", callerPackage);
13525
13526            List allSticky = null;
13527
13528            // Look for any matching sticky broadcasts...
13529            Iterator actions = filter.actionsIterator();
13530            if (actions != null) {
13531                while (actions.hasNext()) {
13532                    String action = (String)actions.next();
13533                    allSticky = getStickiesLocked(action, filter, allSticky,
13534                            UserHandle.USER_ALL);
13535                    allSticky = getStickiesLocked(action, filter, allSticky,
13536                            UserHandle.getUserId(callingUid));
13537                }
13538            } else {
13539                allSticky = getStickiesLocked(null, filter, allSticky,
13540                        UserHandle.USER_ALL);
13541                allSticky = getStickiesLocked(null, filter, allSticky,
13542                        UserHandle.getUserId(callingUid));
13543            }
13544
13545            // The first sticky in the list is returned directly back to
13546            // the client.
13547            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13548
13549            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13550                    + ": " + sticky);
13551
13552            if (receiver == null) {
13553                return sticky;
13554            }
13555
13556            ReceiverList rl
13557                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13558            if (rl == null) {
13559                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13560                        userId, receiver);
13561                if (rl.app != null) {
13562                    rl.app.receivers.add(rl);
13563                } else {
13564                    try {
13565                        receiver.asBinder().linkToDeath(rl, 0);
13566                    } catch (RemoteException e) {
13567                        return sticky;
13568                    }
13569                    rl.linkedToDeath = true;
13570                }
13571                mRegisteredReceivers.put(receiver.asBinder(), rl);
13572            } else if (rl.uid != callingUid) {
13573                throw new IllegalArgumentException(
13574                        "Receiver requested to register for uid " + callingUid
13575                        + " was previously registered for uid " + rl.uid);
13576            } else if (rl.pid != callingPid) {
13577                throw new IllegalArgumentException(
13578                        "Receiver requested to register for pid " + callingPid
13579                        + " was previously registered for pid " + rl.pid);
13580            } else if (rl.userId != userId) {
13581                throw new IllegalArgumentException(
13582                        "Receiver requested to register for user " + userId
13583                        + " was previously registered for user " + rl.userId);
13584            }
13585            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13586                    permission, callingUid, userId);
13587            rl.add(bf);
13588            if (!bf.debugCheck()) {
13589                Slog.w(TAG, "==> For Dynamic broadast");
13590            }
13591            mReceiverResolver.addFilter(bf);
13592
13593            // Enqueue broadcasts for all existing stickies that match
13594            // this filter.
13595            if (allSticky != null) {
13596                ArrayList receivers = new ArrayList();
13597                receivers.add(bf);
13598
13599                int N = allSticky.size();
13600                for (int i=0; i<N; i++) {
13601                    Intent intent = (Intent)allSticky.get(i);
13602                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13603                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13604                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13605                            null, null, false, true, true, -1);
13606                    queue.enqueueParallelBroadcastLocked(r);
13607                    queue.scheduleBroadcastsLocked();
13608                }
13609            }
13610
13611            return sticky;
13612        }
13613    }
13614
13615    public void unregisterReceiver(IIntentReceiver receiver) {
13616        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13617
13618        final long origId = Binder.clearCallingIdentity();
13619        try {
13620            boolean doTrim = false;
13621
13622            synchronized(this) {
13623                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13624                if (rl != null) {
13625                    if (rl.curBroadcast != null) {
13626                        BroadcastRecord r = rl.curBroadcast;
13627                        final boolean doNext = finishReceiverLocked(
13628                                receiver.asBinder(), r.resultCode, r.resultData,
13629                                r.resultExtras, r.resultAbort);
13630                        if (doNext) {
13631                            doTrim = true;
13632                            r.queue.processNextBroadcast(false);
13633                        }
13634                    }
13635
13636                    if (rl.app != null) {
13637                        rl.app.receivers.remove(rl);
13638                    }
13639                    removeReceiverLocked(rl);
13640                    if (rl.linkedToDeath) {
13641                        rl.linkedToDeath = false;
13642                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13643                    }
13644                }
13645            }
13646
13647            // If we actually concluded any broadcasts, we might now be able
13648            // to trim the recipients' apps from our working set
13649            if (doTrim) {
13650                trimApplications();
13651                return;
13652            }
13653
13654        } finally {
13655            Binder.restoreCallingIdentity(origId);
13656        }
13657    }
13658
13659    void removeReceiverLocked(ReceiverList rl) {
13660        mRegisteredReceivers.remove(rl.receiver.asBinder());
13661        int N = rl.size();
13662        for (int i=0; i<N; i++) {
13663            mReceiverResolver.removeFilter(rl.get(i));
13664        }
13665    }
13666
13667    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13668        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13669            ProcessRecord r = mLruProcesses.get(i);
13670            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13671                try {
13672                    r.thread.dispatchPackageBroadcast(cmd, packages);
13673                } catch (RemoteException ex) {
13674                }
13675            }
13676        }
13677    }
13678
13679    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13680            int[] users) {
13681        List<ResolveInfo> receivers = null;
13682        try {
13683            HashSet<ComponentName> singleUserReceivers = null;
13684            boolean scannedFirstReceivers = false;
13685            for (int user : users) {
13686                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13687                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13688                if (user != 0 && newReceivers != null) {
13689                    // If this is not the primary user, we need to check for
13690                    // any receivers that should be filtered out.
13691                    for (int i=0; i<newReceivers.size(); i++) {
13692                        ResolveInfo ri = newReceivers.get(i);
13693                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13694                            newReceivers.remove(i);
13695                            i--;
13696                        }
13697                    }
13698                }
13699                if (newReceivers != null && newReceivers.size() == 0) {
13700                    newReceivers = null;
13701                }
13702                if (receivers == null) {
13703                    receivers = newReceivers;
13704                } else if (newReceivers != null) {
13705                    // We need to concatenate the additional receivers
13706                    // found with what we have do far.  This would be easy,
13707                    // but we also need to de-dup any receivers that are
13708                    // singleUser.
13709                    if (!scannedFirstReceivers) {
13710                        // Collect any single user receivers we had already retrieved.
13711                        scannedFirstReceivers = true;
13712                        for (int i=0; i<receivers.size(); i++) {
13713                            ResolveInfo ri = receivers.get(i);
13714                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13715                                ComponentName cn = new ComponentName(
13716                                        ri.activityInfo.packageName, ri.activityInfo.name);
13717                                if (singleUserReceivers == null) {
13718                                    singleUserReceivers = new HashSet<ComponentName>();
13719                                }
13720                                singleUserReceivers.add(cn);
13721                            }
13722                        }
13723                    }
13724                    // Add the new results to the existing results, tracking
13725                    // and de-dupping single user receivers.
13726                    for (int i=0; i<newReceivers.size(); i++) {
13727                        ResolveInfo ri = newReceivers.get(i);
13728                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13729                            ComponentName cn = new ComponentName(
13730                                    ri.activityInfo.packageName, ri.activityInfo.name);
13731                            if (singleUserReceivers == null) {
13732                                singleUserReceivers = new HashSet<ComponentName>();
13733                            }
13734                            if (!singleUserReceivers.contains(cn)) {
13735                                singleUserReceivers.add(cn);
13736                                receivers.add(ri);
13737                            }
13738                        } else {
13739                            receivers.add(ri);
13740                        }
13741                    }
13742                }
13743            }
13744        } catch (RemoteException ex) {
13745            // pm is in same process, this will never happen.
13746        }
13747        return receivers;
13748    }
13749
13750    private final int broadcastIntentLocked(ProcessRecord callerApp,
13751            String callerPackage, Intent intent, String resolvedType,
13752            IIntentReceiver resultTo, int resultCode, String resultData,
13753            Bundle map, String requiredPermission, int appOp,
13754            boolean ordered, boolean sticky, int callingPid, int callingUid,
13755            int userId) {
13756        intent = new Intent(intent);
13757
13758        // By default broadcasts do not go to stopped apps.
13759        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13760
13761        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13762            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13763            + " ordered=" + ordered + " userid=" + userId);
13764        if ((resultTo != null) && !ordered) {
13765            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13766        }
13767
13768        userId = handleIncomingUser(callingPid, callingUid, userId,
13769                true, false, "broadcast", callerPackage);
13770
13771        // Make sure that the user who is receiving this broadcast is started.
13772        // If not, we will just skip it.
13773        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13774            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13775                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13776                Slog.w(TAG, "Skipping broadcast of " + intent
13777                        + ": user " + userId + " is stopped");
13778                return ActivityManager.BROADCAST_SUCCESS;
13779            }
13780        }
13781
13782        /*
13783         * Prevent non-system code (defined here to be non-persistent
13784         * processes) from sending protected broadcasts.
13785         */
13786        int callingAppId = UserHandle.getAppId(callingUid);
13787        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13788                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13789                || callingUid == 0) {
13790            // Always okay.
13791        } else if (callerApp == null || !callerApp.persistent) {
13792            try {
13793                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13794                        intent.getAction())) {
13795                    String msg = "Permission Denial: not allowed to send broadcast "
13796                            + intent.getAction() + " from pid="
13797                            + callingPid + ", uid=" + callingUid;
13798                    Slog.w(TAG, msg);
13799                    throw new SecurityException(msg);
13800                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13801                    // Special case for compatibility: we don't want apps to send this,
13802                    // but historically it has not been protected and apps may be using it
13803                    // to poke their own app widget.  So, instead of making it protected,
13804                    // just limit it to the caller.
13805                    if (callerApp == null) {
13806                        String msg = "Permission Denial: not allowed to send broadcast "
13807                                + intent.getAction() + " from unknown caller.";
13808                        Slog.w(TAG, msg);
13809                        throw new SecurityException(msg);
13810                    } else if (intent.getComponent() != null) {
13811                        // They are good enough to send to an explicit component...  verify
13812                        // it is being sent to the calling app.
13813                        if (!intent.getComponent().getPackageName().equals(
13814                                callerApp.info.packageName)) {
13815                            String msg = "Permission Denial: not allowed to send broadcast "
13816                                    + intent.getAction() + " to "
13817                                    + intent.getComponent().getPackageName() + " from "
13818                                    + callerApp.info.packageName;
13819                            Slog.w(TAG, msg);
13820                            throw new SecurityException(msg);
13821                        }
13822                    } else {
13823                        // Limit broadcast to their own package.
13824                        intent.setPackage(callerApp.info.packageName);
13825                    }
13826                }
13827            } catch (RemoteException e) {
13828                Slog.w(TAG, "Remote exception", e);
13829                return ActivityManager.BROADCAST_SUCCESS;
13830            }
13831        }
13832
13833        // Handle special intents: if this broadcast is from the package
13834        // manager about a package being removed, we need to remove all of
13835        // its activities from the history stack.
13836        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13837                intent.getAction());
13838        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13839                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13840                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13841                || uidRemoved) {
13842            if (checkComponentPermission(
13843                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13844                    callingPid, callingUid, -1, true)
13845                    == PackageManager.PERMISSION_GRANTED) {
13846                if (uidRemoved) {
13847                    final Bundle intentExtras = intent.getExtras();
13848                    final int uid = intentExtras != null
13849                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13850                    if (uid >= 0) {
13851                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13852                        synchronized (bs) {
13853                            bs.removeUidStatsLocked(uid);
13854                        }
13855                        mAppOpsService.uidRemoved(uid);
13856                    }
13857                } else {
13858                    // If resources are unavailable just force stop all
13859                    // those packages and flush the attribute cache as well.
13860                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13861                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13862                        if (list != null && (list.length > 0)) {
13863                            for (String pkg : list) {
13864                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13865                                        "storage unmount");
13866                            }
13867                            sendPackageBroadcastLocked(
13868                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13869                        }
13870                    } else {
13871                        Uri data = intent.getData();
13872                        String ssp;
13873                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13874                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13875                                    intent.getAction());
13876                            boolean fullUninstall = removed &&
13877                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13878                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13879                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13880                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13881                                        false, fullUninstall, userId,
13882                                        removed ? "pkg removed" : "pkg changed");
13883                            }
13884                            if (removed) {
13885                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13886                                        new String[] {ssp}, userId);
13887                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13888                                    mAppOpsService.packageRemoved(
13889                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13890
13891                                    // Remove all permissions granted from/to this package
13892                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13893                                }
13894                            }
13895                        }
13896                    }
13897                }
13898            } else {
13899                String msg = "Permission Denial: " + intent.getAction()
13900                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13901                        + ", uid=" + callingUid + ")"
13902                        + " requires "
13903                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13904                Slog.w(TAG, msg);
13905                throw new SecurityException(msg);
13906            }
13907
13908        // Special case for adding a package: by default turn on compatibility
13909        // mode.
13910        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13911            Uri data = intent.getData();
13912            String ssp;
13913            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13914                mCompatModePackages.handlePackageAddedLocked(ssp,
13915                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13916            }
13917        }
13918
13919        /*
13920         * If this is the time zone changed action, queue up a message that will reset the timezone
13921         * of all currently running processes. This message will get queued up before the broadcast
13922         * happens.
13923         */
13924        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13925            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13926        }
13927
13928        /*
13929         * If the user set the time, let all running processes know.
13930         */
13931        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13932            final int is24Hour = intent.getBooleanExtra(
13933                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13934            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13935        }
13936
13937        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13938            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13939        }
13940
13941        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13942            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13943            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13944        }
13945
13946        // Add to the sticky list if requested.
13947        if (sticky) {
13948            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13949                    callingPid, callingUid)
13950                    != PackageManager.PERMISSION_GRANTED) {
13951                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13952                        + callingPid + ", uid=" + callingUid
13953                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13954                Slog.w(TAG, msg);
13955                throw new SecurityException(msg);
13956            }
13957            if (requiredPermission != null) {
13958                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13959                        + " and enforce permission " + requiredPermission);
13960                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13961            }
13962            if (intent.getComponent() != null) {
13963                throw new SecurityException(
13964                        "Sticky broadcasts can't target a specific component");
13965            }
13966            // We use userId directly here, since the "all" target is maintained
13967            // as a separate set of sticky broadcasts.
13968            if (userId != UserHandle.USER_ALL) {
13969                // But first, if this is not a broadcast to all users, then
13970                // make sure it doesn't conflict with an existing broadcast to
13971                // all users.
13972                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13973                        UserHandle.USER_ALL);
13974                if (stickies != null) {
13975                    ArrayList<Intent> list = stickies.get(intent.getAction());
13976                    if (list != null) {
13977                        int N = list.size();
13978                        int i;
13979                        for (i=0; i<N; i++) {
13980                            if (intent.filterEquals(list.get(i))) {
13981                                throw new IllegalArgumentException(
13982                                        "Sticky broadcast " + intent + " for user "
13983                                        + userId + " conflicts with existing global broadcast");
13984                            }
13985                        }
13986                    }
13987                }
13988            }
13989            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13990            if (stickies == null) {
13991                stickies = new ArrayMap<String, ArrayList<Intent>>();
13992                mStickyBroadcasts.put(userId, stickies);
13993            }
13994            ArrayList<Intent> list = stickies.get(intent.getAction());
13995            if (list == null) {
13996                list = new ArrayList<Intent>();
13997                stickies.put(intent.getAction(), list);
13998            }
13999            int N = list.size();
14000            int i;
14001            for (i=0; i<N; i++) {
14002                if (intent.filterEquals(list.get(i))) {
14003                    // This sticky already exists, replace it.
14004                    list.set(i, new Intent(intent));
14005                    break;
14006                }
14007            }
14008            if (i >= N) {
14009                list.add(new Intent(intent));
14010            }
14011        }
14012
14013        int[] users;
14014        if (userId == UserHandle.USER_ALL) {
14015            // Caller wants broadcast to go to all started users.
14016            users = mStartedUserArray;
14017        } else {
14018            // Caller wants broadcast to go to one specific user.
14019            users = new int[] {userId};
14020        }
14021
14022        // Figure out who all will receive this broadcast.
14023        List receivers = null;
14024        List<BroadcastFilter> registeredReceivers = null;
14025        // Need to resolve the intent to interested receivers...
14026        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14027                 == 0) {
14028            receivers = collectReceiverComponents(intent, resolvedType, users);
14029        }
14030        if (intent.getComponent() == null) {
14031            registeredReceivers = mReceiverResolver.queryIntent(intent,
14032                    resolvedType, false, userId);
14033        }
14034
14035        final boolean replacePending =
14036                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14037
14038        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14039                + " replacePending=" + replacePending);
14040
14041        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14042        if (!ordered && NR > 0) {
14043            // If we are not serializing this broadcast, then send the
14044            // registered receivers separately so they don't wait for the
14045            // components to be launched.
14046            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14047            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14048                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14049                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14050                    ordered, sticky, false, userId);
14051            if (DEBUG_BROADCAST) Slog.v(
14052                    TAG, "Enqueueing parallel broadcast " + r);
14053            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14054            if (!replaced) {
14055                queue.enqueueParallelBroadcastLocked(r);
14056                queue.scheduleBroadcastsLocked();
14057            }
14058            registeredReceivers = null;
14059            NR = 0;
14060        }
14061
14062        // Merge into one list.
14063        int ir = 0;
14064        if (receivers != null) {
14065            // A special case for PACKAGE_ADDED: do not allow the package
14066            // being added to see this broadcast.  This prevents them from
14067            // using this as a back door to get run as soon as they are
14068            // installed.  Maybe in the future we want to have a special install
14069            // broadcast or such for apps, but we'd like to deliberately make
14070            // this decision.
14071            String skipPackages[] = null;
14072            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14073                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14074                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14075                Uri data = intent.getData();
14076                if (data != null) {
14077                    String pkgName = data.getSchemeSpecificPart();
14078                    if (pkgName != null) {
14079                        skipPackages = new String[] { pkgName };
14080                    }
14081                }
14082            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14083                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14084            }
14085            if (skipPackages != null && (skipPackages.length > 0)) {
14086                for (String skipPackage : skipPackages) {
14087                    if (skipPackage != null) {
14088                        int NT = receivers.size();
14089                        for (int it=0; it<NT; it++) {
14090                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14091                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14092                                receivers.remove(it);
14093                                it--;
14094                                NT--;
14095                            }
14096                        }
14097                    }
14098                }
14099            }
14100
14101            int NT = receivers != null ? receivers.size() : 0;
14102            int it = 0;
14103            ResolveInfo curt = null;
14104            BroadcastFilter curr = null;
14105            while (it < NT && ir < NR) {
14106                if (curt == null) {
14107                    curt = (ResolveInfo)receivers.get(it);
14108                }
14109                if (curr == null) {
14110                    curr = registeredReceivers.get(ir);
14111                }
14112                if (curr.getPriority() >= curt.priority) {
14113                    // Insert this broadcast record into the final list.
14114                    receivers.add(it, curr);
14115                    ir++;
14116                    curr = null;
14117                    it++;
14118                    NT++;
14119                } else {
14120                    // Skip to the next ResolveInfo in the final list.
14121                    it++;
14122                    curt = null;
14123                }
14124            }
14125        }
14126        while (ir < NR) {
14127            if (receivers == null) {
14128                receivers = new ArrayList();
14129            }
14130            receivers.add(registeredReceivers.get(ir));
14131            ir++;
14132        }
14133
14134        if ((receivers != null && receivers.size() > 0)
14135                || resultTo != null) {
14136            BroadcastQueue queue = broadcastQueueForIntent(intent);
14137            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14138                    callerPackage, callingPid, callingUid, resolvedType,
14139                    requiredPermission, appOp, receivers, resultTo, resultCode,
14140                    resultData, map, ordered, sticky, false, userId);
14141            if (DEBUG_BROADCAST) Slog.v(
14142                    TAG, "Enqueueing ordered broadcast " + r
14143                    + ": prev had " + queue.mOrderedBroadcasts.size());
14144            if (DEBUG_BROADCAST) {
14145                int seq = r.intent.getIntExtra("seq", -1);
14146                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14147            }
14148            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14149            if (!replaced) {
14150                queue.enqueueOrderedBroadcastLocked(r);
14151                queue.scheduleBroadcastsLocked();
14152            }
14153        }
14154
14155        return ActivityManager.BROADCAST_SUCCESS;
14156    }
14157
14158    final Intent verifyBroadcastLocked(Intent intent) {
14159        // Refuse possible leaked file descriptors
14160        if (intent != null && intent.hasFileDescriptors() == true) {
14161            throw new IllegalArgumentException("File descriptors passed in Intent");
14162        }
14163
14164        int flags = intent.getFlags();
14165
14166        if (!mProcessesReady) {
14167            // if the caller really truly claims to know what they're doing, go
14168            // ahead and allow the broadcast without launching any receivers
14169            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14170                intent = new Intent(intent);
14171                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14172            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14173                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14174                        + " before boot completion");
14175                throw new IllegalStateException("Cannot broadcast before boot completed");
14176            }
14177        }
14178
14179        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14180            throw new IllegalArgumentException(
14181                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14182        }
14183
14184        return intent;
14185    }
14186
14187    public final int broadcastIntent(IApplicationThread caller,
14188            Intent intent, String resolvedType, IIntentReceiver resultTo,
14189            int resultCode, String resultData, Bundle map,
14190            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14191        enforceNotIsolatedCaller("broadcastIntent");
14192        synchronized(this) {
14193            intent = verifyBroadcastLocked(intent);
14194
14195            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14196            final int callingPid = Binder.getCallingPid();
14197            final int callingUid = Binder.getCallingUid();
14198            final long origId = Binder.clearCallingIdentity();
14199            int res = broadcastIntentLocked(callerApp,
14200                    callerApp != null ? callerApp.info.packageName : null,
14201                    intent, resolvedType, resultTo,
14202                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14203                    callingPid, callingUid, userId);
14204            Binder.restoreCallingIdentity(origId);
14205            return res;
14206        }
14207    }
14208
14209    int broadcastIntentInPackage(String packageName, int uid,
14210            Intent intent, String resolvedType, IIntentReceiver resultTo,
14211            int resultCode, String resultData, Bundle map,
14212            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14213        synchronized(this) {
14214            intent = verifyBroadcastLocked(intent);
14215
14216            final long origId = Binder.clearCallingIdentity();
14217            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14218                    resultTo, resultCode, resultData, map, requiredPermission,
14219                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14220            Binder.restoreCallingIdentity(origId);
14221            return res;
14222        }
14223    }
14224
14225    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14226        // Refuse possible leaked file descriptors
14227        if (intent != null && intent.hasFileDescriptors() == true) {
14228            throw new IllegalArgumentException("File descriptors passed in Intent");
14229        }
14230
14231        userId = handleIncomingUser(Binder.getCallingPid(),
14232                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14233
14234        synchronized(this) {
14235            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14236                    != PackageManager.PERMISSION_GRANTED) {
14237                String msg = "Permission Denial: unbroadcastIntent() from pid="
14238                        + Binder.getCallingPid()
14239                        + ", uid=" + Binder.getCallingUid()
14240                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14241                Slog.w(TAG, msg);
14242                throw new SecurityException(msg);
14243            }
14244            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14245            if (stickies != null) {
14246                ArrayList<Intent> list = stickies.get(intent.getAction());
14247                if (list != null) {
14248                    int N = list.size();
14249                    int i;
14250                    for (i=0; i<N; i++) {
14251                        if (intent.filterEquals(list.get(i))) {
14252                            list.remove(i);
14253                            break;
14254                        }
14255                    }
14256                    if (list.size() <= 0) {
14257                        stickies.remove(intent.getAction());
14258                    }
14259                }
14260                if (stickies.size() <= 0) {
14261                    mStickyBroadcasts.remove(userId);
14262                }
14263            }
14264        }
14265    }
14266
14267    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14268            String resultData, Bundle resultExtras, boolean resultAbort) {
14269        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14270        if (r == null) {
14271            Slog.w(TAG, "finishReceiver called but not found on queue");
14272            return false;
14273        }
14274
14275        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14276    }
14277
14278    void backgroundServicesFinishedLocked(int userId) {
14279        for (BroadcastQueue queue : mBroadcastQueues) {
14280            queue.backgroundServicesFinishedLocked(userId);
14281        }
14282    }
14283
14284    public void finishReceiver(IBinder who, int resultCode, String resultData,
14285            Bundle resultExtras, boolean resultAbort) {
14286        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14287
14288        // Refuse possible leaked file descriptors
14289        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14290            throw new IllegalArgumentException("File descriptors passed in Bundle");
14291        }
14292
14293        final long origId = Binder.clearCallingIdentity();
14294        try {
14295            boolean doNext = false;
14296            BroadcastRecord r;
14297
14298            synchronized(this) {
14299                r = broadcastRecordForReceiverLocked(who);
14300                if (r != null) {
14301                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14302                        resultData, resultExtras, resultAbort, true);
14303                }
14304            }
14305
14306            if (doNext) {
14307                r.queue.processNextBroadcast(false);
14308            }
14309            trimApplications();
14310        } finally {
14311            Binder.restoreCallingIdentity(origId);
14312        }
14313    }
14314
14315    // =========================================================
14316    // INSTRUMENTATION
14317    // =========================================================
14318
14319    public boolean startInstrumentation(ComponentName className,
14320            String profileFile, int flags, Bundle arguments,
14321            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14322            int userId, String abiOverride) {
14323        enforceNotIsolatedCaller("startInstrumentation");
14324        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14325                userId, false, true, "startInstrumentation", null);
14326        // Refuse possible leaked file descriptors
14327        if (arguments != null && arguments.hasFileDescriptors()) {
14328            throw new IllegalArgumentException("File descriptors passed in Bundle");
14329        }
14330
14331        synchronized(this) {
14332            InstrumentationInfo ii = null;
14333            ApplicationInfo ai = null;
14334            try {
14335                ii = mContext.getPackageManager().getInstrumentationInfo(
14336                    className, STOCK_PM_FLAGS);
14337                ai = AppGlobals.getPackageManager().getApplicationInfo(
14338                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14339            } catch (PackageManager.NameNotFoundException e) {
14340            } catch (RemoteException e) {
14341            }
14342            if (ii == null) {
14343                reportStartInstrumentationFailure(watcher, className,
14344                        "Unable to find instrumentation info for: " + className);
14345                return false;
14346            }
14347            if (ai == null) {
14348                reportStartInstrumentationFailure(watcher, className,
14349                        "Unable to find instrumentation target package: " + ii.targetPackage);
14350                return false;
14351            }
14352
14353            int match = mContext.getPackageManager().checkSignatures(
14354                    ii.targetPackage, ii.packageName);
14355            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14356                String msg = "Permission Denial: starting instrumentation "
14357                        + className + " from pid="
14358                        + Binder.getCallingPid()
14359                        + ", uid=" + Binder.getCallingPid()
14360                        + " not allowed because package " + ii.packageName
14361                        + " does not have a signature matching the target "
14362                        + ii.targetPackage;
14363                reportStartInstrumentationFailure(watcher, className, msg);
14364                throw new SecurityException(msg);
14365            }
14366
14367            final long origId = Binder.clearCallingIdentity();
14368            // Instrumentation can kill and relaunch even persistent processes
14369            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14370                    "start instr");
14371            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14372            app.instrumentationClass = className;
14373            app.instrumentationInfo = ai;
14374            app.instrumentationProfileFile = profileFile;
14375            app.instrumentationArguments = arguments;
14376            app.instrumentationWatcher = watcher;
14377            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14378            app.instrumentationResultClass = className;
14379            Binder.restoreCallingIdentity(origId);
14380        }
14381
14382        return true;
14383    }
14384
14385    /**
14386     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14387     * error to the logs, but if somebody is watching, send the report there too.  This enables
14388     * the "am" command to report errors with more information.
14389     *
14390     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14391     * @param cn The component name of the instrumentation.
14392     * @param report The error report.
14393     */
14394    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14395            ComponentName cn, String report) {
14396        Slog.w(TAG, report);
14397        try {
14398            if (watcher != null) {
14399                Bundle results = new Bundle();
14400                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14401                results.putString("Error", report);
14402                watcher.instrumentationStatus(cn, -1, results);
14403            }
14404        } catch (RemoteException e) {
14405            Slog.w(TAG, e);
14406        }
14407    }
14408
14409    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14410        if (app.instrumentationWatcher != null) {
14411            try {
14412                // NOTE:  IInstrumentationWatcher *must* be oneway here
14413                app.instrumentationWatcher.instrumentationFinished(
14414                    app.instrumentationClass,
14415                    resultCode,
14416                    results);
14417            } catch (RemoteException e) {
14418            }
14419        }
14420        if (app.instrumentationUiAutomationConnection != null) {
14421            try {
14422                app.instrumentationUiAutomationConnection.shutdown();
14423            } catch (RemoteException re) {
14424                /* ignore */
14425            }
14426            // Only a UiAutomation can set this flag and now that
14427            // it is finished we make sure it is reset to its default.
14428            mUserIsMonkey = false;
14429        }
14430        app.instrumentationWatcher = null;
14431        app.instrumentationUiAutomationConnection = null;
14432        app.instrumentationClass = null;
14433        app.instrumentationInfo = null;
14434        app.instrumentationProfileFile = null;
14435        app.instrumentationArguments = null;
14436
14437        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14438                "finished inst");
14439    }
14440
14441    public void finishInstrumentation(IApplicationThread target,
14442            int resultCode, Bundle results) {
14443        int userId = UserHandle.getCallingUserId();
14444        // Refuse possible leaked file descriptors
14445        if (results != null && results.hasFileDescriptors()) {
14446            throw new IllegalArgumentException("File descriptors passed in Intent");
14447        }
14448
14449        synchronized(this) {
14450            ProcessRecord app = getRecordForAppLocked(target);
14451            if (app == null) {
14452                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14453                return;
14454            }
14455            final long origId = Binder.clearCallingIdentity();
14456            finishInstrumentationLocked(app, resultCode, results);
14457            Binder.restoreCallingIdentity(origId);
14458        }
14459    }
14460
14461    // =========================================================
14462    // CONFIGURATION
14463    // =========================================================
14464
14465    public ConfigurationInfo getDeviceConfigurationInfo() {
14466        ConfigurationInfo config = new ConfigurationInfo();
14467        synchronized (this) {
14468            config.reqTouchScreen = mConfiguration.touchscreen;
14469            config.reqKeyboardType = mConfiguration.keyboard;
14470            config.reqNavigation = mConfiguration.navigation;
14471            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14472                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14473                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14474            }
14475            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14476                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14477                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14478            }
14479            config.reqGlEsVersion = GL_ES_VERSION;
14480        }
14481        return config;
14482    }
14483
14484    ActivityStack getFocusedStack() {
14485        return mStackSupervisor.getFocusedStack();
14486    }
14487
14488    public Configuration getConfiguration() {
14489        Configuration ci;
14490        synchronized(this) {
14491            ci = new Configuration(mConfiguration);
14492        }
14493        return ci;
14494    }
14495
14496    public void updatePersistentConfiguration(Configuration values) {
14497        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14498                "updateConfiguration()");
14499        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14500                "updateConfiguration()");
14501        if (values == null) {
14502            throw new NullPointerException("Configuration must not be null");
14503        }
14504
14505        synchronized(this) {
14506            final long origId = Binder.clearCallingIdentity();
14507            updateConfigurationLocked(values, null, true, false);
14508            Binder.restoreCallingIdentity(origId);
14509        }
14510    }
14511
14512    public void updateConfiguration(Configuration values) {
14513        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14514                "updateConfiguration()");
14515
14516        synchronized(this) {
14517            if (values == null && mWindowManager != null) {
14518                // sentinel: fetch the current configuration from the window manager
14519                values = mWindowManager.computeNewConfiguration();
14520            }
14521
14522            if (mWindowManager != null) {
14523                mProcessList.applyDisplaySize(mWindowManager);
14524            }
14525
14526            final long origId = Binder.clearCallingIdentity();
14527            if (values != null) {
14528                Settings.System.clearConfiguration(values);
14529            }
14530            updateConfigurationLocked(values, null, false, false);
14531            Binder.restoreCallingIdentity(origId);
14532        }
14533    }
14534
14535    /**
14536     * Do either or both things: (1) change the current configuration, and (2)
14537     * make sure the given activity is running with the (now) current
14538     * configuration.  Returns true if the activity has been left running, or
14539     * false if <var>starting</var> is being destroyed to match the new
14540     * configuration.
14541     * @param persistent TODO
14542     */
14543    boolean updateConfigurationLocked(Configuration values,
14544            ActivityRecord starting, boolean persistent, boolean initLocale) {
14545        int changes = 0;
14546
14547        if (values != null) {
14548            Configuration newConfig = new Configuration(mConfiguration);
14549            changes = newConfig.updateFrom(values);
14550            if (changes != 0) {
14551                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14552                    Slog.i(TAG, "Updating configuration to: " + values);
14553                }
14554
14555                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14556
14557                if (values.locale != null && !initLocale) {
14558                    saveLocaleLocked(values.locale,
14559                                     !values.locale.equals(mConfiguration.locale),
14560                                     values.userSetLocale);
14561                }
14562
14563                mConfigurationSeq++;
14564                if (mConfigurationSeq <= 0) {
14565                    mConfigurationSeq = 1;
14566                }
14567                newConfig.seq = mConfigurationSeq;
14568                mConfiguration = newConfig;
14569                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14570                mUsageStatsService.noteStartConfig(newConfig);
14571
14572                final Configuration configCopy = new Configuration(mConfiguration);
14573
14574                // TODO: If our config changes, should we auto dismiss any currently
14575                // showing dialogs?
14576                mShowDialogs = shouldShowDialogs(newConfig);
14577
14578                AttributeCache ac = AttributeCache.instance();
14579                if (ac != null) {
14580                    ac.updateConfiguration(configCopy);
14581                }
14582
14583                // Make sure all resources in our process are updated
14584                // right now, so that anyone who is going to retrieve
14585                // resource values after we return will be sure to get
14586                // the new ones.  This is especially important during
14587                // boot, where the first config change needs to guarantee
14588                // all resources have that config before following boot
14589                // code is executed.
14590                mSystemThread.applyConfigurationToResources(configCopy);
14591
14592                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14593                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14594                    msg.obj = new Configuration(configCopy);
14595                    mHandler.sendMessage(msg);
14596                }
14597
14598                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14599                    ProcessRecord app = mLruProcesses.get(i);
14600                    try {
14601                        if (app.thread != null) {
14602                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14603                                    + app.processName + " new config " + mConfiguration);
14604                            app.thread.scheduleConfigurationChanged(configCopy);
14605                        }
14606                    } catch (Exception e) {
14607                    }
14608                }
14609                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14610                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14611                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14612                        | Intent.FLAG_RECEIVER_FOREGROUND);
14613                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14614                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14615                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14616                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14617                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14618                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14619                    broadcastIntentLocked(null, null, intent,
14620                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14621                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14622                }
14623            }
14624        }
14625
14626        boolean kept = true;
14627        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14628        // mainStack is null during startup.
14629        if (mainStack != null) {
14630            if (changes != 0 && starting == null) {
14631                // If the configuration changed, and the caller is not already
14632                // in the process of starting an activity, then find the top
14633                // activity to check if its configuration needs to change.
14634                starting = mainStack.topRunningActivityLocked(null);
14635            }
14636
14637            if (starting != null) {
14638                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14639                // And we need to make sure at this point that all other activities
14640                // are made visible with the correct configuration.
14641                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14642            }
14643        }
14644
14645        if (values != null && mWindowManager != null) {
14646            mWindowManager.setNewConfiguration(mConfiguration);
14647        }
14648
14649        return kept;
14650    }
14651
14652    /**
14653     * Decide based on the configuration whether we should shouw the ANR,
14654     * crash, etc dialogs.  The idea is that if there is no affordnace to
14655     * press the on-screen buttons, we shouldn't show the dialog.
14656     *
14657     * A thought: SystemUI might also want to get told about this, the Power
14658     * dialog / global actions also might want different behaviors.
14659     */
14660    private static final boolean shouldShowDialogs(Configuration config) {
14661        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14662                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14663    }
14664
14665    /**
14666     * Save the locale.  You must be inside a synchronized (this) block.
14667     */
14668    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14669        if(isDiff) {
14670            SystemProperties.set("user.language", l.getLanguage());
14671            SystemProperties.set("user.region", l.getCountry());
14672        }
14673
14674        if(isPersist) {
14675            SystemProperties.set("persist.sys.language", l.getLanguage());
14676            SystemProperties.set("persist.sys.country", l.getCountry());
14677            SystemProperties.set("persist.sys.localevar", l.getVariant());
14678        }
14679    }
14680
14681    @Override
14682    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14683        ActivityRecord srec = ActivityRecord.forToken(token);
14684        return srec != null && srec.task.affinity != null &&
14685                srec.task.affinity.equals(destAffinity);
14686    }
14687
14688    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14689            Intent resultData) {
14690
14691        synchronized (this) {
14692            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14693            if (stack != null) {
14694                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14695            }
14696            return false;
14697        }
14698    }
14699
14700    public int getLaunchedFromUid(IBinder activityToken) {
14701        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14702        if (srec == null) {
14703            return -1;
14704        }
14705        return srec.launchedFromUid;
14706    }
14707
14708    public String getLaunchedFromPackage(IBinder activityToken) {
14709        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14710        if (srec == null) {
14711            return null;
14712        }
14713        return srec.launchedFromPackage;
14714    }
14715
14716    // =========================================================
14717    // LIFETIME MANAGEMENT
14718    // =========================================================
14719
14720    // Returns which broadcast queue the app is the current [or imminent] receiver
14721    // on, or 'null' if the app is not an active broadcast recipient.
14722    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14723        BroadcastRecord r = app.curReceiver;
14724        if (r != null) {
14725            return r.queue;
14726        }
14727
14728        // It's not the current receiver, but it might be starting up to become one
14729        synchronized (this) {
14730            for (BroadcastQueue queue : mBroadcastQueues) {
14731                r = queue.mPendingBroadcast;
14732                if (r != null && r.curApp == app) {
14733                    // found it; report which queue it's in
14734                    return queue;
14735                }
14736            }
14737        }
14738
14739        return null;
14740    }
14741
14742    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14743            boolean doingAll, long now) {
14744        if (mAdjSeq == app.adjSeq) {
14745            // This adjustment has already been computed.
14746            return app.curRawAdj;
14747        }
14748
14749        if (app.thread == null) {
14750            app.adjSeq = mAdjSeq;
14751            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14752            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14753            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14754        }
14755
14756        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14757        app.adjSource = null;
14758        app.adjTarget = null;
14759        app.empty = false;
14760        app.cached = false;
14761
14762        final int activitiesSize = app.activities.size();
14763
14764        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14765            // The max adjustment doesn't allow this app to be anything
14766            // below foreground, so it is not worth doing work for it.
14767            app.adjType = "fixed";
14768            app.adjSeq = mAdjSeq;
14769            app.curRawAdj = app.maxAdj;
14770            app.foregroundActivities = false;
14771            app.keeping = true;
14772            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14773            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14774            // System processes can do UI, and when they do we want to have
14775            // them trim their memory after the user leaves the UI.  To
14776            // facilitate this, here we need to determine whether or not it
14777            // is currently showing UI.
14778            app.systemNoUi = true;
14779            if (app == TOP_APP) {
14780                app.systemNoUi = false;
14781            } else if (activitiesSize > 0) {
14782                for (int j = 0; j < activitiesSize; j++) {
14783                    final ActivityRecord r = app.activities.get(j);
14784                    if (r.visible) {
14785                        app.systemNoUi = false;
14786                    }
14787                }
14788            }
14789            if (!app.systemNoUi) {
14790                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14791            }
14792            return (app.curAdj=app.maxAdj);
14793        }
14794
14795        app.keeping = false;
14796        app.systemNoUi = false;
14797
14798        // Determine the importance of the process, starting with most
14799        // important to least, and assign an appropriate OOM adjustment.
14800        int adj;
14801        int schedGroup;
14802        int procState;
14803        boolean foregroundActivities = false;
14804        boolean interesting = false;
14805        BroadcastQueue queue;
14806        if (app == TOP_APP) {
14807            // The last app on the list is the foreground app.
14808            adj = ProcessList.FOREGROUND_APP_ADJ;
14809            schedGroup = Process.THREAD_GROUP_DEFAULT;
14810            app.adjType = "top-activity";
14811            foregroundActivities = true;
14812            interesting = true;
14813            procState = ActivityManager.PROCESS_STATE_TOP;
14814        } else if (app.instrumentationClass != null) {
14815            // Don't want to kill running instrumentation.
14816            adj = ProcessList.FOREGROUND_APP_ADJ;
14817            schedGroup = Process.THREAD_GROUP_DEFAULT;
14818            app.adjType = "instrumentation";
14819            interesting = true;
14820            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14821        } else if ((queue = isReceivingBroadcast(app)) != null) {
14822            // An app that is currently receiving a broadcast also
14823            // counts as being in the foreground for OOM killer purposes.
14824            // It's placed in a sched group based on the nature of the
14825            // broadcast as reflected by which queue it's active in.
14826            adj = ProcessList.FOREGROUND_APP_ADJ;
14827            schedGroup = (queue == mFgBroadcastQueue)
14828                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14829            app.adjType = "broadcast";
14830            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14831        } else if (app.executingServices.size() > 0) {
14832            // An app that is currently executing a service callback also
14833            // counts as being in the foreground.
14834            adj = ProcessList.FOREGROUND_APP_ADJ;
14835            schedGroup = app.execServicesFg ?
14836                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14837            app.adjType = "exec-service";
14838            procState = ActivityManager.PROCESS_STATE_SERVICE;
14839            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14840        } else {
14841            // As far as we know the process is empty.  We may change our mind later.
14842            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14843            // At this point we don't actually know the adjustment.  Use the cached adj
14844            // value that the caller wants us to.
14845            adj = cachedAdj;
14846            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14847            app.cached = true;
14848            app.empty = true;
14849            app.adjType = "cch-empty";
14850        }
14851
14852        // Examine all activities if not already foreground.
14853        if (!foregroundActivities && activitiesSize > 0) {
14854            for (int j = 0; j < activitiesSize; j++) {
14855                final ActivityRecord r = app.activities.get(j);
14856                if (r.app != app) {
14857                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14858                            + app + "?!?");
14859                    continue;
14860                }
14861                if (r.visible) {
14862                    // App has a visible activity; only upgrade adjustment.
14863                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14864                        adj = ProcessList.VISIBLE_APP_ADJ;
14865                        app.adjType = "visible";
14866                    }
14867                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14868                        procState = ActivityManager.PROCESS_STATE_TOP;
14869                    }
14870                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14871                    app.cached = false;
14872                    app.empty = false;
14873                    foregroundActivities = true;
14874                    break;
14875                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14876                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14877                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14878                        app.adjType = "pausing";
14879                    }
14880                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14881                        procState = ActivityManager.PROCESS_STATE_TOP;
14882                    }
14883                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14884                    app.cached = false;
14885                    app.empty = false;
14886                    foregroundActivities = true;
14887                } else if (r.state == ActivityState.STOPPING) {
14888                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14889                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14890                        app.adjType = "stopping";
14891                    }
14892                    // For the process state, we will at this point consider the
14893                    // process to be cached.  It will be cached either as an activity
14894                    // or empty depending on whether the activity is finishing.  We do
14895                    // this so that we can treat the process as cached for purposes of
14896                    // memory trimming (determing current memory level, trim command to
14897                    // send to process) since there can be an arbitrary number of stopping
14898                    // processes and they should soon all go into the cached state.
14899                    if (!r.finishing) {
14900                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14901                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14902                        }
14903                    }
14904                    app.cached = false;
14905                    app.empty = false;
14906                    foregroundActivities = true;
14907                } else {
14908                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14909                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14910                        app.adjType = "cch-act";
14911                    }
14912                }
14913            }
14914        }
14915
14916        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14917            if (app.foregroundServices) {
14918                // The user is aware of this app, so make it visible.
14919                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14920                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14921                app.cached = false;
14922                app.adjType = "fg-service";
14923                schedGroup = Process.THREAD_GROUP_DEFAULT;
14924            } else if (app.forcingToForeground != null) {
14925                // The user is aware of this app, so make it visible.
14926                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14927                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14928                app.cached = false;
14929                app.adjType = "force-fg";
14930                app.adjSource = app.forcingToForeground;
14931                schedGroup = Process.THREAD_GROUP_DEFAULT;
14932            }
14933        }
14934
14935        if (app.foregroundServices) {
14936            interesting = true;
14937        }
14938
14939        if (app == mHeavyWeightProcess) {
14940            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14941                // We don't want to kill the current heavy-weight process.
14942                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14943                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14944                app.cached = false;
14945                app.adjType = "heavy";
14946            }
14947            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14948                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14949            }
14950        }
14951
14952        if (app == mHomeProcess) {
14953            if (adj > ProcessList.HOME_APP_ADJ) {
14954                // This process is hosting what we currently consider to be the
14955                // home app, so we don't want to let it go into the background.
14956                adj = ProcessList.HOME_APP_ADJ;
14957                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14958                app.cached = false;
14959                app.adjType = "home";
14960            }
14961            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14962                procState = ActivityManager.PROCESS_STATE_HOME;
14963            }
14964        }
14965
14966        if (app == mPreviousProcess && app.activities.size() > 0) {
14967            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14968                // This was the previous process that showed UI to the user.
14969                // We want to try to keep it around more aggressively, to give
14970                // a good experience around switching between two apps.
14971                adj = ProcessList.PREVIOUS_APP_ADJ;
14972                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14973                app.cached = false;
14974                app.adjType = "previous";
14975            }
14976            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14977                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14978            }
14979        }
14980
14981        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14982                + " reason=" + app.adjType);
14983
14984        // By default, we use the computed adjustment.  It may be changed if
14985        // there are applications dependent on our services or providers, but
14986        // this gives us a baseline and makes sure we don't get into an
14987        // infinite recursion.
14988        app.adjSeq = mAdjSeq;
14989        app.curRawAdj = adj;
14990        app.hasStartedServices = false;
14991
14992        if (mBackupTarget != null && app == mBackupTarget.app) {
14993            // If possible we want to avoid killing apps while they're being backed up
14994            if (adj > ProcessList.BACKUP_APP_ADJ) {
14995                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14996                adj = ProcessList.BACKUP_APP_ADJ;
14997                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14998                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14999                }
15000                app.adjType = "backup";
15001                app.cached = false;
15002            }
15003            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15004                procState = ActivityManager.PROCESS_STATE_BACKUP;
15005            }
15006        }
15007
15008        boolean mayBeTop = false;
15009
15010        for (int is = app.services.size()-1;
15011                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15012                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15013                        || procState > ActivityManager.PROCESS_STATE_TOP);
15014                is--) {
15015            ServiceRecord s = app.services.valueAt(is);
15016            if (s.startRequested) {
15017                app.hasStartedServices = true;
15018                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15019                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15020                }
15021                if (app.hasShownUi && app != mHomeProcess) {
15022                    // If this process has shown some UI, let it immediately
15023                    // go to the LRU list because it may be pretty heavy with
15024                    // UI stuff.  We'll tag it with a label just to help
15025                    // debug and understand what is going on.
15026                    if (adj > ProcessList.SERVICE_ADJ) {
15027                        app.adjType = "cch-started-ui-services";
15028                    }
15029                } else {
15030                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15031                        // This service has seen some activity within
15032                        // recent memory, so we will keep its process ahead
15033                        // of the background processes.
15034                        if (adj > ProcessList.SERVICE_ADJ) {
15035                            adj = ProcessList.SERVICE_ADJ;
15036                            app.adjType = "started-services";
15037                            app.cached = false;
15038                        }
15039                    }
15040                    // If we have let the service slide into the background
15041                    // state, still have some text describing what it is doing
15042                    // even though the service no longer has an impact.
15043                    if (adj > ProcessList.SERVICE_ADJ) {
15044                        app.adjType = "cch-started-services";
15045                    }
15046                }
15047                // Don't kill this process because it is doing work; it
15048                // has said it is doing work.
15049                app.keeping = true;
15050            }
15051            for (int conni = s.connections.size()-1;
15052                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15053                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15054                            || procState > ActivityManager.PROCESS_STATE_TOP);
15055                    conni--) {
15056                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15057                for (int i = 0;
15058                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15059                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15060                                || procState > ActivityManager.PROCESS_STATE_TOP);
15061                        i++) {
15062                    // XXX should compute this based on the max of
15063                    // all connected clients.
15064                    ConnectionRecord cr = clist.get(i);
15065                    if (cr.binding.client == app) {
15066                        // Binding to ourself is not interesting.
15067                        continue;
15068                    }
15069                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15070                        ProcessRecord client = cr.binding.client;
15071                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15072                                TOP_APP, doingAll, now);
15073                        int clientProcState = client.curProcState;
15074                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15075                            // If the other app is cached for any reason, for purposes here
15076                            // we are going to consider it empty.  The specific cached state
15077                            // doesn't propagate except under certain conditions.
15078                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15079                        }
15080                        String adjType = null;
15081                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15082                            // Not doing bind OOM management, so treat
15083                            // this guy more like a started service.
15084                            if (app.hasShownUi && app != mHomeProcess) {
15085                                // If this process has shown some UI, let it immediately
15086                                // go to the LRU list because it may be pretty heavy with
15087                                // UI stuff.  We'll tag it with a label just to help
15088                                // debug and understand what is going on.
15089                                if (adj > clientAdj) {
15090                                    adjType = "cch-bound-ui-services";
15091                                }
15092                                app.cached = false;
15093                                clientAdj = adj;
15094                                clientProcState = procState;
15095                            } else {
15096                                if (now >= (s.lastActivity
15097                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15098                                    // This service has not seen activity within
15099                                    // recent memory, so allow it to drop to the
15100                                    // LRU list if there is no other reason to keep
15101                                    // it around.  We'll also tag it with a label just
15102                                    // to help debug and undertand what is going on.
15103                                    if (adj > clientAdj) {
15104                                        adjType = "cch-bound-services";
15105                                    }
15106                                    clientAdj = adj;
15107                                }
15108                            }
15109                        }
15110                        if (adj > clientAdj) {
15111                            // If this process has recently shown UI, and
15112                            // the process that is binding to it is less
15113                            // important than being visible, then we don't
15114                            // care about the binding as much as we care
15115                            // about letting this process get into the LRU
15116                            // list to be killed and restarted if needed for
15117                            // memory.
15118                            if (app.hasShownUi && app != mHomeProcess
15119                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15120                                adjType = "cch-bound-ui-services";
15121                            } else {
15122                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15123                                        |Context.BIND_IMPORTANT)) != 0) {
15124                                    adj = clientAdj;
15125                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15126                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15127                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15128                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15129                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15130                                    adj = clientAdj;
15131                                } else {
15132                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15133                                        adj = ProcessList.VISIBLE_APP_ADJ;
15134                                    }
15135                                }
15136                                if (!client.cached) {
15137                                    app.cached = false;
15138                                }
15139                                if (client.keeping) {
15140                                    app.keeping = true;
15141                                }
15142                                adjType = "service";
15143                            }
15144                        }
15145                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15146                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15147                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15148                            }
15149                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15150                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15151                                    // Special handling of clients who are in the top state.
15152                                    // We *may* want to consider this process to be in the
15153                                    // top state as well, but only if there is not another
15154                                    // reason for it to be running.  Being on the top is a
15155                                    // special state, meaning you are specifically running
15156                                    // for the current top app.  If the process is already
15157                                    // running in the background for some other reason, it
15158                                    // is more important to continue considering it to be
15159                                    // in the background state.
15160                                    mayBeTop = true;
15161                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15162                                } else {
15163                                    // Special handling for above-top states (persistent
15164                                    // processes).  These should not bring the current process
15165                                    // into the top state, since they are not on top.  Instead
15166                                    // give them the best state after that.
15167                                    clientProcState =
15168                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15169                                }
15170                            }
15171                        } else {
15172                            if (clientProcState <
15173                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15174                                clientProcState =
15175                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15176                            }
15177                        }
15178                        if (procState > clientProcState) {
15179                            procState = clientProcState;
15180                        }
15181                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15182                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15183                            app.pendingUiClean = true;
15184                        }
15185                        if (adjType != null) {
15186                            app.adjType = adjType;
15187                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15188                                    .REASON_SERVICE_IN_USE;
15189                            app.adjSource = cr.binding.client;
15190                            app.adjSourceOom = clientAdj;
15191                            app.adjTarget = s.name;
15192                        }
15193                    }
15194                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15195                        app.treatLikeActivity = true;
15196                    }
15197                    final ActivityRecord a = cr.activity;
15198                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15199                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15200                                (a.visible || a.state == ActivityState.RESUMED
15201                                 || a.state == ActivityState.PAUSING)) {
15202                            adj = ProcessList.FOREGROUND_APP_ADJ;
15203                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15204                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15205                            }
15206                            app.cached = false;
15207                            app.adjType = "service";
15208                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15209                                    .REASON_SERVICE_IN_USE;
15210                            app.adjSource = a;
15211                            app.adjSourceOom = adj;
15212                            app.adjTarget = s.name;
15213                        }
15214                    }
15215                }
15216            }
15217        }
15218
15219        for (int provi = app.pubProviders.size()-1;
15220                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15221                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15222                        || procState > ActivityManager.PROCESS_STATE_TOP);
15223                provi--) {
15224            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15225            for (int i = cpr.connections.size()-1;
15226                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15227                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15228                            || procState > ActivityManager.PROCESS_STATE_TOP);
15229                    i--) {
15230                ContentProviderConnection conn = cpr.connections.get(i);
15231                ProcessRecord client = conn.client;
15232                if (client == app) {
15233                    // Being our own client is not interesting.
15234                    continue;
15235                }
15236                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15237                int clientProcState = client.curProcState;
15238                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15239                    // If the other app is cached for any reason, for purposes here
15240                    // we are going to consider it empty.
15241                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15242                }
15243                if (adj > clientAdj) {
15244                    if (app.hasShownUi && app != mHomeProcess
15245                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15246                        app.adjType = "cch-ui-provider";
15247                    } else {
15248                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15249                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15250                        app.adjType = "provider";
15251                    }
15252                    app.cached &= client.cached;
15253                    app.keeping |= client.keeping;
15254                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15255                            .REASON_PROVIDER_IN_USE;
15256                    app.adjSource = client;
15257                    app.adjSourceOom = clientAdj;
15258                    app.adjTarget = cpr.name;
15259                }
15260                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15261                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15262                        // Special handling of clients who are in the top state.
15263                        // We *may* want to consider this process to be in the
15264                        // top state as well, but only if there is not another
15265                        // reason for it to be running.  Being on the top is a
15266                        // special state, meaning you are specifically running
15267                        // for the current top app.  If the process is already
15268                        // running in the background for some other reason, it
15269                        // is more important to continue considering it to be
15270                        // in the background state.
15271                        mayBeTop = true;
15272                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15273                    } else {
15274                        // Special handling for above-top states (persistent
15275                        // processes).  These should not bring the current process
15276                        // into the top state, since they are not on top.  Instead
15277                        // give them the best state after that.
15278                        clientProcState =
15279                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15280                    }
15281                }
15282                if (procState > clientProcState) {
15283                    procState = clientProcState;
15284                }
15285                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15286                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15287                }
15288            }
15289            // If the provider has external (non-framework) process
15290            // dependencies, ensure that its adjustment is at least
15291            // FOREGROUND_APP_ADJ.
15292            if (cpr.hasExternalProcessHandles()) {
15293                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15294                    adj = ProcessList.FOREGROUND_APP_ADJ;
15295                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15296                    app.cached = false;
15297                    app.keeping = true;
15298                    app.adjType = "provider";
15299                    app.adjTarget = cpr.name;
15300                }
15301                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15302                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15303                }
15304            }
15305        }
15306
15307        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15308            // A client of one of our services or providers is in the top state.  We
15309            // *may* want to be in the top state, but not if we are already running in
15310            // the background for some other reason.  For the decision here, we are going
15311            // to pick out a few specific states that we want to remain in when a client
15312            // is top (states that tend to be longer-term) and otherwise allow it to go
15313            // to the top state.
15314            switch (procState) {
15315                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15316                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15317                case ActivityManager.PROCESS_STATE_SERVICE:
15318                    // These all are longer-term states, so pull them up to the top
15319                    // of the background states, but not all the way to the top state.
15320                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15321                    break;
15322                default:
15323                    // Otherwise, top is a better choice, so take it.
15324                    procState = ActivityManager.PROCESS_STATE_TOP;
15325                    break;
15326            }
15327        }
15328
15329        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15330            if (app.hasClientActivities) {
15331                // This is a cached process, but with client activities.  Mark it so.
15332                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15333                app.adjType = "cch-client-act";
15334            } else if (app.treatLikeActivity) {
15335                // This is a cached process, but somebody wants us to treat it like it has
15336                // an activity, okay!
15337                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15338                app.adjType = "cch-as-act";
15339            }
15340        }
15341
15342        if (adj == ProcessList.SERVICE_ADJ) {
15343            if (doingAll) {
15344                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15345                mNewNumServiceProcs++;
15346                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15347                if (!app.serviceb) {
15348                    // This service isn't far enough down on the LRU list to
15349                    // normally be a B service, but if we are low on RAM and it
15350                    // is large we want to force it down since we would prefer to
15351                    // keep launcher over it.
15352                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15353                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15354                        app.serviceHighRam = true;
15355                        app.serviceb = true;
15356                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15357                    } else {
15358                        mNewNumAServiceProcs++;
15359                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15360                    }
15361                } else {
15362                    app.serviceHighRam = false;
15363                }
15364            }
15365            if (app.serviceb) {
15366                adj = ProcessList.SERVICE_B_ADJ;
15367            }
15368        }
15369
15370        app.curRawAdj = adj;
15371
15372        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15373        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15374        if (adj > app.maxAdj) {
15375            adj = app.maxAdj;
15376            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15377                schedGroup = Process.THREAD_GROUP_DEFAULT;
15378            }
15379        }
15380        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15381            app.keeping = true;
15382        }
15383
15384        // Do final modification to adj.  Everything we do between here and applying
15385        // the final setAdj must be done in this function, because we will also use
15386        // it when computing the final cached adj later.  Note that we don't need to
15387        // worry about this for max adj above, since max adj will always be used to
15388        // keep it out of the cached vaues.
15389        app.curAdj = app.modifyRawOomAdj(adj);
15390        app.curSchedGroup = schedGroup;
15391        app.curProcState = procState;
15392        app.foregroundActivities = foregroundActivities;
15393
15394        return app.curRawAdj;
15395    }
15396
15397    /**
15398     * Schedule PSS collection of a process.
15399     */
15400    void requestPssLocked(ProcessRecord proc, int procState) {
15401        if (mPendingPssProcesses.contains(proc)) {
15402            return;
15403        }
15404        if (mPendingPssProcesses.size() == 0) {
15405            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15406        }
15407        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15408        proc.pssProcState = procState;
15409        mPendingPssProcesses.add(proc);
15410    }
15411
15412    /**
15413     * Schedule PSS collection of all processes.
15414     */
15415    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15416        if (!always) {
15417            if (now < (mLastFullPssTime +
15418                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15419                return;
15420            }
15421        }
15422        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15423        mLastFullPssTime = now;
15424        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15425        mPendingPssProcesses.clear();
15426        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15427            ProcessRecord app = mLruProcesses.get(i);
15428            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15429                app.pssProcState = app.setProcState;
15430                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15431                        isSleeping(), now);
15432                mPendingPssProcesses.add(app);
15433            }
15434        }
15435        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15436    }
15437
15438    /**
15439     * Ask a given process to GC right now.
15440     */
15441    final void performAppGcLocked(ProcessRecord app) {
15442        try {
15443            app.lastRequestedGc = SystemClock.uptimeMillis();
15444            if (app.thread != null) {
15445                if (app.reportLowMemory) {
15446                    app.reportLowMemory = false;
15447                    app.thread.scheduleLowMemory();
15448                } else {
15449                    app.thread.processInBackground();
15450                }
15451            }
15452        } catch (Exception e) {
15453            // whatever.
15454        }
15455    }
15456
15457    /**
15458     * Returns true if things are idle enough to perform GCs.
15459     */
15460    private final boolean canGcNowLocked() {
15461        boolean processingBroadcasts = false;
15462        for (BroadcastQueue q : mBroadcastQueues) {
15463            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15464                processingBroadcasts = true;
15465            }
15466        }
15467        return !processingBroadcasts
15468                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15469    }
15470
15471    /**
15472     * Perform GCs on all processes that are waiting for it, but only
15473     * if things are idle.
15474     */
15475    final void performAppGcsLocked() {
15476        final int N = mProcessesToGc.size();
15477        if (N <= 0) {
15478            return;
15479        }
15480        if (canGcNowLocked()) {
15481            while (mProcessesToGc.size() > 0) {
15482                ProcessRecord proc = mProcessesToGc.remove(0);
15483                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15484                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15485                            <= SystemClock.uptimeMillis()) {
15486                        // To avoid spamming the system, we will GC processes one
15487                        // at a time, waiting a few seconds between each.
15488                        performAppGcLocked(proc);
15489                        scheduleAppGcsLocked();
15490                        return;
15491                    } else {
15492                        // It hasn't been long enough since we last GCed this
15493                        // process...  put it in the list to wait for its time.
15494                        addProcessToGcListLocked(proc);
15495                        break;
15496                    }
15497                }
15498            }
15499
15500            scheduleAppGcsLocked();
15501        }
15502    }
15503
15504    /**
15505     * If all looks good, perform GCs on all processes waiting for them.
15506     */
15507    final void performAppGcsIfAppropriateLocked() {
15508        if (canGcNowLocked()) {
15509            performAppGcsLocked();
15510            return;
15511        }
15512        // Still not idle, wait some more.
15513        scheduleAppGcsLocked();
15514    }
15515
15516    /**
15517     * Schedule the execution of all pending app GCs.
15518     */
15519    final void scheduleAppGcsLocked() {
15520        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15521
15522        if (mProcessesToGc.size() > 0) {
15523            // Schedule a GC for the time to the next process.
15524            ProcessRecord proc = mProcessesToGc.get(0);
15525            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15526
15527            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15528            long now = SystemClock.uptimeMillis();
15529            if (when < (now+GC_TIMEOUT)) {
15530                when = now + GC_TIMEOUT;
15531            }
15532            mHandler.sendMessageAtTime(msg, when);
15533        }
15534    }
15535
15536    /**
15537     * Add a process to the array of processes waiting to be GCed.  Keeps the
15538     * list in sorted order by the last GC time.  The process can't already be
15539     * on the list.
15540     */
15541    final void addProcessToGcListLocked(ProcessRecord proc) {
15542        boolean added = false;
15543        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15544            if (mProcessesToGc.get(i).lastRequestedGc <
15545                    proc.lastRequestedGc) {
15546                added = true;
15547                mProcessesToGc.add(i+1, proc);
15548                break;
15549            }
15550        }
15551        if (!added) {
15552            mProcessesToGc.add(0, proc);
15553        }
15554    }
15555
15556    /**
15557     * Set up to ask a process to GC itself.  This will either do it
15558     * immediately, or put it on the list of processes to gc the next
15559     * time things are idle.
15560     */
15561    final void scheduleAppGcLocked(ProcessRecord app) {
15562        long now = SystemClock.uptimeMillis();
15563        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15564            return;
15565        }
15566        if (!mProcessesToGc.contains(app)) {
15567            addProcessToGcListLocked(app);
15568            scheduleAppGcsLocked();
15569        }
15570    }
15571
15572    final void checkExcessivePowerUsageLocked(boolean doKills) {
15573        updateCpuStatsNow();
15574
15575        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15576        boolean doWakeKills = doKills;
15577        boolean doCpuKills = doKills;
15578        if (mLastPowerCheckRealtime == 0) {
15579            doWakeKills = false;
15580        }
15581        if (mLastPowerCheckUptime == 0) {
15582            doCpuKills = false;
15583        }
15584        if (stats.isScreenOn()) {
15585            doWakeKills = false;
15586        }
15587        final long curRealtime = SystemClock.elapsedRealtime();
15588        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15589        final long curUptime = SystemClock.uptimeMillis();
15590        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15591        mLastPowerCheckRealtime = curRealtime;
15592        mLastPowerCheckUptime = curUptime;
15593        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15594            doWakeKills = false;
15595        }
15596        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15597            doCpuKills = false;
15598        }
15599        int i = mLruProcesses.size();
15600        while (i > 0) {
15601            i--;
15602            ProcessRecord app = mLruProcesses.get(i);
15603            if (!app.keeping) {
15604                long wtime;
15605                synchronized (stats) {
15606                    wtime = stats.getProcessWakeTime(app.info.uid,
15607                            app.pid, curRealtime);
15608                }
15609                long wtimeUsed = wtime - app.lastWakeTime;
15610                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15611                if (DEBUG_POWER) {
15612                    StringBuilder sb = new StringBuilder(128);
15613                    sb.append("Wake for ");
15614                    app.toShortString(sb);
15615                    sb.append(": over ");
15616                    TimeUtils.formatDuration(realtimeSince, sb);
15617                    sb.append(" used ");
15618                    TimeUtils.formatDuration(wtimeUsed, sb);
15619                    sb.append(" (");
15620                    sb.append((wtimeUsed*100)/realtimeSince);
15621                    sb.append("%)");
15622                    Slog.i(TAG, sb.toString());
15623                    sb.setLength(0);
15624                    sb.append("CPU for ");
15625                    app.toShortString(sb);
15626                    sb.append(": over ");
15627                    TimeUtils.formatDuration(uptimeSince, sb);
15628                    sb.append(" used ");
15629                    TimeUtils.formatDuration(cputimeUsed, sb);
15630                    sb.append(" (");
15631                    sb.append((cputimeUsed*100)/uptimeSince);
15632                    sb.append("%)");
15633                    Slog.i(TAG, sb.toString());
15634                }
15635                // If a process has held a wake lock for more
15636                // than 50% of the time during this period,
15637                // that sounds bad.  Kill!
15638                if (doWakeKills && realtimeSince > 0
15639                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15640                    synchronized (stats) {
15641                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15642                                realtimeSince, wtimeUsed);
15643                    }
15644                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15645                            + " during " + realtimeSince);
15646                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15647                } else if (doCpuKills && uptimeSince > 0
15648                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15649                    synchronized (stats) {
15650                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15651                                uptimeSince, cputimeUsed);
15652                    }
15653                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15654                            + " during " + uptimeSince);
15655                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15656                } else {
15657                    app.lastWakeTime = wtime;
15658                    app.lastCpuTime = app.curCpuTime;
15659                }
15660            }
15661        }
15662    }
15663
15664    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15665            ProcessRecord TOP_APP, boolean doingAll, long now) {
15666        boolean success = true;
15667
15668        if (app.curRawAdj != app.setRawAdj) {
15669            if (wasKeeping && !app.keeping) {
15670                // This app is no longer something we want to keep.  Note
15671                // its current wake lock time to later know to kill it if
15672                // it is not behaving well.
15673                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15674                synchronized (stats) {
15675                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15676                            app.pid, SystemClock.elapsedRealtime());
15677                }
15678                app.lastCpuTime = app.curCpuTime;
15679            }
15680
15681            app.setRawAdj = app.curRawAdj;
15682        }
15683
15684        int changes = 0;
15685
15686        if (app.curAdj != app.setAdj) {
15687            ProcessList.setOomAdj(app.pid, app.curAdj);
15688            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15689                TAG, "Set " + app.pid + " " + app.processName +
15690                " adj " + app.curAdj + ": " + app.adjType);
15691            app.setAdj = app.curAdj;
15692        }
15693
15694        if (app.setSchedGroup != app.curSchedGroup) {
15695            app.setSchedGroup = app.curSchedGroup;
15696            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15697                    "Setting process group of " + app.processName
15698                    + " to " + app.curSchedGroup);
15699            if (app.waitingToKill != null &&
15700                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15701                killUnneededProcessLocked(app, app.waitingToKill);
15702                success = false;
15703            } else {
15704                if (true) {
15705                    long oldId = Binder.clearCallingIdentity();
15706                    try {
15707                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15708                    } catch (Exception e) {
15709                        Slog.w(TAG, "Failed setting process group of " + app.pid
15710                                + " to " + app.curSchedGroup);
15711                        e.printStackTrace();
15712                    } finally {
15713                        Binder.restoreCallingIdentity(oldId);
15714                    }
15715                } else {
15716                    if (app.thread != null) {
15717                        try {
15718                            app.thread.setSchedulingGroup(app.curSchedGroup);
15719                        } catch (RemoteException e) {
15720                        }
15721                    }
15722                }
15723                Process.setSwappiness(app.pid,
15724                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15725            }
15726        }
15727        if (app.repForegroundActivities != app.foregroundActivities) {
15728            app.repForegroundActivities = app.foregroundActivities;
15729            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15730        }
15731        if (app.repProcState != app.curProcState) {
15732            app.repProcState = app.curProcState;
15733            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15734            if (app.thread != null) {
15735                try {
15736                    if (false) {
15737                        //RuntimeException h = new RuntimeException("here");
15738                        Slog.i(TAG, "Sending new process state " + app.repProcState
15739                                + " to " + app /*, h*/);
15740                    }
15741                    app.thread.setProcessState(app.repProcState);
15742                } catch (RemoteException e) {
15743                }
15744            }
15745        }
15746        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15747                app.setProcState)) {
15748            app.lastStateTime = now;
15749            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15750                    isSleeping(), now);
15751            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15752                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15753                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15754                    + (app.nextPssTime-now) + ": " + app);
15755        } else {
15756            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15757                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15758                requestPssLocked(app, app.setProcState);
15759                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15760                        isSleeping(), now);
15761            } else if (false && DEBUG_PSS) {
15762                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15763            }
15764        }
15765        if (app.setProcState != app.curProcState) {
15766            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15767                    "Proc state change of " + app.processName
15768                    + " to " + app.curProcState);
15769            app.setProcState = app.curProcState;
15770            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15771                app.notCachedSinceIdle = false;
15772            }
15773            if (!doingAll) {
15774                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15775            } else {
15776                app.procStateChanged = true;
15777            }
15778        }
15779
15780        if (changes != 0) {
15781            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15782            int i = mPendingProcessChanges.size()-1;
15783            ProcessChangeItem item = null;
15784            while (i >= 0) {
15785                item = mPendingProcessChanges.get(i);
15786                if (item.pid == app.pid) {
15787                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15788                    break;
15789                }
15790                i--;
15791            }
15792            if (i < 0) {
15793                // No existing item in pending changes; need a new one.
15794                final int NA = mAvailProcessChanges.size();
15795                if (NA > 0) {
15796                    item = mAvailProcessChanges.remove(NA-1);
15797                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15798                } else {
15799                    item = new ProcessChangeItem();
15800                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15801                }
15802                item.changes = 0;
15803                item.pid = app.pid;
15804                item.uid = app.info.uid;
15805                if (mPendingProcessChanges.size() == 0) {
15806                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15807                            "*** Enqueueing dispatch processes changed!");
15808                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15809                }
15810                mPendingProcessChanges.add(item);
15811            }
15812            item.changes |= changes;
15813            item.processState = app.repProcState;
15814            item.foregroundActivities = app.repForegroundActivities;
15815            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15816                    + Integer.toHexString(System.identityHashCode(item))
15817                    + " " + app.toShortString() + ": changes=" + item.changes
15818                    + " procState=" + item.processState
15819                    + " foreground=" + item.foregroundActivities
15820                    + " type=" + app.adjType + " source=" + app.adjSource
15821                    + " target=" + app.adjTarget);
15822        }
15823
15824        return success;
15825    }
15826
15827    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15828        if (proc.thread != null && proc.baseProcessTracker != null) {
15829            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15830        }
15831    }
15832
15833    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15834            ProcessRecord TOP_APP, boolean doingAll, long now) {
15835        if (app.thread == null) {
15836            return false;
15837        }
15838
15839        final boolean wasKeeping = app.keeping;
15840
15841        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15842
15843        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15844    }
15845
15846    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15847            boolean oomAdj) {
15848        if (isForeground != proc.foregroundServices) {
15849            proc.foregroundServices = isForeground;
15850            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15851                    proc.info.uid);
15852            if (isForeground) {
15853                if (curProcs == null) {
15854                    curProcs = new ArrayList<ProcessRecord>();
15855                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15856                }
15857                if (!curProcs.contains(proc)) {
15858                    curProcs.add(proc);
15859                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15860                            proc.info.packageName, proc.info.uid);
15861                }
15862            } else {
15863                if (curProcs != null) {
15864                    if (curProcs.remove(proc)) {
15865                        mBatteryStatsService.noteEvent(
15866                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15867                                proc.info.packageName, proc.info.uid);
15868                        if (curProcs.size() <= 0) {
15869                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15870                        }
15871                    }
15872                }
15873            }
15874            if (oomAdj) {
15875                updateOomAdjLocked();
15876            }
15877        }
15878    }
15879
15880    private final ActivityRecord resumedAppLocked() {
15881        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15882        String pkg;
15883        int uid;
15884        if (act != null && !act.sleeping) {
15885            pkg = act.packageName;
15886            uid = act.info.applicationInfo.uid;
15887        } else {
15888            pkg = null;
15889            uid = -1;
15890        }
15891        // Has the UID or resumed package name changed?
15892        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15893                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15894            if (mCurResumedPackage != null) {
15895                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15896                        mCurResumedPackage, mCurResumedUid);
15897            }
15898            mCurResumedPackage = pkg;
15899            mCurResumedUid = uid;
15900            if (mCurResumedPackage != null) {
15901                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15902                        mCurResumedPackage, mCurResumedUid);
15903            }
15904        }
15905        return act;
15906    }
15907
15908    final boolean updateOomAdjLocked(ProcessRecord app) {
15909        final ActivityRecord TOP_ACT = resumedAppLocked();
15910        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15911        final boolean wasCached = app.cached;
15912
15913        mAdjSeq++;
15914
15915        // This is the desired cached adjusment we want to tell it to use.
15916        // If our app is currently cached, we know it, and that is it.  Otherwise,
15917        // we don't know it yet, and it needs to now be cached we will then
15918        // need to do a complete oom adj.
15919        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15920                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15921        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15922                SystemClock.uptimeMillis());
15923        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15924            // Changed to/from cached state, so apps after it in the LRU
15925            // list may also be changed.
15926            updateOomAdjLocked();
15927        }
15928        return success;
15929    }
15930
15931    final void updateOomAdjLocked() {
15932        final ActivityRecord TOP_ACT = resumedAppLocked();
15933        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15934        final long now = SystemClock.uptimeMillis();
15935        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15936        final int N = mLruProcesses.size();
15937
15938        if (false) {
15939            RuntimeException e = new RuntimeException();
15940            e.fillInStackTrace();
15941            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15942        }
15943
15944        mAdjSeq++;
15945        mNewNumServiceProcs = 0;
15946        mNewNumAServiceProcs = 0;
15947
15948        final int emptyProcessLimit;
15949        final int cachedProcessLimit;
15950        if (mProcessLimit <= 0) {
15951            emptyProcessLimit = cachedProcessLimit = 0;
15952        } else if (mProcessLimit == 1) {
15953            emptyProcessLimit = 1;
15954            cachedProcessLimit = 0;
15955        } else {
15956            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15957            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15958        }
15959
15960        // Let's determine how many processes we have running vs.
15961        // how many slots we have for background processes; we may want
15962        // to put multiple processes in a slot of there are enough of
15963        // them.
15964        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15965                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15966        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15967        if (numEmptyProcs > cachedProcessLimit) {
15968            // If there are more empty processes than our limit on cached
15969            // processes, then use the cached process limit for the factor.
15970            // This ensures that the really old empty processes get pushed
15971            // down to the bottom, so if we are running low on memory we will
15972            // have a better chance at keeping around more cached processes
15973            // instead of a gazillion empty processes.
15974            numEmptyProcs = cachedProcessLimit;
15975        }
15976        int emptyFactor = numEmptyProcs/numSlots;
15977        if (emptyFactor < 1) emptyFactor = 1;
15978        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15979        if (cachedFactor < 1) cachedFactor = 1;
15980        int stepCached = 0;
15981        int stepEmpty = 0;
15982        int numCached = 0;
15983        int numEmpty = 0;
15984        int numTrimming = 0;
15985
15986        mNumNonCachedProcs = 0;
15987        mNumCachedHiddenProcs = 0;
15988
15989        // First update the OOM adjustment for each of the
15990        // application processes based on their current state.
15991        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15992        int nextCachedAdj = curCachedAdj+1;
15993        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15994        int nextEmptyAdj = curEmptyAdj+2;
15995        for (int i=N-1; i>=0; i--) {
15996            ProcessRecord app = mLruProcesses.get(i);
15997            if (!app.killedByAm && app.thread != null) {
15998                app.procStateChanged = false;
15999                final boolean wasKeeping = app.keeping;
16000                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16001
16002                // If we haven't yet assigned the final cached adj
16003                // to the process, do that now.
16004                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16005                    switch (app.curProcState) {
16006                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16007                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16008                            // This process is a cached process holding activities...
16009                            // assign it the next cached value for that type, and then
16010                            // step that cached level.
16011                            app.curRawAdj = curCachedAdj;
16012                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16013                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16014                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16015                                    + ")");
16016                            if (curCachedAdj != nextCachedAdj) {
16017                                stepCached++;
16018                                if (stepCached >= cachedFactor) {
16019                                    stepCached = 0;
16020                                    curCachedAdj = nextCachedAdj;
16021                                    nextCachedAdj += 2;
16022                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16023                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16024                                    }
16025                                }
16026                            }
16027                            break;
16028                        default:
16029                            // For everything else, assign next empty cached process
16030                            // level and bump that up.  Note that this means that
16031                            // long-running services that have dropped down to the
16032                            // cached level will be treated as empty (since their process
16033                            // state is still as a service), which is what we want.
16034                            app.curRawAdj = curEmptyAdj;
16035                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16036                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16037                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16038                                    + ")");
16039                            if (curEmptyAdj != nextEmptyAdj) {
16040                                stepEmpty++;
16041                                if (stepEmpty >= emptyFactor) {
16042                                    stepEmpty = 0;
16043                                    curEmptyAdj = nextEmptyAdj;
16044                                    nextEmptyAdj += 2;
16045                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16046                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16047                                    }
16048                                }
16049                            }
16050                            break;
16051                    }
16052                }
16053
16054                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16055
16056                // Count the number of process types.
16057                switch (app.curProcState) {
16058                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16059                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16060                        mNumCachedHiddenProcs++;
16061                        numCached++;
16062                        if (numCached > cachedProcessLimit) {
16063                            killUnneededProcessLocked(app, "cached #" + numCached);
16064                        }
16065                        break;
16066                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16067                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16068                                && app.lastActivityTime < oldTime) {
16069                            killUnneededProcessLocked(app, "empty for "
16070                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16071                                    / 1000) + "s");
16072                        } else {
16073                            numEmpty++;
16074                            if (numEmpty > emptyProcessLimit) {
16075                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16076                            }
16077                        }
16078                        break;
16079                    default:
16080                        mNumNonCachedProcs++;
16081                        break;
16082                }
16083
16084                if (app.isolated && app.services.size() <= 0) {
16085                    // If this is an isolated process, and there are no
16086                    // services running in it, then the process is no longer
16087                    // needed.  We agressively kill these because we can by
16088                    // definition not re-use the same process again, and it is
16089                    // good to avoid having whatever code was running in them
16090                    // left sitting around after no longer needed.
16091                    killUnneededProcessLocked(app, "isolated not needed");
16092                }
16093
16094                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16095                        && !app.killedByAm) {
16096                    numTrimming++;
16097                }
16098            }
16099        }
16100
16101        mNumServiceProcs = mNewNumServiceProcs;
16102
16103        // Now determine the memory trimming level of background processes.
16104        // Unfortunately we need to start at the back of the list to do this
16105        // properly.  We only do this if the number of background apps we
16106        // are managing to keep around is less than half the maximum we desire;
16107        // if we are keeping a good number around, we'll let them use whatever
16108        // memory they want.
16109        final int numCachedAndEmpty = numCached + numEmpty;
16110        int memFactor;
16111        if (numCached <= ProcessList.TRIM_CACHED_APPS
16112                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16113            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16114                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16115            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16116                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16117            } else {
16118                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16119            }
16120        } else {
16121            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16122        }
16123        // We always allow the memory level to go up (better).  We only allow it to go
16124        // down if we are in a state where that is allowed, *and* the total number of processes
16125        // has gone down since last time.
16126        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16127                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16128                + " last=" + mLastNumProcesses);
16129        if (memFactor > mLastMemoryLevel) {
16130            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16131                memFactor = mLastMemoryLevel;
16132                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16133            }
16134        }
16135        mLastMemoryLevel = memFactor;
16136        mLastNumProcesses = mLruProcesses.size();
16137        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16138        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16139        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16140            if (mLowRamStartTime == 0) {
16141                mLowRamStartTime = now;
16142            }
16143            int step = 0;
16144            int fgTrimLevel;
16145            switch (memFactor) {
16146                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16147                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16148                    break;
16149                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16150                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16151                    break;
16152                default:
16153                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16154                    break;
16155            }
16156            int factor = numTrimming/3;
16157            int minFactor = 2;
16158            if (mHomeProcess != null) minFactor++;
16159            if (mPreviousProcess != null) minFactor++;
16160            if (factor < minFactor) factor = minFactor;
16161            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16162            for (int i=N-1; i>=0; i--) {
16163                ProcessRecord app = mLruProcesses.get(i);
16164                if (allChanged || app.procStateChanged) {
16165                    setProcessTrackerState(app, trackerMemFactor, now);
16166                    app.procStateChanged = false;
16167                }
16168                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16169                        && !app.killedByAm) {
16170                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16171                        try {
16172                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16173                                    "Trimming memory of " + app.processName
16174                                    + " to " + curLevel);
16175                            app.thread.scheduleTrimMemory(curLevel);
16176                        } catch (RemoteException e) {
16177                        }
16178                        if (false) {
16179                            // For now we won't do this; our memory trimming seems
16180                            // to be good enough at this point that destroying
16181                            // activities causes more harm than good.
16182                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16183                                    && app != mHomeProcess && app != mPreviousProcess) {
16184                                // Need to do this on its own message because the stack may not
16185                                // be in a consistent state at this point.
16186                                // For these apps we will also finish their activities
16187                                // to help them free memory.
16188                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16189                            }
16190                        }
16191                    }
16192                    app.trimMemoryLevel = curLevel;
16193                    step++;
16194                    if (step >= factor) {
16195                        step = 0;
16196                        switch (curLevel) {
16197                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16198                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16199                                break;
16200                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16201                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16202                                break;
16203                        }
16204                    }
16205                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16206                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16207                            && app.thread != null) {
16208                        try {
16209                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16210                                    "Trimming memory of heavy-weight " + app.processName
16211                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16212                            app.thread.scheduleTrimMemory(
16213                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16214                        } catch (RemoteException e) {
16215                        }
16216                    }
16217                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16218                } else {
16219                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16220                            || app.systemNoUi) && app.pendingUiClean) {
16221                        // If this application is now in the background and it
16222                        // had done UI, then give it the special trim level to
16223                        // have it free UI resources.
16224                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16225                        if (app.trimMemoryLevel < level && app.thread != null) {
16226                            try {
16227                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16228                                        "Trimming memory of bg-ui " + app.processName
16229                                        + " to " + level);
16230                                app.thread.scheduleTrimMemory(level);
16231                            } catch (RemoteException e) {
16232                            }
16233                        }
16234                        app.pendingUiClean = false;
16235                    }
16236                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16237                        try {
16238                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16239                                    "Trimming memory of fg " + app.processName
16240                                    + " to " + fgTrimLevel);
16241                            app.thread.scheduleTrimMemory(fgTrimLevel);
16242                        } catch (RemoteException e) {
16243                        }
16244                    }
16245                    app.trimMemoryLevel = fgTrimLevel;
16246                }
16247            }
16248        } else {
16249            if (mLowRamStartTime != 0) {
16250                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16251                mLowRamStartTime = 0;
16252            }
16253            for (int i=N-1; i>=0; i--) {
16254                ProcessRecord app = mLruProcesses.get(i);
16255                if (allChanged || app.procStateChanged) {
16256                    setProcessTrackerState(app, trackerMemFactor, now);
16257                    app.procStateChanged = false;
16258                }
16259                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16260                        || app.systemNoUi) && app.pendingUiClean) {
16261                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16262                            && app.thread != null) {
16263                        try {
16264                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16265                                    "Trimming memory of ui hidden " + app.processName
16266                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16267                            app.thread.scheduleTrimMemory(
16268                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16269                        } catch (RemoteException e) {
16270                        }
16271                    }
16272                    app.pendingUiClean = false;
16273                }
16274                app.trimMemoryLevel = 0;
16275            }
16276        }
16277
16278        if (mAlwaysFinishActivities) {
16279            // Need to do this on its own message because the stack may not
16280            // be in a consistent state at this point.
16281            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16282        }
16283
16284        if (allChanged) {
16285            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16286        }
16287
16288        if (mProcessStats.shouldWriteNowLocked(now)) {
16289            mHandler.post(new Runnable() {
16290                @Override public void run() {
16291                    synchronized (ActivityManagerService.this) {
16292                        mProcessStats.writeStateAsyncLocked();
16293                    }
16294                }
16295            });
16296        }
16297
16298        if (DEBUG_OOM_ADJ) {
16299            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16300        }
16301    }
16302
16303    final void trimApplications() {
16304        synchronized (this) {
16305            int i;
16306
16307            // First remove any unused application processes whose package
16308            // has been removed.
16309            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16310                final ProcessRecord app = mRemovedProcesses.get(i);
16311                if (app.activities.size() == 0
16312                        && app.curReceiver == null && app.services.size() == 0) {
16313                    Slog.i(
16314                        TAG, "Exiting empty application process "
16315                        + app.processName + " ("
16316                        + (app.thread != null ? app.thread.asBinder() : null)
16317                        + ")\n");
16318                    if (app.pid > 0 && app.pid != MY_PID) {
16319                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16320                                app.processName, app.setAdj, "empty");
16321                        app.killedByAm = true;
16322                        Process.killProcessQuiet(app.pid);
16323                    } else {
16324                        try {
16325                            app.thread.scheduleExit();
16326                        } catch (Exception e) {
16327                            // Ignore exceptions.
16328                        }
16329                    }
16330                    cleanUpApplicationRecordLocked(app, false, true, -1);
16331                    mRemovedProcesses.remove(i);
16332
16333                    if (app.persistent) {
16334                        if (app.persistent) {
16335                            addAppLocked(app.info, false, null /* ABI override */);
16336                        }
16337                    }
16338                }
16339            }
16340
16341            // Now update the oom adj for all processes.
16342            updateOomAdjLocked();
16343        }
16344    }
16345
16346    /** This method sends the specified signal to each of the persistent apps */
16347    public void signalPersistentProcesses(int sig) throws RemoteException {
16348        if (sig != Process.SIGNAL_USR1) {
16349            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16350        }
16351
16352        synchronized (this) {
16353            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16354                    != PackageManager.PERMISSION_GRANTED) {
16355                throw new SecurityException("Requires permission "
16356                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16357            }
16358
16359            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16360                ProcessRecord r = mLruProcesses.get(i);
16361                if (r.thread != null && r.persistent) {
16362                    Process.sendSignal(r.pid, sig);
16363                }
16364            }
16365        }
16366    }
16367
16368    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16369        if (proc == null || proc == mProfileProc) {
16370            proc = mProfileProc;
16371            path = mProfileFile;
16372            profileType = mProfileType;
16373            clearProfilerLocked();
16374        }
16375        if (proc == null) {
16376            return;
16377        }
16378        try {
16379            proc.thread.profilerControl(false, path, null, profileType);
16380        } catch (RemoteException e) {
16381            throw new IllegalStateException("Process disappeared");
16382        }
16383    }
16384
16385    private void clearProfilerLocked() {
16386        if (mProfileFd != null) {
16387            try {
16388                mProfileFd.close();
16389            } catch (IOException e) {
16390            }
16391        }
16392        mProfileApp = null;
16393        mProfileProc = null;
16394        mProfileFile = null;
16395        mProfileType = 0;
16396        mAutoStopProfiler = false;
16397    }
16398
16399    public boolean profileControl(String process, int userId, boolean start,
16400            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16401
16402        try {
16403            synchronized (this) {
16404                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16405                // its own permission.
16406                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16407                        != PackageManager.PERMISSION_GRANTED) {
16408                    throw new SecurityException("Requires permission "
16409                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16410                }
16411
16412                if (start && fd == null) {
16413                    throw new IllegalArgumentException("null fd");
16414                }
16415
16416                ProcessRecord proc = null;
16417                if (process != null) {
16418                    proc = findProcessLocked(process, userId, "profileControl");
16419                }
16420
16421                if (start && (proc == null || proc.thread == null)) {
16422                    throw new IllegalArgumentException("Unknown process: " + process);
16423                }
16424
16425                if (start) {
16426                    stopProfilerLocked(null, null, 0);
16427                    setProfileApp(proc.info, proc.processName, path, fd, false);
16428                    mProfileProc = proc;
16429                    mProfileType = profileType;
16430                    try {
16431                        fd = fd.dup();
16432                    } catch (IOException e) {
16433                        fd = null;
16434                    }
16435                    proc.thread.profilerControl(start, path, fd, profileType);
16436                    fd = null;
16437                    mProfileFd = null;
16438                } else {
16439                    stopProfilerLocked(proc, path, profileType);
16440                    if (fd != null) {
16441                        try {
16442                            fd.close();
16443                        } catch (IOException e) {
16444                        }
16445                    }
16446                }
16447
16448                return true;
16449            }
16450        } catch (RemoteException e) {
16451            throw new IllegalStateException("Process disappeared");
16452        } finally {
16453            if (fd != null) {
16454                try {
16455                    fd.close();
16456                } catch (IOException e) {
16457                }
16458            }
16459        }
16460    }
16461
16462    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16463        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16464                userId, true, true, callName, null);
16465        ProcessRecord proc = null;
16466        try {
16467            int pid = Integer.parseInt(process);
16468            synchronized (mPidsSelfLocked) {
16469                proc = mPidsSelfLocked.get(pid);
16470            }
16471        } catch (NumberFormatException e) {
16472        }
16473
16474        if (proc == null) {
16475            ArrayMap<String, SparseArray<ProcessRecord>> all
16476                    = mProcessNames.getMap();
16477            SparseArray<ProcessRecord> procs = all.get(process);
16478            if (procs != null && procs.size() > 0) {
16479                proc = procs.valueAt(0);
16480                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16481                    for (int i=1; i<procs.size(); i++) {
16482                        ProcessRecord thisProc = procs.valueAt(i);
16483                        if (thisProc.userId == userId) {
16484                            proc = thisProc;
16485                            break;
16486                        }
16487                    }
16488                }
16489            }
16490        }
16491
16492        return proc;
16493    }
16494
16495    public boolean dumpHeap(String process, int userId, boolean managed,
16496            String path, ParcelFileDescriptor fd) throws RemoteException {
16497
16498        try {
16499            synchronized (this) {
16500                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16501                // its own permission (same as profileControl).
16502                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16503                        != PackageManager.PERMISSION_GRANTED) {
16504                    throw new SecurityException("Requires permission "
16505                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16506                }
16507
16508                if (fd == null) {
16509                    throw new IllegalArgumentException("null fd");
16510                }
16511
16512                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16513                if (proc == null || proc.thread == null) {
16514                    throw new IllegalArgumentException("Unknown process: " + process);
16515                }
16516
16517                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16518                if (!isDebuggable) {
16519                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16520                        throw new SecurityException("Process not debuggable: " + proc);
16521                    }
16522                }
16523
16524                proc.thread.dumpHeap(managed, path, fd);
16525                fd = null;
16526                return true;
16527            }
16528        } catch (RemoteException e) {
16529            throw new IllegalStateException("Process disappeared");
16530        } finally {
16531            if (fd != null) {
16532                try {
16533                    fd.close();
16534                } catch (IOException e) {
16535                }
16536            }
16537        }
16538    }
16539
16540    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16541    public void monitor() {
16542        synchronized (this) { }
16543    }
16544
16545    void onCoreSettingsChange(Bundle settings) {
16546        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16547            ProcessRecord processRecord = mLruProcesses.get(i);
16548            try {
16549                if (processRecord.thread != null) {
16550                    processRecord.thread.setCoreSettings(settings);
16551                }
16552            } catch (RemoteException re) {
16553                /* ignore */
16554            }
16555        }
16556    }
16557
16558    // Multi-user methods
16559
16560    /**
16561     * Start user, if its not already running, but don't bring it to foreground.
16562     */
16563    @Override
16564    public boolean startUserInBackground(final int userId) {
16565        return startUser(userId, /* foreground */ false);
16566    }
16567
16568    /**
16569     * Refreshes the list of users related to the current user when either a
16570     * user switch happens or when a new related user is started in the
16571     * background.
16572     */
16573    private void updateCurrentProfileIdsLocked() {
16574        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16575                mCurrentUserId, false /* enabledOnly */);
16576        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16577        for (int i = 0; i < currentProfileIds.length; i++) {
16578            currentProfileIds[i] = profiles.get(i).id;
16579        }
16580        mCurrentProfileIds = currentProfileIds;
16581    }
16582
16583    private Set getProfileIdsLocked(int userId) {
16584        Set userIds = new HashSet<Integer>();
16585        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16586                userId, false /* enabledOnly */);
16587        for (UserInfo user : profiles) {
16588            userIds.add(Integer.valueOf(user.id));
16589        }
16590        return userIds;
16591    }
16592
16593    @Override
16594    public boolean switchUser(final int userId) {
16595        return startUser(userId, /* foregound */ true);
16596    }
16597
16598    private boolean startUser(final int userId, boolean foreground) {
16599        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16600                != PackageManager.PERMISSION_GRANTED) {
16601            String msg = "Permission Denial: switchUser() from pid="
16602                    + Binder.getCallingPid()
16603                    + ", uid=" + Binder.getCallingUid()
16604                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16605            Slog.w(TAG, msg);
16606            throw new SecurityException(msg);
16607        }
16608
16609        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16610
16611        final long ident = Binder.clearCallingIdentity();
16612        try {
16613            synchronized (this) {
16614                final int oldUserId = mCurrentUserId;
16615                if (oldUserId == userId) {
16616                    return true;
16617                }
16618
16619                mStackSupervisor.setLockTaskModeLocked(null);
16620
16621                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16622                if (userInfo == null) {
16623                    Slog.w(TAG, "No user info for user #" + userId);
16624                    return false;
16625                }
16626
16627                if (foreground) {
16628                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16629                            R.anim.screen_user_enter);
16630                }
16631
16632                boolean needStart = false;
16633
16634                // If the user we are switching to is not currently started, then
16635                // we need to start it now.
16636                if (mStartedUsers.get(userId) == null) {
16637                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16638                    updateStartedUserArrayLocked();
16639                    needStart = true;
16640                }
16641
16642                final Integer userIdInt = Integer.valueOf(userId);
16643                mUserLru.remove(userIdInt);
16644                mUserLru.add(userIdInt);
16645
16646                if (foreground) {
16647                    mCurrentUserId = userId;
16648                    updateCurrentProfileIdsLocked();
16649                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16650                    // Once the internal notion of the active user has switched, we lock the device
16651                    // with the option to show the user switcher on the keyguard.
16652                    mWindowManager.lockNow(null);
16653                } else {
16654                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16655                    updateCurrentProfileIdsLocked();
16656                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16657                    mUserLru.remove(currentUserIdInt);
16658                    mUserLru.add(currentUserIdInt);
16659                }
16660
16661                final UserStartedState uss = mStartedUsers.get(userId);
16662
16663                // Make sure user is in the started state.  If it is currently
16664                // stopping, we need to knock that off.
16665                if (uss.mState == UserStartedState.STATE_STOPPING) {
16666                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16667                    // so we can just fairly silently bring the user back from
16668                    // the almost-dead.
16669                    uss.mState = UserStartedState.STATE_RUNNING;
16670                    updateStartedUserArrayLocked();
16671                    needStart = true;
16672                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16673                    // This means ACTION_SHUTDOWN has been sent, so we will
16674                    // need to treat this as a new boot of the user.
16675                    uss.mState = UserStartedState.STATE_BOOTING;
16676                    updateStartedUserArrayLocked();
16677                    needStart = true;
16678                }
16679
16680                if (uss.mState == UserStartedState.STATE_BOOTING) {
16681                    // Booting up a new user, need to tell system services about it.
16682                    // Note that this is on the same handler as scheduling of broadcasts,
16683                    // which is important because it needs to go first.
16684                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16685                }
16686
16687                if (foreground) {
16688                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16689                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16690                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16691                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16692                            oldUserId, userId, uss));
16693                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16694                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16695                }
16696
16697                if (needStart) {
16698                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16699                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16700                            | Intent.FLAG_RECEIVER_FOREGROUND);
16701                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16702                    broadcastIntentLocked(null, null, intent,
16703                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16704                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16705                }
16706
16707                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16708                    if (userId != UserHandle.USER_OWNER) {
16709                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16710                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16711                        broadcastIntentLocked(null, null, intent, null,
16712                                new IIntentReceiver.Stub() {
16713                                    public void performReceive(Intent intent, int resultCode,
16714                                            String data, Bundle extras, boolean ordered,
16715                                            boolean sticky, int sendingUser) {
16716                                        userInitialized(uss, userId);
16717                                    }
16718                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16719                                true, false, MY_PID, Process.SYSTEM_UID,
16720                                userId);
16721                        uss.initializing = true;
16722                    } else {
16723                        getUserManagerLocked().makeInitialized(userInfo.id);
16724                    }
16725                }
16726
16727                if (foreground) {
16728                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16729                    if (homeInFront) {
16730                        startHomeActivityLocked(userId);
16731                    } else {
16732                        mStackSupervisor.resumeTopActivitiesLocked();
16733                    }
16734                    EventLogTags.writeAmSwitchUser(userId);
16735                    getUserManagerLocked().userForeground(userId);
16736                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16737                } else {
16738                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16739                }
16740
16741                if (needStart) {
16742                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16743                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16744                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16745                    broadcastIntentLocked(null, null, intent,
16746                            null, new IIntentReceiver.Stub() {
16747                                @Override
16748                                public void performReceive(Intent intent, int resultCode, String data,
16749                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16750                                        throws RemoteException {
16751                                }
16752                            }, 0, null, null,
16753                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16754                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16755                }
16756            }
16757        } finally {
16758            Binder.restoreCallingIdentity(ident);
16759        }
16760
16761        return true;
16762    }
16763
16764    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16765        long ident = Binder.clearCallingIdentity();
16766        try {
16767            Intent intent;
16768            if (oldUserId >= 0) {
16769                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16770                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16771                        | Intent.FLAG_RECEIVER_FOREGROUND);
16772                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16773                broadcastIntentLocked(null, null, intent,
16774                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16775                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16776            }
16777            if (newUserId >= 0) {
16778                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16779                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16780                        | Intent.FLAG_RECEIVER_FOREGROUND);
16781                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16782                broadcastIntentLocked(null, null, intent,
16783                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16784                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16785                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16786                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16787                        | Intent.FLAG_RECEIVER_FOREGROUND);
16788                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16789                broadcastIntentLocked(null, null, intent,
16790                        null, null, 0, null, null,
16791                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16792                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16793            }
16794        } finally {
16795            Binder.restoreCallingIdentity(ident);
16796        }
16797    }
16798
16799    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16800            final int newUserId) {
16801        final int N = mUserSwitchObservers.beginBroadcast();
16802        if (N > 0) {
16803            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16804                int mCount = 0;
16805                @Override
16806                public void sendResult(Bundle data) throws RemoteException {
16807                    synchronized (ActivityManagerService.this) {
16808                        if (mCurUserSwitchCallback == this) {
16809                            mCount++;
16810                            if (mCount == N) {
16811                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16812                            }
16813                        }
16814                    }
16815                }
16816            };
16817            synchronized (this) {
16818                uss.switching = true;
16819                mCurUserSwitchCallback = callback;
16820            }
16821            for (int i=0; i<N; i++) {
16822                try {
16823                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16824                            newUserId, callback);
16825                } catch (RemoteException e) {
16826                }
16827            }
16828        } else {
16829            synchronized (this) {
16830                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16831            }
16832        }
16833        mUserSwitchObservers.finishBroadcast();
16834    }
16835
16836    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16837        synchronized (this) {
16838            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16839            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16840        }
16841    }
16842
16843    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16844        mCurUserSwitchCallback = null;
16845        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16846        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16847                oldUserId, newUserId, uss));
16848    }
16849
16850    void userInitialized(UserStartedState uss, int newUserId) {
16851        completeSwitchAndInitalize(uss, newUserId, true, false);
16852    }
16853
16854    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16855        completeSwitchAndInitalize(uss, newUserId, false, true);
16856    }
16857
16858    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16859            boolean clearInitializing, boolean clearSwitching) {
16860        boolean unfrozen = false;
16861        synchronized (this) {
16862            if (clearInitializing) {
16863                uss.initializing = false;
16864                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16865            }
16866            if (clearSwitching) {
16867                uss.switching = false;
16868            }
16869            if (!uss.switching && !uss.initializing) {
16870                mWindowManager.stopFreezingScreen();
16871                unfrozen = true;
16872            }
16873        }
16874        if (unfrozen) {
16875            final int N = mUserSwitchObservers.beginBroadcast();
16876            for (int i=0; i<N; i++) {
16877                try {
16878                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16879                } catch (RemoteException e) {
16880                }
16881            }
16882            mUserSwitchObservers.finishBroadcast();
16883        }
16884    }
16885
16886    void scheduleStartProfilesLocked() {
16887        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16888            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16889                    DateUtils.SECOND_IN_MILLIS);
16890        }
16891    }
16892
16893    void startProfilesLocked() {
16894        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16895        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16896                mCurrentUserId, false /* enabledOnly */);
16897        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16898        for (UserInfo user : profiles) {
16899            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16900                    && user.id != mCurrentUserId) {
16901                toStart.add(user);
16902            }
16903        }
16904        final int n = toStart.size();
16905        int i = 0;
16906        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16907            startUserInBackground(toStart.get(i).id);
16908        }
16909        if (i < n) {
16910            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16911        }
16912    }
16913
16914    void finishUserBoot(UserStartedState uss) {
16915        synchronized (this) {
16916            if (uss.mState == UserStartedState.STATE_BOOTING
16917                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16918                uss.mState = UserStartedState.STATE_RUNNING;
16919                final int userId = uss.mHandle.getIdentifier();
16920                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16921                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16922                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16923                broadcastIntentLocked(null, null, intent,
16924                        null, null, 0, null, null,
16925                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16926                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16927            }
16928        }
16929    }
16930
16931    void finishUserSwitch(UserStartedState uss) {
16932        synchronized (this) {
16933            finishUserBoot(uss);
16934
16935            startProfilesLocked();
16936
16937            int num = mUserLru.size();
16938            int i = 0;
16939            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16940                Integer oldUserId = mUserLru.get(i);
16941                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16942                if (oldUss == null) {
16943                    // Shouldn't happen, but be sane if it does.
16944                    mUserLru.remove(i);
16945                    num--;
16946                    continue;
16947                }
16948                if (oldUss.mState == UserStartedState.STATE_STOPPING
16949                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16950                    // This user is already stopping, doesn't count.
16951                    num--;
16952                    i++;
16953                    continue;
16954                }
16955                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16956                    // Owner and current can't be stopped, but count as running.
16957                    i++;
16958                    continue;
16959                }
16960                // This is a user to be stopped.
16961                stopUserLocked(oldUserId, null);
16962                num--;
16963                i++;
16964            }
16965        }
16966    }
16967
16968    @Override
16969    public int stopUser(final int userId, final IStopUserCallback callback) {
16970        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16971                != PackageManager.PERMISSION_GRANTED) {
16972            String msg = "Permission Denial: switchUser() from pid="
16973                    + Binder.getCallingPid()
16974                    + ", uid=" + Binder.getCallingUid()
16975                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16976            Slog.w(TAG, msg);
16977            throw new SecurityException(msg);
16978        }
16979        if (userId <= 0) {
16980            throw new IllegalArgumentException("Can't stop primary user " + userId);
16981        }
16982        synchronized (this) {
16983            return stopUserLocked(userId, callback);
16984        }
16985    }
16986
16987    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16988        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16989        if (mCurrentUserId == userId) {
16990            return ActivityManager.USER_OP_IS_CURRENT;
16991        }
16992
16993        final UserStartedState uss = mStartedUsers.get(userId);
16994        if (uss == null) {
16995            // User is not started, nothing to do...  but we do need to
16996            // callback if requested.
16997            if (callback != null) {
16998                mHandler.post(new Runnable() {
16999                    @Override
17000                    public void run() {
17001                        try {
17002                            callback.userStopped(userId);
17003                        } catch (RemoteException e) {
17004                        }
17005                    }
17006                });
17007            }
17008            return ActivityManager.USER_OP_SUCCESS;
17009        }
17010
17011        if (callback != null) {
17012            uss.mStopCallbacks.add(callback);
17013        }
17014
17015        if (uss.mState != UserStartedState.STATE_STOPPING
17016                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17017            uss.mState = UserStartedState.STATE_STOPPING;
17018            updateStartedUserArrayLocked();
17019
17020            long ident = Binder.clearCallingIdentity();
17021            try {
17022                // We are going to broadcast ACTION_USER_STOPPING and then
17023                // once that is done send a final ACTION_SHUTDOWN and then
17024                // stop the user.
17025                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17026                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17027                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17028                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17029                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17030                // This is the result receiver for the final shutdown broadcast.
17031                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17032                    @Override
17033                    public void performReceive(Intent intent, int resultCode, String data,
17034                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17035                        finishUserStop(uss);
17036                    }
17037                };
17038                // This is the result receiver for the initial stopping broadcast.
17039                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17040                    @Override
17041                    public void performReceive(Intent intent, int resultCode, String data,
17042                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17043                        // On to the next.
17044                        synchronized (ActivityManagerService.this) {
17045                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17046                                // Whoops, we are being started back up.  Abort, abort!
17047                                return;
17048                            }
17049                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17050                        }
17051                        mSystemServiceManager.stopUser(userId);
17052                        broadcastIntentLocked(null, null, shutdownIntent,
17053                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17054                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17055                    }
17056                };
17057                // Kick things off.
17058                broadcastIntentLocked(null, null, stoppingIntent,
17059                        null, stoppingReceiver, 0, null, null,
17060                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17061                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17062            } finally {
17063                Binder.restoreCallingIdentity(ident);
17064            }
17065        }
17066
17067        return ActivityManager.USER_OP_SUCCESS;
17068    }
17069
17070    void finishUserStop(UserStartedState uss) {
17071        final int userId = uss.mHandle.getIdentifier();
17072        boolean stopped;
17073        ArrayList<IStopUserCallback> callbacks;
17074        synchronized (this) {
17075            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17076            if (mStartedUsers.get(userId) != uss) {
17077                stopped = false;
17078            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17079                stopped = false;
17080            } else {
17081                stopped = true;
17082                // User can no longer run.
17083                mStartedUsers.remove(userId);
17084                mUserLru.remove(Integer.valueOf(userId));
17085                updateStartedUserArrayLocked();
17086
17087                // Clean up all state and processes associated with the user.
17088                // Kill all the processes for the user.
17089                forceStopUserLocked(userId, "finish user");
17090            }
17091        }
17092
17093        for (int i=0; i<callbacks.size(); i++) {
17094            try {
17095                if (stopped) callbacks.get(i).userStopped(userId);
17096                else callbacks.get(i).userStopAborted(userId);
17097            } catch (RemoteException e) {
17098            }
17099        }
17100
17101        if (stopped) {
17102            mSystemServiceManager.cleanupUser(userId);
17103            synchronized (this) {
17104                mStackSupervisor.removeUserLocked(userId);
17105            }
17106        }
17107    }
17108
17109    @Override
17110    public UserInfo getCurrentUser() {
17111        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17112                != PackageManager.PERMISSION_GRANTED) && (
17113                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17114                != PackageManager.PERMISSION_GRANTED)) {
17115            String msg = "Permission Denial: getCurrentUser() from pid="
17116                    + Binder.getCallingPid()
17117                    + ", uid=" + Binder.getCallingUid()
17118                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17119            Slog.w(TAG, msg);
17120            throw new SecurityException(msg);
17121        }
17122        synchronized (this) {
17123            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17124        }
17125    }
17126
17127    int getCurrentUserIdLocked() {
17128        return mCurrentUserId;
17129    }
17130
17131    @Override
17132    public boolean isUserRunning(int userId, boolean orStopped) {
17133        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17134                != PackageManager.PERMISSION_GRANTED) {
17135            String msg = "Permission Denial: isUserRunning() from pid="
17136                    + Binder.getCallingPid()
17137                    + ", uid=" + Binder.getCallingUid()
17138                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17139            Slog.w(TAG, msg);
17140            throw new SecurityException(msg);
17141        }
17142        synchronized (this) {
17143            return isUserRunningLocked(userId, orStopped);
17144        }
17145    }
17146
17147    boolean isUserRunningLocked(int userId, boolean orStopped) {
17148        UserStartedState state = mStartedUsers.get(userId);
17149        if (state == null) {
17150            return false;
17151        }
17152        if (orStopped) {
17153            return true;
17154        }
17155        return state.mState != UserStartedState.STATE_STOPPING
17156                && state.mState != UserStartedState.STATE_SHUTDOWN;
17157    }
17158
17159    @Override
17160    public int[] getRunningUserIds() {
17161        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17162                != PackageManager.PERMISSION_GRANTED) {
17163            String msg = "Permission Denial: isUserRunning() from pid="
17164                    + Binder.getCallingPid()
17165                    + ", uid=" + Binder.getCallingUid()
17166                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17167            Slog.w(TAG, msg);
17168            throw new SecurityException(msg);
17169        }
17170        synchronized (this) {
17171            return mStartedUserArray;
17172        }
17173    }
17174
17175    private void updateStartedUserArrayLocked() {
17176        int num = 0;
17177        for (int i=0; i<mStartedUsers.size();  i++) {
17178            UserStartedState uss = mStartedUsers.valueAt(i);
17179            // This list does not include stopping users.
17180            if (uss.mState != UserStartedState.STATE_STOPPING
17181                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17182                num++;
17183            }
17184        }
17185        mStartedUserArray = new int[num];
17186        num = 0;
17187        for (int i=0; i<mStartedUsers.size();  i++) {
17188            UserStartedState uss = mStartedUsers.valueAt(i);
17189            if (uss.mState != UserStartedState.STATE_STOPPING
17190                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17191                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17192                num++;
17193            }
17194        }
17195    }
17196
17197    @Override
17198    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17199        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17200                != PackageManager.PERMISSION_GRANTED) {
17201            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17202                    + Binder.getCallingPid()
17203                    + ", uid=" + Binder.getCallingUid()
17204                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17205            Slog.w(TAG, msg);
17206            throw new SecurityException(msg);
17207        }
17208
17209        mUserSwitchObservers.register(observer);
17210    }
17211
17212    @Override
17213    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17214        mUserSwitchObservers.unregister(observer);
17215    }
17216
17217    private boolean userExists(int userId) {
17218        if (userId == 0) {
17219            return true;
17220        }
17221        UserManagerService ums = getUserManagerLocked();
17222        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17223    }
17224
17225    int[] getUsersLocked() {
17226        UserManagerService ums = getUserManagerLocked();
17227        return ums != null ? ums.getUserIds() : new int[] { 0 };
17228    }
17229
17230    UserManagerService getUserManagerLocked() {
17231        if (mUserManager == null) {
17232            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17233            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17234        }
17235        return mUserManager;
17236    }
17237
17238    private int applyUserId(int uid, int userId) {
17239        return UserHandle.getUid(userId, uid);
17240    }
17241
17242    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17243        if (info == null) return null;
17244        ApplicationInfo newInfo = new ApplicationInfo(info);
17245        newInfo.uid = applyUserId(info.uid, userId);
17246        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17247                + info.packageName;
17248        return newInfo;
17249    }
17250
17251    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17252        if (aInfo == null
17253                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17254            return aInfo;
17255        }
17256
17257        ActivityInfo info = new ActivityInfo(aInfo);
17258        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17259        return info;
17260    }
17261
17262    private final class LocalService extends ActivityManagerInternal {
17263        @Override
17264        public void goingToSleep() {
17265            ActivityManagerService.this.goingToSleep();
17266        }
17267
17268        @Override
17269        public void wakingUp() {
17270            ActivityManagerService.this.wakingUp();
17271        }
17272    }
17273
17274    /**
17275     * An implementation of IAppTask, that allows an app to manage its own tasks via
17276     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17277     * only the process that calls getAppTasks() can call the AppTask methods.
17278     */
17279    class AppTaskImpl extends IAppTask.Stub {
17280        private int mTaskId;
17281        private int mCallingUid;
17282
17283        public AppTaskImpl(int taskId, int callingUid) {
17284            mTaskId = taskId;
17285            mCallingUid = callingUid;
17286        }
17287
17288        @Override
17289        public void finishAndRemoveTask() {
17290            // Ensure that we are called from the same process that created this AppTask
17291            if (mCallingUid != Binder.getCallingUid()) {
17292                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17293                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17294                return;
17295            }
17296
17297            synchronized (ActivityManagerService.this) {
17298                long origId = Binder.clearCallingIdentity();
17299                try {
17300                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17301                    if (tr != null) {
17302                        // Only kill the process if we are not a new document
17303                        int flags = tr.getBaseIntent().getFlags();
17304                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17305                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17306                        removeTaskByIdLocked(mTaskId,
17307                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17308                    }
17309                } finally {
17310                    Binder.restoreCallingIdentity(origId);
17311                }
17312            }
17313        }
17314
17315        @Override
17316        public ActivityManager.RecentTaskInfo getTaskInfo() {
17317            // Ensure that we are called from the same process that created this AppTask
17318            if (mCallingUid != Binder.getCallingUid()) {
17319                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17320                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17321                return null;
17322            }
17323
17324            synchronized (ActivityManagerService.this) {
17325                long origId = Binder.clearCallingIdentity();
17326                try {
17327                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17328                    if (tr != null) {
17329                        return createRecentTaskInfoFromTaskRecord(tr);
17330                    }
17331                } finally {
17332                    Binder.restoreCallingIdentity(origId);
17333                }
17334                return null;
17335            }
17336        }
17337    }
17338}
17339