ActivityManagerService.java revision 9740e468bc895cbc08c71aecc35fc56c3faafa06
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
274
275    // Amount of time after a call to stopAppSwitches() during which we will
276    // prevent further untrusted switches from happening.
277    static final long APP_SWITCH_DELAY_TIME = 5*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real.
281    static final int PROC_START_TIMEOUT = 10*1000;
282
283    // How long we wait for a launched process to attach to the activity manager
284    // before we decide it's never going to come up for real, when the process was
285    // started with a wrapper for instrumentation (such as Valgrind) because it
286    // could take much longer than usual.
287    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
288
289    // How long to wait after going idle before forcing apps to GC.
290    static final int GC_TIMEOUT = 5*1000;
291
292    // The minimum amount of time between successive GC requests for a process.
293    static final int GC_MIN_INTERVAL = 60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process.
296    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process
299    // when the request is due to the memory state being lowered.
300    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
301
302    // The rate at which we check for apps using excessive power -- 15 mins.
303    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on wake locks to start killing things.
307    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // The minimum sample duration we will allow before deciding we have
310    // enough data on CPU usage to start killing things.
311    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
312
313    // How long we allow a receiver to run before giving up on it.
314    static final int BROADCAST_FG_TIMEOUT = 10*1000;
315    static final int BROADCAST_BG_TIMEOUT = 60*1000;
316
317    // How long we wait until we timeout on key dispatching.
318    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
319
320    // How long we wait until we timeout on key dispatching during instrumentation.
321    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
322
323    // Amount of time we wait for observers to handle a user switch before
324    // giving up on them and unfreezing the screen.
325    static final int USER_SWITCH_TIMEOUT = 2*1000;
326
327    // Maximum number of users we allow to be running at a time.
328    static final int MAX_RUNNING_USERS = 3;
329
330    // How long to wait in getAssistContextExtras for the activity and foreground services
331    // to respond with the result.
332    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
333
334    // Maximum number of persisted Uri grants a package is allowed
335    static final int MAX_PERSISTED_URI_GRANTS = 128;
336
337    static final int MY_PID = Process.myPid();
338
339    static final String[] EMPTY_STRING_ARRAY = new String[0];
340
341    // How many bytes to write into the dropbox log before truncating
342    static final int DROPBOX_MAX_SIZE = 256 * 1024;
343
344    /** All system services */
345    SystemServiceManager mSystemServiceManager;
346
347    /** Run all ActivityStacks through this */
348    ActivityStackSupervisor mStackSupervisor;
349
350    public IntentFirewall mIntentFirewall;
351
352    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
353    // default actuion automatically.  Important for devices without direct input
354    // devices.
355    private boolean mShowDialogs = true;
356
357    /**
358     * Description of a request to start a new activity, which has been held
359     * due to app switches being disabled.
360     */
361    static class PendingActivityLaunch {
362        final ActivityRecord r;
363        final ActivityRecord sourceRecord;
364        final int startFlags;
365        final ActivityStack stack;
366
367        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
368                int _startFlags, ActivityStack _stack) {
369            r = _r;
370            sourceRecord = _sourceRecord;
371            startFlags = _startFlags;
372            stack = _stack;
373        }
374    }
375
376    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
377            = new ArrayList<PendingActivityLaunch>();
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414
415    public class PendingAssistExtras extends Binder implements Runnable {
416        public final ActivityRecord activity;
417        public boolean haveResult = false;
418        public Bundle result = null;
419        public PendingAssistExtras(ActivityRecord _activity) {
420            activity = _activity;
421        }
422        @Override
423        public void run() {
424            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
425            synchronized (this) {
426                haveResult = true;
427                notifyAll();
428            }
429        }
430    }
431
432    final ArrayList<PendingAssistExtras> mPendingAssistExtras
433            = new ArrayList<PendingAssistExtras>();
434
435    /**
436     * Process management.
437     */
438    final ProcessList mProcessList = new ProcessList();
439
440    /**
441     * All of the applications we currently have running organized by name.
442     * The keys are strings of the application package name (as
443     * returned by the package manager), and the keys are ApplicationRecord
444     * objects.
445     */
446    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
447
448    /**
449     * Tracking long-term execution of processes to look for abuse and other
450     * bad app behavior.
451     */
452    final ProcessStatsService mProcessStats;
453
454    /**
455     * The currently running isolated processes.
456     */
457    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
458
459    /**
460     * Counter for assigning isolated process uids, to avoid frequently reusing the
461     * same ones.
462     */
463    int mNextIsolatedProcessUid = 0;
464
465    /**
466     * The currently running heavy-weight process, if any.
467     */
468    ProcessRecord mHeavyWeightProcess = null;
469
470    /**
471     * The last time that various processes have crashed.
472     */
473    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
474
475    /**
476     * Information about a process that is currently marked as bad.
477     */
478    static final class BadProcessInfo {
479        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
480            this.time = time;
481            this.shortMsg = shortMsg;
482            this.longMsg = longMsg;
483            this.stack = stack;
484        }
485
486        final long time;
487        final String shortMsg;
488        final String longMsg;
489        final String stack;
490    }
491
492    /**
493     * Set of applications that we consider to be bad, and will reject
494     * incoming broadcasts from (which the user has no control over).
495     * Processes are added to this set when they have crashed twice within
496     * a minimum amount of time; they are removed from it when they are
497     * later restarted (hopefully due to some user action).  The value is the
498     * time it was added to the list.
499     */
500    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
501
502    /**
503     * All of the processes we currently have running organized by pid.
504     * The keys are the pid running the application.
505     *
506     * <p>NOTE: This object is protected by its own lock, NOT the global
507     * activity manager lock!
508     */
509    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
510
511    /**
512     * All of the processes that have been forced to be foreground.  The key
513     * is the pid of the caller who requested it (we hold a death
514     * link on it).
515     */
516    abstract class ForegroundToken implements IBinder.DeathRecipient {
517        int pid;
518        IBinder token;
519    }
520    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
521
522    /**
523     * List of records for processes that someone had tried to start before the
524     * system was ready.  We don't start them at that point, but ensure they
525     * are started by the time booting is complete.
526     */
527    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
528
529    /**
530     * List of persistent applications that are in the process
531     * of being started.
532     */
533    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
534
535    /**
536     * Processes that are being forcibly torn down.
537     */
538    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
539
540    /**
541     * List of running applications, sorted by recent usage.
542     * The first entry in the list is the least recently used.
543     */
544    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
545
546    /**
547     * Where in mLruProcesses that the processes hosting activities start.
548     */
549    int mLruProcessActivityStart = 0;
550
551    /**
552     * Where in mLruProcesses that the processes hosting services start.
553     * This is after (lower index) than mLruProcessesActivityStart.
554     */
555    int mLruProcessServiceStart = 0;
556
557    /**
558     * List of processes that should gc as soon as things are idle.
559     */
560    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
561
562    /**
563     * Processes we want to collect PSS data from.
564     */
565    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Last time we requested PSS data of all processes.
569     */
570    long mLastFullPssTime = SystemClock.uptimeMillis();
571
572    /**
573     * This is the process holding what we currently consider to be
574     * the "home" activity.
575     */
576    ProcessRecord mHomeProcess;
577
578    /**
579     * This is the process holding the activity the user last visited that
580     * is in a different process from the one they are currently in.
581     */
582    ProcessRecord mPreviousProcess;
583
584    /**
585     * The time at which the previous process was last visible.
586     */
587    long mPreviousProcessVisibleTime;
588
589    /**
590     * Which uses have been started, so are allowed to run code.
591     */
592    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
593
594    /**
595     * LRU list of history of current users.  Most recently current is at the end.
596     */
597    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
598
599    /**
600     * Constant array of the users that are currently started.
601     */
602    int[] mStartedUserArray = new int[] { 0 };
603
604    /**
605     * Registered observers of the user switching mechanics.
606     */
607    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
608            = new RemoteCallbackList<IUserSwitchObserver>();
609
610    /**
611     * Currently active user switch.
612     */
613    Object mCurUserSwitchCallback;
614
615    /**
616     * Packages that the user has asked to have run in screen size
617     * compatibility mode instead of filling the screen.
618     */
619    final CompatModePackages mCompatModePackages;
620
621    /**
622     * Set of IntentSenderRecord objects that are currently active.
623     */
624    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
625            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
626
627    /**
628     * Fingerprints (hashCode()) of stack traces that we've
629     * already logged DropBox entries for.  Guarded by itself.  If
630     * something (rogue user app) forces this over
631     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
632     */
633    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
634    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
635
636    /**
637     * Strict Mode background batched logging state.
638     *
639     * The string buffer is guarded by itself, and its lock is also
640     * used to determine if another batched write is already
641     * in-flight.
642     */
643    private final StringBuilder mStrictModeBuffer = new StringBuilder();
644
645    /**
646     * Keeps track of all IIntentReceivers that have been registered for
647     * broadcasts.  Hash keys are the receiver IBinder, hash value is
648     * a ReceiverList.
649     */
650    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
651            new HashMap<IBinder, ReceiverList>();
652
653    /**
654     * Resolver for broadcast intents to registered receivers.
655     * Holds BroadcastFilter (subclass of IntentFilter).
656     */
657    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
658            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
659        @Override
660        protected boolean allowFilterResult(
661                BroadcastFilter filter, List<BroadcastFilter> dest) {
662            IBinder target = filter.receiverList.receiver.asBinder();
663            for (int i=dest.size()-1; i>=0; i--) {
664                if (dest.get(i).receiverList.receiver.asBinder() == target) {
665                    return false;
666                }
667            }
668            return true;
669        }
670
671        @Override
672        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
673            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
674                    || userId == filter.owningUserId) {
675                return super.newResult(filter, match, userId);
676            }
677            return null;
678        }
679
680        @Override
681        protected BroadcastFilter[] newArray(int size) {
682            return new BroadcastFilter[size];
683        }
684
685        @Override
686        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
687            return packageName.equals(filter.packageName);
688        }
689    };
690
691    /**
692     * State of all active sticky broadcasts per user.  Keys are the action of the
693     * sticky Intent, values are an ArrayList of all broadcasted intents with
694     * that action (which should usually be one).  The SparseArray is keyed
695     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
696     * for stickies that are sent to all users.
697     */
698    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
699            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
700
701    final ActiveServices mServices;
702
703    /**
704     * Backup/restore process management
705     */
706    String mBackupAppName = null;
707    BackupRecord mBackupTarget = null;
708
709    final ProviderMap mProviderMap;
710
711    /**
712     * List of content providers who have clients waiting for them.  The
713     * application is currently being launched and the provider will be
714     * removed from this list once it is published.
715     */
716    final ArrayList<ContentProviderRecord> mLaunchingProviders
717            = new ArrayList<ContentProviderRecord>();
718
719    /**
720     * File storing persisted {@link #mGrantedUriPermissions}.
721     */
722    private final AtomicFile mGrantFile;
723
724    /** XML constants used in {@link #mGrantFile} */
725    private static final String TAG_URI_GRANTS = "uri-grants";
726    private static final String TAG_URI_GRANT = "uri-grant";
727    private static final String ATTR_USER_HANDLE = "userHandle";
728    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
729    private static final String ATTR_TARGET_USER_ID = "targetUserId";
730    private static final String ATTR_SOURCE_PKG = "sourcePkg";
731    private static final String ATTR_TARGET_PKG = "targetPkg";
732    private static final String ATTR_URI = "uri";
733    private static final String ATTR_MODE_FLAGS = "modeFlags";
734    private static final String ATTR_CREATED_TIME = "createdTime";
735    private static final String ATTR_PREFIX = "prefix";
736
737    /**
738     * Global set of specific {@link Uri} permissions that have been granted.
739     * This optimized lookup structure maps from {@link UriPermission#targetUid}
740     * to {@link UriPermission#uri} to {@link UriPermission}.
741     */
742    @GuardedBy("this")
743    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
744            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
745
746    public static class GrantUri {
747        public final int sourceUserId;
748        public final Uri uri;
749        public boolean prefix;
750
751        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
752            this.sourceUserId = sourceUserId;
753            this.uri = uri;
754            this.prefix = prefix;
755        }
756
757        @Override
758        public int hashCode() {
759            return toString().hashCode();
760        }
761
762        @Override
763        public boolean equals(Object o) {
764            if (o instanceof GrantUri) {
765                GrantUri other = (GrantUri) o;
766                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
767                        && prefix == other.prefix;
768            }
769            return false;
770        }
771
772        @Override
773        public String toString() {
774            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
775            if (prefix) result += " [prefix]";
776            return result;
777        }
778
779        public String toSafeString() {
780            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
781            if (prefix) result += " [prefix]";
782            return result;
783        }
784
785        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
786            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
787                    ContentProvider.getUriWithoutUserId(uri), false);
788        }
789    }
790
791    CoreSettingsObserver mCoreSettingsObserver;
792
793    /**
794     * Thread-local storage used to carry caller permissions over through
795     * indirect content-provider access.
796     */
797    private class Identity {
798        public int pid;
799        public int uid;
800
801        Identity(int _pid, int _uid) {
802            pid = _pid;
803            uid = _uid;
804        }
805    }
806
807    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
808
809    /**
810     * All information we have collected about the runtime performance of
811     * any user id that can impact battery performance.
812     */
813    final BatteryStatsService mBatteryStatsService;
814
815    /**
816     * Information about component usage
817     */
818    final UsageStatsService mUsageStatsService;
819
820    /**
821     * Information about and control over application operations
822     */
823    final AppOpsService mAppOpsService;
824
825    /**
826     * Save recent tasks information across reboots.
827     */
828    final TaskPersister mTaskPersister;
829
830    /**
831     * Current configuration information.  HistoryRecord objects are given
832     * a reference to this object to indicate which configuration they are
833     * currently running in, so this object must be kept immutable.
834     */
835    Configuration mConfiguration = new Configuration();
836
837    /**
838     * Current sequencing integer of the configuration, for skipping old
839     * configurations.
840     */
841    int mConfigurationSeq = 0;
842
843    /**
844     * Hardware-reported OpenGLES version.
845     */
846    final int GL_ES_VERSION;
847
848    /**
849     * List of initialization arguments to pass to all processes when binding applications to them.
850     * For example, references to the commonly used services.
851     */
852    HashMap<String, IBinder> mAppBindArgs;
853
854    /**
855     * Temporary to avoid allocations.  Protected by main lock.
856     */
857    final StringBuilder mStringBuilder = new StringBuilder(256);
858
859    /**
860     * Used to control how we initialize the service.
861     */
862    ComponentName mTopComponent;
863    String mTopAction = Intent.ACTION_MAIN;
864    String mTopData;
865    boolean mProcessesReady = false;
866    boolean mSystemReady = false;
867    boolean mBooting = false;
868    boolean mWaitingUpdate = false;
869    boolean mDidUpdate = false;
870    boolean mOnBattery = false;
871    boolean mLaunchWarningShown = false;
872
873    Context mContext;
874
875    int mFactoryTest;
876
877    boolean mCheckedForSetup;
878
879    /**
880     * The time at which we will allow normal application switches again,
881     * after a call to {@link #stopAppSwitches()}.
882     */
883    long mAppSwitchesAllowedTime;
884
885    /**
886     * This is set to true after the first switch after mAppSwitchesAllowedTime
887     * is set; any switches after that will clear the time.
888     */
889    boolean mDidAppSwitch;
890
891    /**
892     * Last time (in realtime) at which we checked for power usage.
893     */
894    long mLastPowerCheckRealtime;
895
896    /**
897     * Last time (in uptime) at which we checked for power usage.
898     */
899    long mLastPowerCheckUptime;
900
901    /**
902     * Set while we are wanting to sleep, to prevent any
903     * activities from being started/resumed.
904     */
905    private boolean mSleeping = false;
906
907    /**
908     * Set while we are running a voice interaction.  This overrides
909     * sleeping while it is active.
910     */
911    private boolean mRunningVoice = false;
912
913    /**
914     * State of external calls telling us if the device is asleep.
915     */
916    private boolean mWentToSleep = false;
917
918    /**
919     * State of external call telling us if the lock screen is shown.
920     */
921    private boolean mLockScreenShown = false;
922
923    /**
924     * Set if we are shutting down the system, similar to sleeping.
925     */
926    boolean mShuttingDown = false;
927
928    /**
929     * Current sequence id for oom_adj computation traversal.
930     */
931    int mAdjSeq = 0;
932
933    /**
934     * Current sequence id for process LRU updating.
935     */
936    int mLruSeq = 0;
937
938    /**
939     * Keep track of the non-cached/empty process we last found, to help
940     * determine how to distribute cached/empty processes next time.
941     */
942    int mNumNonCachedProcs = 0;
943
944    /**
945     * Keep track of the number of cached hidden procs, to balance oom adj
946     * distribution between those and empty procs.
947     */
948    int mNumCachedHiddenProcs = 0;
949
950    /**
951     * Keep track of the number of service processes we last found, to
952     * determine on the next iteration which should be B services.
953     */
954    int mNumServiceProcs = 0;
955    int mNewNumAServiceProcs = 0;
956    int mNewNumServiceProcs = 0;
957
958    /**
959     * Allow the current computed overall memory level of the system to go down?
960     * This is set to false when we are killing processes for reasons other than
961     * memory management, so that the now smaller process list will not be taken as
962     * an indication that memory is tighter.
963     */
964    boolean mAllowLowerMemLevel = false;
965
966    /**
967     * The last computed memory level, for holding when we are in a state that
968     * processes are going away for other reasons.
969     */
970    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
971
972    /**
973     * The last total number of process we have, to determine if changes actually look
974     * like a shrinking number of process due to lower RAM.
975     */
976    int mLastNumProcesses;
977
978    /**
979     * The uptime of the last time we performed idle maintenance.
980     */
981    long mLastIdleTime = SystemClock.uptimeMillis();
982
983    /**
984     * Total time spent with RAM that has been added in the past since the last idle time.
985     */
986    long mLowRamTimeSinceLastIdle = 0;
987
988    /**
989     * If RAM is currently low, when that horrible situation started.
990     */
991    long mLowRamStartTime = 0;
992
993    /**
994     * For reporting to battery stats the current top application.
995     */
996    private String mCurResumedPackage = null;
997    private int mCurResumedUid = -1;
998
999    /**
1000     * For reporting to battery stats the apps currently running foreground
1001     * service.  The ProcessMap is package/uid tuples; each of these contain
1002     * an array of the currently foreground processes.
1003     */
1004    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1005            = new ProcessMap<ArrayList<ProcessRecord>>();
1006
1007    /**
1008     * This is set if we had to do a delayed dexopt of an app before launching
1009     * it, to increase the ANR timeouts in that case.
1010     */
1011    boolean mDidDexOpt;
1012
1013    /**
1014     * Set if the systemServer made a call to enterSafeMode.
1015     */
1016    boolean mSafeMode;
1017
1018    String mDebugApp = null;
1019    boolean mWaitForDebugger = false;
1020    boolean mDebugTransient = false;
1021    String mOrigDebugApp = null;
1022    boolean mOrigWaitForDebugger = false;
1023    boolean mAlwaysFinishActivities = false;
1024    IActivityController mController = null;
1025    String mProfileApp = null;
1026    ProcessRecord mProfileProc = null;
1027    String mProfileFile;
1028    ParcelFileDescriptor mProfileFd;
1029    int mProfileType = 0;
1030    boolean mAutoStopProfiler = false;
1031    String mOpenGlTraceApp = null;
1032
1033    static class ProcessChangeItem {
1034        static final int CHANGE_ACTIVITIES = 1<<0;
1035        static final int CHANGE_PROCESS_STATE = 1<<1;
1036        int changes;
1037        int uid;
1038        int pid;
1039        int processState;
1040        boolean foregroundActivities;
1041    }
1042
1043    final RemoteCallbackList<IProcessObserver> mProcessObservers
1044            = new RemoteCallbackList<IProcessObserver>();
1045    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1046
1047    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1048            = new ArrayList<ProcessChangeItem>();
1049    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1050            = new ArrayList<ProcessChangeItem>();
1051
1052    /**
1053     * Runtime CPU use collection thread.  This object's lock is used to
1054     * protect all related state.
1055     */
1056    final Thread mProcessCpuThread;
1057
1058    /**
1059     * Used to collect process stats when showing not responding dialog.
1060     * Protected by mProcessCpuThread.
1061     */
1062    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1063            MONITOR_THREAD_CPU_USAGE);
1064    final AtomicLong mLastCpuTime = new AtomicLong(0);
1065    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1066
1067    long mLastWriteTime = 0;
1068
1069    /**
1070     * Used to retain an update lock when the foreground activity is in
1071     * immersive mode.
1072     */
1073    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1074
1075    /**
1076     * Set to true after the system has finished booting.
1077     */
1078    boolean mBooted = false;
1079
1080    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1081    int mProcessLimitOverride = -1;
1082
1083    WindowManagerService mWindowManager;
1084
1085    final ActivityThread mSystemThread;
1086
1087    int mCurrentUserId = 0;
1088    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1089    private UserManagerService mUserManager;
1090
1091    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1092        final ProcessRecord mApp;
1093        final int mPid;
1094        final IApplicationThread mAppThread;
1095
1096        AppDeathRecipient(ProcessRecord app, int pid,
1097                IApplicationThread thread) {
1098            if (localLOGV) Slog.v(
1099                TAG, "New death recipient " + this
1100                + " for thread " + thread.asBinder());
1101            mApp = app;
1102            mPid = pid;
1103            mAppThread = thread;
1104        }
1105
1106        @Override
1107        public void binderDied() {
1108            if (localLOGV) Slog.v(
1109                TAG, "Death received in " + this
1110                + " for thread " + mAppThread.asBinder());
1111            synchronized(ActivityManagerService.this) {
1112                appDiedLocked(mApp, mPid, mAppThread);
1113            }
1114        }
1115    }
1116
1117    static final int SHOW_ERROR_MSG = 1;
1118    static final int SHOW_NOT_RESPONDING_MSG = 2;
1119    static final int SHOW_FACTORY_ERROR_MSG = 3;
1120    static final int UPDATE_CONFIGURATION_MSG = 4;
1121    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1122    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1123    static final int SERVICE_TIMEOUT_MSG = 12;
1124    static final int UPDATE_TIME_ZONE = 13;
1125    static final int SHOW_UID_ERROR_MSG = 14;
1126    static final int IM_FEELING_LUCKY_MSG = 15;
1127    static final int PROC_START_TIMEOUT_MSG = 20;
1128    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1129    static final int KILL_APPLICATION_MSG = 22;
1130    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1131    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1132    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1133    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1134    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1135    static final int CLEAR_DNS_CACHE_MSG = 28;
1136    static final int UPDATE_HTTP_PROXY_MSG = 29;
1137    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1138    static final int DISPATCH_PROCESSES_CHANGED = 31;
1139    static final int DISPATCH_PROCESS_DIED = 32;
1140    static final int REPORT_MEM_USAGE_MSG = 33;
1141    static final int REPORT_USER_SWITCH_MSG = 34;
1142    static final int CONTINUE_USER_SWITCH_MSG = 35;
1143    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1144    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1145    static final int PERSIST_URI_GRANTS_MSG = 38;
1146    static final int REQUEST_ALL_PSS_MSG = 39;
1147    static final int START_PROFILES_MSG = 40;
1148    static final int UPDATE_TIME = 41;
1149    static final int SYSTEM_USER_START_MSG = 42;
1150    static final int SYSTEM_USER_CURRENT_MSG = 43;
1151
1152    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1153    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1154    static final int FIRST_COMPAT_MODE_MSG = 300;
1155    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1156
1157    AlertDialog mUidAlert;
1158    CompatModeDialog mCompatModeDialog;
1159    long mLastMemUsageReportTime = 0;
1160
1161    /**
1162     * Flag whether the current user is a "monkey", i.e. whether
1163     * the UI is driven by a UI automation tool.
1164     */
1165    private boolean mUserIsMonkey;
1166
1167    final ServiceThread mHandlerThread;
1168    final MainHandler mHandler;
1169
1170    final class MainHandler extends Handler {
1171        public MainHandler(Looper looper) {
1172            super(looper, null, true);
1173        }
1174
1175        @Override
1176        public void handleMessage(Message msg) {
1177            switch (msg.what) {
1178            case SHOW_ERROR_MSG: {
1179                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1180                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1181                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1182                synchronized (ActivityManagerService.this) {
1183                    ProcessRecord proc = (ProcessRecord)data.get("app");
1184                    AppErrorResult res = (AppErrorResult) data.get("result");
1185                    if (proc != null && proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has crash dialog: " + proc);
1187                        if (res != null) {
1188                            res.set(0);
1189                        }
1190                        return;
1191                    }
1192                    if (!showBackground && UserHandle.getAppId(proc.uid)
1193                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1194                            && proc.pid != MY_PID) {
1195                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1196                        if (res != null) {
1197                            res.set(0);
1198                        }
1199                        return;
1200                    }
1201                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1202                        Dialog d = new AppErrorDialog(mContext,
1203                                ActivityManagerService.this, res, proc);
1204                        d.show();
1205                        proc.crashDialog = d;
1206                    } else {
1207                        // The device is asleep, so just pretend that the user
1208                        // saw a crash dialog and hit "force quit".
1209                        if (res != null) {
1210                            res.set(0);
1211                        }
1212                    }
1213                }
1214
1215                ensureBootCompleted();
1216            } break;
1217            case SHOW_NOT_RESPONDING_MSG: {
1218                synchronized (ActivityManagerService.this) {
1219                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1220                    ProcessRecord proc = (ProcessRecord)data.get("app");
1221                    if (proc != null && proc.anrDialog != null) {
1222                        Slog.e(TAG, "App already has anr dialog: " + proc);
1223                        return;
1224                    }
1225
1226                    Intent intent = new Intent("android.intent.action.ANR");
1227                    if (!mProcessesReady) {
1228                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1229                                | Intent.FLAG_RECEIVER_FOREGROUND);
1230                    }
1231                    broadcastIntentLocked(null, null, intent,
1232                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1233                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1234
1235                    if (mShowDialogs) {
1236                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1237                                mContext, proc, (ActivityRecord)data.get("activity"),
1238                                msg.arg1 != 0);
1239                        d.show();
1240                        proc.anrDialog = d;
1241                    } else {
1242                        // Just kill the app if there is no dialog to be shown.
1243                        killAppAtUsersRequest(proc, null);
1244                    }
1245                }
1246
1247                ensureBootCompleted();
1248            } break;
1249            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1250                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1251                synchronized (ActivityManagerService.this) {
1252                    ProcessRecord proc = (ProcessRecord) data.get("app");
1253                    if (proc == null) {
1254                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1255                        break;
1256                    }
1257                    if (proc.crashDialog != null) {
1258                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1259                        return;
1260                    }
1261                    AppErrorResult res = (AppErrorResult) data.get("result");
1262                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1263                        Dialog d = new StrictModeViolationDialog(mContext,
1264                                ActivityManagerService.this, res, proc);
1265                        d.show();
1266                        proc.crashDialog = d;
1267                    } else {
1268                        // The device is asleep, so just pretend that the user
1269                        // saw a crash dialog and hit "force quit".
1270                        res.set(0);
1271                    }
1272                }
1273                ensureBootCompleted();
1274            } break;
1275            case SHOW_FACTORY_ERROR_MSG: {
1276                Dialog d = new FactoryErrorDialog(
1277                    mContext, msg.getData().getCharSequence("msg"));
1278                d.show();
1279                ensureBootCompleted();
1280            } break;
1281            case UPDATE_CONFIGURATION_MSG: {
1282                final ContentResolver resolver = mContext.getContentResolver();
1283                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1284            } break;
1285            case GC_BACKGROUND_PROCESSES_MSG: {
1286                synchronized (ActivityManagerService.this) {
1287                    performAppGcsIfAppropriateLocked();
1288                }
1289            } break;
1290            case WAIT_FOR_DEBUGGER_MSG: {
1291                synchronized (ActivityManagerService.this) {
1292                    ProcessRecord app = (ProcessRecord)msg.obj;
1293                    if (msg.arg1 != 0) {
1294                        if (!app.waitedForDebugger) {
1295                            Dialog d = new AppWaitingForDebuggerDialog(
1296                                    ActivityManagerService.this,
1297                                    mContext, app);
1298                            app.waitDialog = d;
1299                            app.waitedForDebugger = true;
1300                            d.show();
1301                        }
1302                    } else {
1303                        if (app.waitDialog != null) {
1304                            app.waitDialog.dismiss();
1305                            app.waitDialog = null;
1306                        }
1307                    }
1308                }
1309            } break;
1310            case SERVICE_TIMEOUT_MSG: {
1311                if (mDidDexOpt) {
1312                    mDidDexOpt = false;
1313                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1314                    nmsg.obj = msg.obj;
1315                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1316                    return;
1317                }
1318                mServices.serviceTimeout((ProcessRecord)msg.obj);
1319            } break;
1320            case UPDATE_TIME_ZONE: {
1321                synchronized (ActivityManagerService.this) {
1322                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1323                        ProcessRecord r = mLruProcesses.get(i);
1324                        if (r.thread != null) {
1325                            try {
1326                                r.thread.updateTimeZone();
1327                            } catch (RemoteException ex) {
1328                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1329                            }
1330                        }
1331                    }
1332                }
1333            } break;
1334            case CLEAR_DNS_CACHE_MSG: {
1335                synchronized (ActivityManagerService.this) {
1336                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1337                        ProcessRecord r = mLruProcesses.get(i);
1338                        if (r.thread != null) {
1339                            try {
1340                                r.thread.clearDnsCache();
1341                            } catch (RemoteException ex) {
1342                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1343                            }
1344                        }
1345                    }
1346                }
1347            } break;
1348            case UPDATE_HTTP_PROXY_MSG: {
1349                ProxyInfo proxy = (ProxyInfo)msg.obj;
1350                String host = "";
1351                String port = "";
1352                String exclList = "";
1353                Uri pacFileUrl = Uri.EMPTY;
1354                if (proxy != null) {
1355                    host = proxy.getHost();
1356                    port = Integer.toString(proxy.getPort());
1357                    exclList = proxy.getExclusionListAsString();
1358                    pacFileUrl = proxy.getPacFileUrl();
1359                }
1360                synchronized (ActivityManagerService.this) {
1361                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1362                        ProcessRecord r = mLruProcesses.get(i);
1363                        if (r.thread != null) {
1364                            try {
1365                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1366                            } catch (RemoteException ex) {
1367                                Slog.w(TAG, "Failed to update http proxy for: " +
1368                                        r.info.processName);
1369                            }
1370                        }
1371                    }
1372                }
1373            } break;
1374            case SHOW_UID_ERROR_MSG: {
1375                String title = "System UIDs Inconsistent";
1376                String text = "UIDs on the system are inconsistent, you need to wipe your"
1377                        + " data partition or your device will be unstable.";
1378                Log.e(TAG, title + ": " + text);
1379                if (mShowDialogs) {
1380                    // XXX This is a temporary dialog, no need to localize.
1381                    AlertDialog d = new BaseErrorDialog(mContext);
1382                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1383                    d.setCancelable(false);
1384                    d.setTitle(title);
1385                    d.setMessage(text);
1386                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1387                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1388                    mUidAlert = d;
1389                    d.show();
1390                }
1391            } break;
1392            case IM_FEELING_LUCKY_MSG: {
1393                if (mUidAlert != null) {
1394                    mUidAlert.dismiss();
1395                    mUidAlert = null;
1396                }
1397            } break;
1398            case PROC_START_TIMEOUT_MSG: {
1399                if (mDidDexOpt) {
1400                    mDidDexOpt = false;
1401                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1402                    nmsg.obj = msg.obj;
1403                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1404                    return;
1405                }
1406                ProcessRecord app = (ProcessRecord)msg.obj;
1407                synchronized (ActivityManagerService.this) {
1408                    processStartTimedOutLocked(app);
1409                }
1410            } break;
1411            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1412                synchronized (ActivityManagerService.this) {
1413                    doPendingActivityLaunchesLocked(true);
1414                }
1415            } break;
1416            case KILL_APPLICATION_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    int appid = msg.arg1;
1419                    boolean restart = (msg.arg2 == 1);
1420                    Bundle bundle = (Bundle)msg.obj;
1421                    String pkg = bundle.getString("pkg");
1422                    String reason = bundle.getString("reason");
1423                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1424                            false, UserHandle.USER_ALL, reason);
1425                }
1426            } break;
1427            case FINALIZE_PENDING_INTENT_MSG: {
1428                ((PendingIntentRecord)msg.obj).completeFinalize();
1429            } break;
1430            case POST_HEAVY_NOTIFICATION_MSG: {
1431                INotificationManager inm = NotificationManager.getService();
1432                if (inm == null) {
1433                    return;
1434                }
1435
1436                ActivityRecord root = (ActivityRecord)msg.obj;
1437                ProcessRecord process = root.app;
1438                if (process == null) {
1439                    return;
1440                }
1441
1442                try {
1443                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1444                    String text = mContext.getString(R.string.heavy_weight_notification,
1445                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1446                    Notification notification = new Notification();
1447                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1448                    notification.when = 0;
1449                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1450                    notification.tickerText = text;
1451                    notification.defaults = 0; // please be quiet
1452                    notification.sound = null;
1453                    notification.vibrate = null;
1454                    notification.setLatestEventInfo(context, text,
1455                            mContext.getText(R.string.heavy_weight_notification_detail),
1456                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1457                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1458                                    new UserHandle(root.userId)));
1459
1460                    try {
1461                        int[] outId = new int[1];
1462                        inm.enqueueNotificationWithTag("android", "android", null,
1463                                R.string.heavy_weight_notification,
1464                                notification, outId, root.userId);
1465                    } catch (RuntimeException e) {
1466                        Slog.w(ActivityManagerService.TAG,
1467                                "Error showing notification for heavy-weight app", e);
1468                    } catch (RemoteException e) {
1469                    }
1470                } catch (NameNotFoundException e) {
1471                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1472                }
1473            } break;
1474            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1475                INotificationManager inm = NotificationManager.getService();
1476                if (inm == null) {
1477                    return;
1478                }
1479                try {
1480                    inm.cancelNotificationWithTag("android", null,
1481                            R.string.heavy_weight_notification,  msg.arg1);
1482                } catch (RuntimeException e) {
1483                    Slog.w(ActivityManagerService.TAG,
1484                            "Error canceling notification for service", e);
1485                } catch (RemoteException e) {
1486                }
1487            } break;
1488            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1489                synchronized (ActivityManagerService.this) {
1490                    checkExcessivePowerUsageLocked(true);
1491                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1492                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1493                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1494                }
1495            } break;
1496            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1497                synchronized (ActivityManagerService.this) {
1498                    ActivityRecord ar = (ActivityRecord)msg.obj;
1499                    if (mCompatModeDialog != null) {
1500                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1501                                ar.info.applicationInfo.packageName)) {
1502                            return;
1503                        }
1504                        mCompatModeDialog.dismiss();
1505                        mCompatModeDialog = null;
1506                    }
1507                    if (ar != null && false) {
1508                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1509                                ar.packageName)) {
1510                            int mode = mCompatModePackages.computeCompatModeLocked(
1511                                    ar.info.applicationInfo);
1512                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1513                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1514                                mCompatModeDialog = new CompatModeDialog(
1515                                        ActivityManagerService.this, mContext,
1516                                        ar.info.applicationInfo);
1517                                mCompatModeDialog.show();
1518                            }
1519                        }
1520                    }
1521                }
1522                break;
1523            }
1524            case DISPATCH_PROCESSES_CHANGED: {
1525                dispatchProcessesChanged();
1526                break;
1527            }
1528            case DISPATCH_PROCESS_DIED: {
1529                final int pid = msg.arg1;
1530                final int uid = msg.arg2;
1531                dispatchProcessDied(pid, uid);
1532                break;
1533            }
1534            case REPORT_MEM_USAGE_MSG: {
1535                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1536                Thread thread = new Thread() {
1537                    @Override public void run() {
1538                        final SparseArray<ProcessMemInfo> infoMap
1539                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1540                        for (int i=0, N=memInfos.size(); i<N; i++) {
1541                            ProcessMemInfo mi = memInfos.get(i);
1542                            infoMap.put(mi.pid, mi);
1543                        }
1544                        updateCpuStatsNow();
1545                        synchronized (mProcessCpuThread) {
1546                            final int N = mProcessCpuTracker.countStats();
1547                            for (int i=0; i<N; i++) {
1548                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1549                                if (st.vsize > 0) {
1550                                    long pss = Debug.getPss(st.pid, null);
1551                                    if (pss > 0) {
1552                                        if (infoMap.indexOfKey(st.pid) < 0) {
1553                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1554                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1555                                            mi.pss = pss;
1556                                            memInfos.add(mi);
1557                                        }
1558                                    }
1559                                }
1560                            }
1561                        }
1562
1563                        long totalPss = 0;
1564                        for (int i=0, N=memInfos.size(); i<N; i++) {
1565                            ProcessMemInfo mi = memInfos.get(i);
1566                            if (mi.pss == 0) {
1567                                mi.pss = Debug.getPss(mi.pid, null);
1568                            }
1569                            totalPss += mi.pss;
1570                        }
1571                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1572                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1573                                if (lhs.oomAdj != rhs.oomAdj) {
1574                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1575                                }
1576                                if (lhs.pss != rhs.pss) {
1577                                    return lhs.pss < rhs.pss ? 1 : -1;
1578                                }
1579                                return 0;
1580                            }
1581                        });
1582
1583                        StringBuilder tag = new StringBuilder(128);
1584                        StringBuilder stack = new StringBuilder(128);
1585                        tag.append("Low on memory -- ");
1586                        appendMemBucket(tag, totalPss, "total", false);
1587                        appendMemBucket(stack, totalPss, "total", true);
1588
1589                        StringBuilder logBuilder = new StringBuilder(1024);
1590                        logBuilder.append("Low on memory:\n");
1591
1592                        boolean firstLine = true;
1593                        int lastOomAdj = Integer.MIN_VALUE;
1594                        for (int i=0, N=memInfos.size(); i<N; i++) {
1595                            ProcessMemInfo mi = memInfos.get(i);
1596
1597                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1598                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1599                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1600                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1601                                if (lastOomAdj != mi.oomAdj) {
1602                                    lastOomAdj = mi.oomAdj;
1603                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1604                                        tag.append(" / ");
1605                                    }
1606                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1607                                        if (firstLine) {
1608                                            stack.append(":");
1609                                            firstLine = false;
1610                                        }
1611                                        stack.append("\n\t at ");
1612                                    } else {
1613                                        stack.append("$");
1614                                    }
1615                                } else {
1616                                    tag.append(" ");
1617                                    stack.append("$");
1618                                }
1619                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                    appendMemBucket(tag, mi.pss, mi.name, false);
1621                                }
1622                                appendMemBucket(stack, mi.pss, mi.name, true);
1623                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1624                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1625                                    stack.append("(");
1626                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1627                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1628                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1629                                            stack.append(":");
1630                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1631                                        }
1632                                    }
1633                                    stack.append(")");
1634                                }
1635                            }
1636
1637                            logBuilder.append("  ");
1638                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1639                            logBuilder.append(' ');
1640                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1641                            logBuilder.append(' ');
1642                            ProcessList.appendRamKb(logBuilder, mi.pss);
1643                            logBuilder.append(" kB: ");
1644                            logBuilder.append(mi.name);
1645                            logBuilder.append(" (");
1646                            logBuilder.append(mi.pid);
1647                            logBuilder.append(") ");
1648                            logBuilder.append(mi.adjType);
1649                            logBuilder.append('\n');
1650                            if (mi.adjReason != null) {
1651                                logBuilder.append("                      ");
1652                                logBuilder.append(mi.adjReason);
1653                                logBuilder.append('\n');
1654                            }
1655                        }
1656
1657                        logBuilder.append("           ");
1658                        ProcessList.appendRamKb(logBuilder, totalPss);
1659                        logBuilder.append(" kB: TOTAL\n");
1660
1661                        long[] infos = new long[Debug.MEMINFO_COUNT];
1662                        Debug.getMemInfo(infos);
1663                        logBuilder.append("  MemInfo: ");
1664                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1667                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1668                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1669                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1670                            logBuilder.append("  ZRAM: ");
1671                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1672                            logBuilder.append(" kB RAM, ");
1673                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1674                            logBuilder.append(" kB swap total, ");
1675                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1676                            logBuilder.append(" kB swap free\n");
1677                        }
1678                        Slog.i(TAG, logBuilder.toString());
1679
1680                        StringBuilder dropBuilder = new StringBuilder(1024);
1681                        /*
1682                        StringWriter oomSw = new StringWriter();
1683                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1684                        StringWriter catSw = new StringWriter();
1685                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1686                        String[] emptyArgs = new String[] { };
1687                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1688                        oomPw.flush();
1689                        String oomString = oomSw.toString();
1690                        */
1691                        dropBuilder.append(stack);
1692                        dropBuilder.append('\n');
1693                        dropBuilder.append('\n');
1694                        dropBuilder.append(logBuilder);
1695                        dropBuilder.append('\n');
1696                        /*
1697                        dropBuilder.append(oomString);
1698                        dropBuilder.append('\n');
1699                        */
1700                        StringWriter catSw = new StringWriter();
1701                        synchronized (ActivityManagerService.this) {
1702                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                            String[] emptyArgs = new String[] { };
1704                            catPw.println();
1705                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1706                            catPw.println();
1707                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1708                                    false, false, null);
1709                            catPw.println();
1710                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1711                            catPw.flush();
1712                        }
1713                        dropBuilder.append(catSw.toString());
1714                        addErrorToDropBox("lowmem", null, "system_server", null,
1715                                null, tag.toString(), dropBuilder.toString(), null, null);
1716                        //Slog.i(TAG, "Sent to dropbox:");
1717                        //Slog.i(TAG, dropBuilder.toString());
1718                        synchronized (ActivityManagerService.this) {
1719                            long now = SystemClock.uptimeMillis();
1720                            if (mLastMemUsageReportTime < now) {
1721                                mLastMemUsageReportTime = now;
1722                            }
1723                        }
1724                    }
1725                };
1726                thread.start();
1727                break;
1728            }
1729            case REPORT_USER_SWITCH_MSG: {
1730                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1731                break;
1732            }
1733            case CONTINUE_USER_SWITCH_MSG: {
1734                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1735                break;
1736            }
1737            case USER_SWITCH_TIMEOUT_MSG: {
1738                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1739                break;
1740            }
1741            case IMMERSIVE_MODE_LOCK_MSG: {
1742                final boolean nextState = (msg.arg1 != 0);
1743                if (mUpdateLock.isHeld() != nextState) {
1744                    if (DEBUG_IMMERSIVE) {
1745                        final ActivityRecord r = (ActivityRecord) msg.obj;
1746                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1747                    }
1748                    if (nextState) {
1749                        mUpdateLock.acquire();
1750                    } else {
1751                        mUpdateLock.release();
1752                    }
1753                }
1754                break;
1755            }
1756            case PERSIST_URI_GRANTS_MSG: {
1757                writeGrantedUriPermissions();
1758                break;
1759            }
1760            case REQUEST_ALL_PSS_MSG: {
1761                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1762                break;
1763            }
1764            case START_PROFILES_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    startProfilesLocked();
1767                }
1768                break;
1769            }
1770            case UPDATE_TIME: {
1771                synchronized (ActivityManagerService.this) {
1772                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1773                        ProcessRecord r = mLruProcesses.get(i);
1774                        if (r.thread != null) {
1775                            try {
1776                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1777                            } catch (RemoteException ex) {
1778                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1779                            }
1780                        }
1781                    }
1782                }
1783                break;
1784            }
1785            case SYSTEM_USER_START_MSG: {
1786                mSystemServiceManager.startUser(msg.arg1);
1787                break;
1788            }
1789            case SYSTEM_USER_CURRENT_MSG: {
1790                mSystemServiceManager.switchUser(msg.arg1);
1791                break;
1792            }
1793            }
1794        }
1795    };
1796
1797    static final int COLLECT_PSS_BG_MSG = 1;
1798
1799    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1800        @Override
1801        public void handleMessage(Message msg) {
1802            switch (msg.what) {
1803            case COLLECT_PSS_BG_MSG: {
1804                int i=0, num=0;
1805                long start = SystemClock.uptimeMillis();
1806                long[] tmp = new long[1];
1807                do {
1808                    ProcessRecord proc;
1809                    int procState;
1810                    int pid;
1811                    synchronized (ActivityManagerService.this) {
1812                        if (i >= mPendingPssProcesses.size()) {
1813                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1814                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1815                            mPendingPssProcesses.clear();
1816                            return;
1817                        }
1818                        proc = mPendingPssProcesses.get(i);
1819                        procState = proc.pssProcState;
1820                        if (proc.thread != null && procState == proc.setProcState) {
1821                            pid = proc.pid;
1822                        } else {
1823                            proc = null;
1824                            pid = 0;
1825                        }
1826                        i++;
1827                    }
1828                    if (proc != null) {
1829                        long pss = Debug.getPss(pid, tmp);
1830                        synchronized (ActivityManagerService.this) {
1831                            if (proc.thread != null && proc.setProcState == procState
1832                                    && proc.pid == pid) {
1833                                num++;
1834                                proc.lastPssTime = SystemClock.uptimeMillis();
1835                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1836                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1837                                        + ": " + pss + " lastPss=" + proc.lastPss
1838                                        + " state=" + ProcessList.makeProcStateString(procState));
1839                                if (proc.initialIdlePss == 0) {
1840                                    proc.initialIdlePss = pss;
1841                                }
1842                                proc.lastPss = pss;
1843                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1844                                    proc.lastCachedPss = pss;
1845                                }
1846                            }
1847                        }
1848                    }
1849                } while (true);
1850            }
1851            }
1852        }
1853    };
1854
1855    /**
1856     * Monitor for package changes and update our internal state.
1857     */
1858    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1859        @Override
1860        public void onPackageRemoved(String packageName, int uid) {
1861            // Remove all tasks with activities in the specified package from the list of recent tasks
1862            synchronized (ActivityManagerService.this) {
1863                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1864                    TaskRecord tr = mRecentTasks.get(i);
1865                    ComponentName cn = tr.intent.getComponent();
1866                    if (cn != null && cn.getPackageName().equals(packageName)) {
1867                        // If the package name matches, remove the task and kill the process
1868                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1869                    }
1870                }
1871            }
1872        }
1873
1874        @Override
1875        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1876            onPackageModified(packageName);
1877            return true;
1878        }
1879
1880        @Override
1881        public void onPackageModified(String packageName) {
1882            final PackageManager pm = mContext.getPackageManager();
1883            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1884                    new ArrayList<Pair<Intent, Integer>>();
1885            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1886            // Copy the list of recent tasks so that we don't hold onto the lock on
1887            // ActivityManagerService for long periods while checking if components exist.
1888            synchronized (ActivityManagerService.this) {
1889                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1890                    TaskRecord tr = mRecentTasks.get(i);
1891                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1892                }
1893            }
1894            // Check the recent tasks and filter out all tasks with components that no longer exist.
1895            Intent tmpI = new Intent();
1896            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1897                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1898                ComponentName cn = p.first.getComponent();
1899                if (cn != null && cn.getPackageName().equals(packageName)) {
1900                    try {
1901                        // Add the task to the list to remove if the component no longer exists
1902                        tmpI.setComponent(cn);
1903                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1904                            tasksToRemove.add(p.second);
1905                        }
1906                    } catch (Exception e) {}
1907                }
1908            }
1909            // Prune all the tasks with removed components from the list of recent tasks
1910            synchronized (ActivityManagerService.this) {
1911                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1912                    // Remove the task but don't kill the process (since other components in that
1913                    // package may still be running and in the background)
1914                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1915                }
1916            }
1917        }
1918
1919        @Override
1920        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1921            // Force stop the specified packages
1922            if (packages != null) {
1923                for (String pkg : packages) {
1924                    synchronized (ActivityManagerService.this) {
1925                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1926                                "finished booting")) {
1927                            return true;
1928                        }
1929                    }
1930                }
1931            }
1932            return false;
1933        }
1934    };
1935
1936    public void setSystemProcess() {
1937        try {
1938            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1939            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1940            ServiceManager.addService("meminfo", new MemBinder(this));
1941            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1942            ServiceManager.addService("dbinfo", new DbBinder(this));
1943            if (MONITOR_CPU_USAGE) {
1944                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1945            }
1946            ServiceManager.addService("permission", new PermissionController(this));
1947
1948            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1949                    "android", STOCK_PM_FLAGS);
1950            mSystemThread.installSystemApplicationInfo(info);
1951
1952            synchronized (this) {
1953                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1954                app.persistent = true;
1955                app.pid = MY_PID;
1956                app.maxAdj = ProcessList.SYSTEM_ADJ;
1957                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1958                mProcessNames.put(app.processName, app.uid, app);
1959                synchronized (mPidsSelfLocked) {
1960                    mPidsSelfLocked.put(app.pid, app);
1961                }
1962                updateLruProcessLocked(app, false, null);
1963                updateOomAdjLocked();
1964            }
1965        } catch (PackageManager.NameNotFoundException e) {
1966            throw new RuntimeException(
1967                    "Unable to find android system package", e);
1968        }
1969    }
1970
1971    public void setWindowManager(WindowManagerService wm) {
1972        mWindowManager = wm;
1973        mStackSupervisor.setWindowManager(wm);
1974    }
1975
1976    public void startObservingNativeCrashes() {
1977        final NativeCrashListener ncl = new NativeCrashListener(this);
1978        ncl.start();
1979    }
1980
1981    public IAppOpsService getAppOpsService() {
1982        return mAppOpsService;
1983    }
1984
1985    static class MemBinder extends Binder {
1986        ActivityManagerService mActivityManagerService;
1987        MemBinder(ActivityManagerService activityManagerService) {
1988            mActivityManagerService = activityManagerService;
1989        }
1990
1991        @Override
1992        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1993            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1994                    != PackageManager.PERMISSION_GRANTED) {
1995                pw.println("Permission Denial: can't dump meminfo from from pid="
1996                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1997                        + " without permission " + android.Manifest.permission.DUMP);
1998                return;
1999            }
2000
2001            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2002        }
2003    }
2004
2005    static class GraphicsBinder extends Binder {
2006        ActivityManagerService mActivityManagerService;
2007        GraphicsBinder(ActivityManagerService activityManagerService) {
2008            mActivityManagerService = activityManagerService;
2009        }
2010
2011        @Override
2012        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2013            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2014                    != PackageManager.PERMISSION_GRANTED) {
2015                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2016                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2017                        + " without permission " + android.Manifest.permission.DUMP);
2018                return;
2019            }
2020
2021            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2022        }
2023    }
2024
2025    static class DbBinder extends Binder {
2026        ActivityManagerService mActivityManagerService;
2027        DbBinder(ActivityManagerService activityManagerService) {
2028            mActivityManagerService = activityManagerService;
2029        }
2030
2031        @Override
2032        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2033            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2034                    != PackageManager.PERMISSION_GRANTED) {
2035                pw.println("Permission Denial: can't dump dbinfo from from pid="
2036                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2037                        + " without permission " + android.Manifest.permission.DUMP);
2038                return;
2039            }
2040
2041            mActivityManagerService.dumpDbInfo(fd, pw, args);
2042        }
2043    }
2044
2045    static class CpuBinder extends Binder {
2046        ActivityManagerService mActivityManagerService;
2047        CpuBinder(ActivityManagerService activityManagerService) {
2048            mActivityManagerService = activityManagerService;
2049        }
2050
2051        @Override
2052        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2053            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2054                    != PackageManager.PERMISSION_GRANTED) {
2055                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2056                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2057                        + " without permission " + android.Manifest.permission.DUMP);
2058                return;
2059            }
2060
2061            synchronized (mActivityManagerService.mProcessCpuThread) {
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2063                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2064                        SystemClock.uptimeMillis()));
2065            }
2066        }
2067    }
2068
2069    public static final class Lifecycle extends SystemService {
2070        private final ActivityManagerService mService;
2071
2072        public Lifecycle(Context context) {
2073            super(context);
2074            mService = new ActivityManagerService(context);
2075        }
2076
2077        @Override
2078        public void onStart() {
2079            mService.start();
2080        }
2081
2082        public ActivityManagerService getService() {
2083            return mService;
2084        }
2085    }
2086
2087    // Note: This method is invoked on the main thread but may need to attach various
2088    // handlers to other threads.  So take care to be explicit about the looper.
2089    public ActivityManagerService(Context systemContext) {
2090        mContext = systemContext;
2091        mFactoryTest = FactoryTest.getMode();
2092        mSystemThread = ActivityThread.currentActivityThread();
2093
2094        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2095
2096        mHandlerThread = new ServiceThread(TAG,
2097                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2098        mHandlerThread.start();
2099        mHandler = new MainHandler(mHandlerThread.getLooper());
2100
2101        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2102                "foreground", BROADCAST_FG_TIMEOUT, false);
2103        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2104                "background", BROADCAST_BG_TIMEOUT, true);
2105        mBroadcastQueues[0] = mFgBroadcastQueue;
2106        mBroadcastQueues[1] = mBgBroadcastQueue;
2107
2108        mServices = new ActiveServices(this);
2109        mProviderMap = new ProviderMap(this);
2110
2111        // TODO: Move creation of battery stats service outside of activity manager service.
2112        File dataDir = Environment.getDataDirectory();
2113        File systemDir = new File(dataDir, "system");
2114        systemDir.mkdirs();
2115        mBatteryStatsService = new BatteryStatsService(new File(
2116                systemDir, "batterystats.bin").toString(), mHandler);
2117        mBatteryStatsService.getActiveStatistics().readLocked();
2118        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2119        mOnBattery = DEBUG_POWER ? true
2120                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2121        mBatteryStatsService.getActiveStatistics().setCallback(this);
2122
2123        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2124
2125        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2126        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2127
2128        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2129
2130        // User 0 is the first and only user that runs at boot.
2131        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2132        mUserLru.add(Integer.valueOf(0));
2133        updateStartedUserArrayLocked();
2134
2135        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2136            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2137
2138        mConfiguration.setToDefaults();
2139        mConfiguration.setLocale(Locale.getDefault());
2140
2141        mConfigurationSeq = mConfiguration.seq = 1;
2142        mProcessCpuTracker.init();
2143
2144        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2145        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2146        mStackSupervisor = new ActivityStackSupervisor(this);
2147        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2148
2149        mProcessCpuThread = new Thread("CpuTracker") {
2150            @Override
2151            public void run() {
2152                while (true) {
2153                    try {
2154                        try {
2155                            synchronized(this) {
2156                                final long now = SystemClock.uptimeMillis();
2157                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2158                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2159                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2160                                //        + ", write delay=" + nextWriteDelay);
2161                                if (nextWriteDelay < nextCpuDelay) {
2162                                    nextCpuDelay = nextWriteDelay;
2163                                }
2164                                if (nextCpuDelay > 0) {
2165                                    mProcessCpuMutexFree.set(true);
2166                                    this.wait(nextCpuDelay);
2167                                }
2168                            }
2169                        } catch (InterruptedException e) {
2170                        }
2171                        updateCpuStatsNow();
2172                    } catch (Exception e) {
2173                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2174                    }
2175                }
2176            }
2177        };
2178
2179        Watchdog.getInstance().addMonitor(this);
2180        Watchdog.getInstance().addThread(mHandler);
2181    }
2182
2183    public void setSystemServiceManager(SystemServiceManager mgr) {
2184        mSystemServiceManager = mgr;
2185    }
2186
2187    private void start() {
2188        mProcessCpuThread.start();
2189
2190        mBatteryStatsService.publish(mContext);
2191        mUsageStatsService.publish(mContext);
2192        mAppOpsService.publish(mContext);
2193        Slog.d("AppOps", "AppOpsService published");
2194        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2195    }
2196
2197    @Override
2198    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2199            throws RemoteException {
2200        if (code == SYSPROPS_TRANSACTION) {
2201            // We need to tell all apps about the system property change.
2202            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2203            synchronized(this) {
2204                final int NP = mProcessNames.getMap().size();
2205                for (int ip=0; ip<NP; ip++) {
2206                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2207                    final int NA = apps.size();
2208                    for (int ia=0; ia<NA; ia++) {
2209                        ProcessRecord app = apps.valueAt(ia);
2210                        if (app.thread != null) {
2211                            procs.add(app.thread.asBinder());
2212                        }
2213                    }
2214                }
2215            }
2216
2217            int N = procs.size();
2218            for (int i=0; i<N; i++) {
2219                Parcel data2 = Parcel.obtain();
2220                try {
2221                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2222                } catch (RemoteException e) {
2223                }
2224                data2.recycle();
2225            }
2226        }
2227        try {
2228            return super.onTransact(code, data, reply, flags);
2229        } catch (RuntimeException e) {
2230            // The activity manager only throws security exceptions, so let's
2231            // log all others.
2232            if (!(e instanceof SecurityException)) {
2233                Slog.wtf(TAG, "Activity Manager Crash", e);
2234            }
2235            throw e;
2236        }
2237    }
2238
2239    void updateCpuStats() {
2240        final long now = SystemClock.uptimeMillis();
2241        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2242            return;
2243        }
2244        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2245            synchronized (mProcessCpuThread) {
2246                mProcessCpuThread.notify();
2247            }
2248        }
2249    }
2250
2251    void updateCpuStatsNow() {
2252        synchronized (mProcessCpuThread) {
2253            mProcessCpuMutexFree.set(false);
2254            final long now = SystemClock.uptimeMillis();
2255            boolean haveNewCpuStats = false;
2256
2257            if (MONITOR_CPU_USAGE &&
2258                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2259                mLastCpuTime.set(now);
2260                haveNewCpuStats = true;
2261                mProcessCpuTracker.update();
2262                //Slog.i(TAG, mProcessCpu.printCurrentState());
2263                //Slog.i(TAG, "Total CPU usage: "
2264                //        + mProcessCpu.getTotalCpuPercent() + "%");
2265
2266                // Slog the cpu usage if the property is set.
2267                if ("true".equals(SystemProperties.get("events.cpu"))) {
2268                    int user = mProcessCpuTracker.getLastUserTime();
2269                    int system = mProcessCpuTracker.getLastSystemTime();
2270                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2271                    int irq = mProcessCpuTracker.getLastIrqTime();
2272                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2273                    int idle = mProcessCpuTracker.getLastIdleTime();
2274
2275                    int total = user + system + iowait + irq + softIrq + idle;
2276                    if (total == 0) total = 1;
2277
2278                    EventLog.writeEvent(EventLogTags.CPU,
2279                            ((user+system+iowait+irq+softIrq) * 100) / total,
2280                            (user * 100) / total,
2281                            (system * 100) / total,
2282                            (iowait * 100) / total,
2283                            (irq * 100) / total,
2284                            (softIrq * 100) / total);
2285                }
2286            }
2287
2288            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2289            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2290            synchronized(bstats) {
2291                synchronized(mPidsSelfLocked) {
2292                    if (haveNewCpuStats) {
2293                        if (mOnBattery) {
2294                            int perc = bstats.startAddingCpuLocked();
2295                            int totalUTime = 0;
2296                            int totalSTime = 0;
2297                            final int N = mProcessCpuTracker.countStats();
2298                            for (int i=0; i<N; i++) {
2299                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2300                                if (!st.working) {
2301                                    continue;
2302                                }
2303                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2304                                int otherUTime = (st.rel_utime*perc)/100;
2305                                int otherSTime = (st.rel_stime*perc)/100;
2306                                totalUTime += otherUTime;
2307                                totalSTime += otherSTime;
2308                                if (pr != null) {
2309                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2312                                                pr.info.uid, pr.processName);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2318                                } else {
2319                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2320                                    if (ps == null || !ps.isActive()) {
2321                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2322                                                bstats.mapUid(st.uid), st.name);
2323                                    }
2324                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2325                                            st.rel_stime-otherSTime);
2326                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2327                                }
2328                            }
2329                            bstats.finishAddingCpuLocked(perc, totalUTime,
2330                                    totalSTime, cpuSpeedTimes);
2331                        }
2332                    }
2333                }
2334
2335                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2336                    mLastWriteTime = now;
2337                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2338                }
2339            }
2340        }
2341    }
2342
2343    @Override
2344    public void batteryNeedsCpuUpdate() {
2345        updateCpuStatsNow();
2346    }
2347
2348    @Override
2349    public void batteryPowerChanged(boolean onBattery) {
2350        // When plugging in, update the CPU stats first before changing
2351        // the plug state.
2352        updateCpuStatsNow();
2353        synchronized (this) {
2354            synchronized(mPidsSelfLocked) {
2355                mOnBattery = DEBUG_POWER ? true : onBattery;
2356            }
2357        }
2358    }
2359
2360    /**
2361     * Initialize the application bind args. These are passed to each
2362     * process when the bindApplication() IPC is sent to the process. They're
2363     * lazily setup to make sure the services are running when they're asked for.
2364     */
2365    private HashMap<String, IBinder> getCommonServicesLocked() {
2366        if (mAppBindArgs == null) {
2367            mAppBindArgs = new HashMap<String, IBinder>();
2368
2369            // Setup the application init args
2370            mAppBindArgs.put("package", ServiceManager.getService("package"));
2371            mAppBindArgs.put("window", ServiceManager.getService("window"));
2372            mAppBindArgs.put(Context.ALARM_SERVICE,
2373                    ServiceManager.getService(Context.ALARM_SERVICE));
2374        }
2375        return mAppBindArgs;
2376    }
2377
2378    final void setFocusedActivityLocked(ActivityRecord r) {
2379        if (mFocusedActivity != r) {
2380            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2381            mFocusedActivity = r;
2382            if (r.task != null && r.task.voiceInteractor != null) {
2383                startRunningVoiceLocked();
2384            } else {
2385                finishRunningVoiceLocked();
2386            }
2387            mStackSupervisor.setFocusedStack(r);
2388            if (r != null) {
2389                mWindowManager.setFocusedApp(r.appToken, true);
2390            }
2391            applyUpdateLockStateLocked(r);
2392        }
2393    }
2394
2395    final void clearFocusedActivity(ActivityRecord r) {
2396        if (mFocusedActivity == r) {
2397            mFocusedActivity = null;
2398        }
2399    }
2400
2401    @Override
2402    public void setFocusedStack(int stackId) {
2403        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2404        synchronized (ActivityManagerService.this) {
2405            ActivityStack stack = mStackSupervisor.getStack(stackId);
2406            if (stack != null) {
2407                ActivityRecord r = stack.topRunningActivityLocked(null);
2408                if (r != null) {
2409                    setFocusedActivityLocked(r);
2410                }
2411            }
2412        }
2413    }
2414
2415    @Override
2416    public void notifyActivityDrawn(IBinder token) {
2417        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2418        synchronized (this) {
2419            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2420            if (r != null) {
2421                r.task.stack.notifyActivityDrawnLocked(r);
2422            }
2423        }
2424    }
2425
2426    final void applyUpdateLockStateLocked(ActivityRecord r) {
2427        // Modifications to the UpdateLock state are done on our handler, outside
2428        // the activity manager's locks.  The new state is determined based on the
2429        // state *now* of the relevant activity record.  The object is passed to
2430        // the handler solely for logging detail, not to be consulted/modified.
2431        final boolean nextState = r != null && r.immersive;
2432        mHandler.sendMessage(
2433                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2434    }
2435
2436    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2437        Message msg = Message.obtain();
2438        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2439        msg.obj = r.task.askedCompatMode ? null : r;
2440        mHandler.sendMessage(msg);
2441    }
2442
2443    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2444            String what, Object obj, ProcessRecord srcApp) {
2445        app.lastActivityTime = now;
2446
2447        if (app.activities.size() > 0) {
2448            // Don't want to touch dependent processes that are hosting activities.
2449            return index;
2450        }
2451
2452        int lrui = mLruProcesses.lastIndexOf(app);
2453        if (lrui < 0) {
2454            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2455                    + what + " " + obj + " from " + srcApp);
2456            return index;
2457        }
2458
2459        if (lrui >= index) {
2460            // Don't want to cause this to move dependent processes *back* in the
2461            // list as if they were less frequently used.
2462            return index;
2463        }
2464
2465        if (lrui >= mLruProcessActivityStart) {
2466            // Don't want to touch dependent processes that are hosting activities.
2467            return index;
2468        }
2469
2470        mLruProcesses.remove(lrui);
2471        if (index > 0) {
2472            index--;
2473        }
2474        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2475                + " in LRU list: " + app);
2476        mLruProcesses.add(index, app);
2477        return index;
2478    }
2479
2480    final void removeLruProcessLocked(ProcessRecord app) {
2481        int lrui = mLruProcesses.lastIndexOf(app);
2482        if (lrui >= 0) {
2483            if (lrui <= mLruProcessActivityStart) {
2484                mLruProcessActivityStart--;
2485            }
2486            if (lrui <= mLruProcessServiceStart) {
2487                mLruProcessServiceStart--;
2488            }
2489            mLruProcesses.remove(lrui);
2490        }
2491    }
2492
2493    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2494            ProcessRecord client) {
2495        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2496                || app.treatLikeActivity;
2497        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2498        if (!activityChange && hasActivity) {
2499            // The process has activities, so we are only allowing activity-based adjustments
2500            // to move it.  It should be kept in the front of the list with other
2501            // processes that have activities, and we don't want those to change their
2502            // order except due to activity operations.
2503            return;
2504        }
2505
2506        mLruSeq++;
2507        final long now = SystemClock.uptimeMillis();
2508        app.lastActivityTime = now;
2509
2510        // First a quick reject: if the app is already at the position we will
2511        // put it, then there is nothing to do.
2512        if (hasActivity) {
2513            final int N = mLruProcesses.size();
2514            if (N > 0 && mLruProcesses.get(N-1) == app) {
2515                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2516                return;
2517            }
2518        } else {
2519            if (mLruProcessServiceStart > 0
2520                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2521                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2522                return;
2523            }
2524        }
2525
2526        int lrui = mLruProcesses.lastIndexOf(app);
2527
2528        if (app.persistent && lrui >= 0) {
2529            // We don't care about the position of persistent processes, as long as
2530            // they are in the list.
2531            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2532            return;
2533        }
2534
2535        /* In progress: compute new position first, so we can avoid doing work
2536           if the process is not actually going to move.  Not yet working.
2537        int addIndex;
2538        int nextIndex;
2539        boolean inActivity = false, inService = false;
2540        if (hasActivity) {
2541            // Process has activities, put it at the very tipsy-top.
2542            addIndex = mLruProcesses.size();
2543            nextIndex = mLruProcessServiceStart;
2544            inActivity = true;
2545        } else if (hasService) {
2546            // Process has services, put it at the top of the service list.
2547            addIndex = mLruProcessActivityStart;
2548            nextIndex = mLruProcessServiceStart;
2549            inActivity = true;
2550            inService = true;
2551        } else  {
2552            // Process not otherwise of interest, it goes to the top of the non-service area.
2553            addIndex = mLruProcessServiceStart;
2554            if (client != null) {
2555                int clientIndex = mLruProcesses.lastIndexOf(client);
2556                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2557                        + app);
2558                if (clientIndex >= 0 && addIndex > clientIndex) {
2559                    addIndex = clientIndex;
2560                }
2561            }
2562            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2563        }
2564
2565        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2566                + mLruProcessActivityStart + "): " + app);
2567        */
2568
2569        if (lrui >= 0) {
2570            if (lrui < mLruProcessActivityStart) {
2571                mLruProcessActivityStart--;
2572            }
2573            if (lrui < mLruProcessServiceStart) {
2574                mLruProcessServiceStart--;
2575            }
2576            /*
2577            if (addIndex > lrui) {
2578                addIndex--;
2579            }
2580            if (nextIndex > lrui) {
2581                nextIndex--;
2582            }
2583            */
2584            mLruProcesses.remove(lrui);
2585        }
2586
2587        /*
2588        mLruProcesses.add(addIndex, app);
2589        if (inActivity) {
2590            mLruProcessActivityStart++;
2591        }
2592        if (inService) {
2593            mLruProcessActivityStart++;
2594        }
2595        */
2596
2597        int nextIndex;
2598        if (hasActivity) {
2599            final int N = mLruProcesses.size();
2600            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2601                // Process doesn't have activities, but has clients with
2602                // activities...  move it up, but one below the top (the top
2603                // should always have a real activity).
2604                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2605                mLruProcesses.add(N-1, app);
2606                // To keep it from spamming the LRU list (by making a bunch of clients),
2607                // we will push down any other entries owned by the app.
2608                final int uid = app.info.uid;
2609                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2610                    ProcessRecord subProc = mLruProcesses.get(i);
2611                    if (subProc.info.uid == uid) {
2612                        // We want to push this one down the list.  If the process after
2613                        // it is for the same uid, however, don't do so, because we don't
2614                        // want them internally to be re-ordered.
2615                        if (mLruProcesses.get(i-1).info.uid != uid) {
2616                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2617                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2618                            ProcessRecord tmp = mLruProcesses.get(i);
2619                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2620                            mLruProcesses.set(i-1, tmp);
2621                            i--;
2622                        }
2623                    } else {
2624                        // A gap, we can stop here.
2625                        break;
2626                    }
2627                }
2628            } else {
2629                // Process has activities, put it at the very tipsy-top.
2630                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2631                mLruProcesses.add(app);
2632            }
2633            nextIndex = mLruProcessServiceStart;
2634        } else if (hasService) {
2635            // Process has services, put it at the top of the service list.
2636            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2637            mLruProcesses.add(mLruProcessActivityStart, app);
2638            nextIndex = mLruProcessServiceStart;
2639            mLruProcessActivityStart++;
2640        } else  {
2641            // Process not otherwise of interest, it goes to the top of the non-service area.
2642            int index = mLruProcessServiceStart;
2643            if (client != null) {
2644                // If there is a client, don't allow the process to be moved up higher
2645                // in the list than that client.
2646                int clientIndex = mLruProcesses.lastIndexOf(client);
2647                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2648                        + " when updating " + app);
2649                if (clientIndex <= lrui) {
2650                    // Don't allow the client index restriction to push it down farther in the
2651                    // list than it already is.
2652                    clientIndex = lrui;
2653                }
2654                if (clientIndex >= 0 && index > clientIndex) {
2655                    index = clientIndex;
2656                }
2657            }
2658            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2659            mLruProcesses.add(index, app);
2660            nextIndex = index-1;
2661            mLruProcessActivityStart++;
2662            mLruProcessServiceStart++;
2663        }
2664
2665        // If the app is currently using a content provider or service,
2666        // bump those processes as well.
2667        for (int j=app.connections.size()-1; j>=0; j--) {
2668            ConnectionRecord cr = app.connections.valueAt(j);
2669            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2670                    && cr.binding.service.app != null
2671                    && cr.binding.service.app.lruSeq != mLruSeq
2672                    && !cr.binding.service.app.persistent) {
2673                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2674                        "service connection", cr, app);
2675            }
2676        }
2677        for (int j=app.conProviders.size()-1; j>=0; j--) {
2678            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2679            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2680                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2681                        "provider reference", cpr, app);
2682            }
2683        }
2684    }
2685
2686    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2687        if (uid == Process.SYSTEM_UID) {
2688            // The system gets to run in any process.  If there are multiple
2689            // processes with the same uid, just pick the first (this
2690            // should never happen).
2691            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2692            if (procs == null) return null;
2693            final int N = procs.size();
2694            for (int i = 0; i < N; i++) {
2695                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2696            }
2697        }
2698        ProcessRecord proc = mProcessNames.get(processName, uid);
2699        if (false && proc != null && !keepIfLarge
2700                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2701                && proc.lastCachedPss >= 4000) {
2702            // Turn this condition on to cause killing to happen regularly, for testing.
2703            if (proc.baseProcessTracker != null) {
2704                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2705            }
2706            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2707                    + "k from cached");
2708        } else if (proc != null && !keepIfLarge
2709                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2710                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2711            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2712            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2713                if (proc.baseProcessTracker != null) {
2714                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2715                }
2716                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2717                        + "k from cached");
2718            }
2719        }
2720        return proc;
2721    }
2722
2723    void ensurePackageDexOpt(String packageName) {
2724        IPackageManager pm = AppGlobals.getPackageManager();
2725        try {
2726            if (pm.performDexOpt(packageName)) {
2727                mDidDexOpt = true;
2728            }
2729        } catch (RemoteException e) {
2730        }
2731    }
2732
2733    boolean isNextTransitionForward() {
2734        int transit = mWindowManager.getPendingAppTransition();
2735        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_OPEN
2737                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2738    }
2739
2740    final ProcessRecord startProcessLocked(String processName,
2741            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2742            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2743            boolean isolated, boolean keepIfLarge) {
2744        ProcessRecord app;
2745        if (!isolated) {
2746            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2747        } else {
2748            // If this is an isolated process, it can't re-use an existing process.
2749            app = null;
2750        }
2751        // We don't have to do anything more if:
2752        // (1) There is an existing application record; and
2753        // (2) The caller doesn't think it is dead, OR there is no thread
2754        //     object attached to it so we know it couldn't have crashed; and
2755        // (3) There is a pid assigned to it, so it is either starting or
2756        //     already running.
2757        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2758                + " app=" + app + " knownToBeDead=" + knownToBeDead
2759                + " thread=" + (app != null ? app.thread : null)
2760                + " pid=" + (app != null ? app.pid : -1));
2761        if (app != null && app.pid > 0) {
2762            if (!knownToBeDead || app.thread == null) {
2763                // We already have the app running, or are waiting for it to
2764                // come up (we have a pid but not yet its thread), so keep it.
2765                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2766                // If this is a new package in the process, add the package to the list
2767                app.addPackage(info.packageName, mProcessStats);
2768                return app;
2769            }
2770
2771            // An application record is attached to a previous process,
2772            // clean it up now.
2773            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2774            handleAppDiedLocked(app, true, true);
2775        }
2776
2777        String hostingNameStr = hostingName != null
2778                ? hostingName.flattenToShortString() : null;
2779
2780        if (!isolated) {
2781            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2782                // If we are in the background, then check to see if this process
2783                // is bad.  If so, we will just silently fail.
2784                if (mBadProcesses.get(info.processName, info.uid) != null) {
2785                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2786                            + "/" + info.processName);
2787                    return null;
2788                }
2789            } else {
2790                // When the user is explicitly starting a process, then clear its
2791                // crash count so that we won't make it bad until they see at
2792                // least one crash dialog again, and make the process good again
2793                // if it had been bad.
2794                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2795                        + "/" + info.processName);
2796                mProcessCrashTimes.remove(info.processName, info.uid);
2797                if (mBadProcesses.get(info.processName, info.uid) != null) {
2798                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2799                            UserHandle.getUserId(info.uid), info.uid,
2800                            info.processName);
2801                    mBadProcesses.remove(info.processName, info.uid);
2802                    if (app != null) {
2803                        app.bad = false;
2804                    }
2805                }
2806            }
2807        }
2808
2809        if (app == null) {
2810            app = newProcessRecordLocked(info, processName, isolated);
2811            if (app == null) {
2812                Slog.w(TAG, "Failed making new process record for "
2813                        + processName + "/" + info.uid + " isolated=" + isolated);
2814                return null;
2815            }
2816            mProcessNames.put(processName, app.uid, app);
2817            if (isolated) {
2818                mIsolatedProcesses.put(app.uid, app);
2819            }
2820        } else {
2821            // If this is a new package in the process, add the package to the list
2822            app.addPackage(info.packageName, mProcessStats);
2823        }
2824
2825        // If the system is not ready yet, then hold off on starting this
2826        // process until it is.
2827        if (!mProcessesReady
2828                && !isAllowedWhileBooting(info)
2829                && !allowWhileBooting) {
2830            if (!mProcessesOnHold.contains(app)) {
2831                mProcessesOnHold.add(app);
2832            }
2833            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2834            return app;
2835        }
2836
2837        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2838        return (app.pid != 0) ? app : null;
2839    }
2840
2841    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2842        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2843    }
2844
2845    private final void startProcessLocked(ProcessRecord app,
2846            String hostingType, String hostingNameStr, String abiOverride) {
2847        if (app.pid > 0 && app.pid != MY_PID) {
2848            synchronized (mPidsSelfLocked) {
2849                mPidsSelfLocked.remove(app.pid);
2850                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2851            }
2852            app.setPid(0);
2853        }
2854
2855        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2856                "startProcessLocked removing on hold: " + app);
2857        mProcessesOnHold.remove(app);
2858
2859        updateCpuStats();
2860
2861        try {
2862            int uid = app.uid;
2863
2864            int[] gids = null;
2865            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2866            if (!app.isolated) {
2867                int[] permGids = null;
2868                try {
2869                    final PackageManager pm = mContext.getPackageManager();
2870                    permGids = pm.getPackageGids(app.info.packageName);
2871
2872                    if (Environment.isExternalStorageEmulated()) {
2873                        if (pm.checkPermission(
2874                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2875                                app.info.packageName) == PERMISSION_GRANTED) {
2876                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2877                        } else {
2878                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2879                        }
2880                    }
2881                } catch (PackageManager.NameNotFoundException e) {
2882                    Slog.w(TAG, "Unable to retrieve gids", e);
2883                }
2884
2885                /*
2886                 * Add shared application and profile GIDs so applications can share some
2887                 * resources like shared libraries and access user-wide resources
2888                 */
2889                if (permGids == null) {
2890                    gids = new int[2];
2891                } else {
2892                    gids = new int[permGids.length + 2];
2893                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2894                }
2895                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2896                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2897            }
2898            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2899                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2900                        && mTopComponent != null
2901                        && app.processName.equals(mTopComponent.getPackageName())) {
2902                    uid = 0;
2903                }
2904                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2905                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2906                    uid = 0;
2907                }
2908            }
2909            int debugFlags = 0;
2910            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2911                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2912                // Also turn on CheckJNI for debuggable apps. It's quite
2913                // awkward to turn on otherwise.
2914                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2915            }
2916            // Run the app in safe mode if its manifest requests so or the
2917            // system is booted in safe mode.
2918            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2919                mSafeMode == true) {
2920                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2921            }
2922            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2923                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2924            }
2925            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2926                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2927            }
2928            if ("1".equals(SystemProperties.get("debug.assert"))) {
2929                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2930            }
2931
2932            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2933            if (requiredAbi == null) {
2934                requiredAbi = Build.SUPPORTED_ABIS[0];
2935            }
2936
2937            // Start the process.  It will either succeed and return a result containing
2938            // the PID of the new process, or else throw a RuntimeException.
2939            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2940                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2941                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2942
2943            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2944            synchronized (bs) {
2945                if (bs.isOnBattery()) {
2946                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2947                }
2948            }
2949
2950            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2951                    UserHandle.getUserId(uid), startResult.pid, uid,
2952                    app.processName, hostingType,
2953                    hostingNameStr != null ? hostingNameStr : "");
2954
2955            if (app.persistent) {
2956                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2957            }
2958
2959            StringBuilder buf = mStringBuilder;
2960            buf.setLength(0);
2961            buf.append("Start proc ");
2962            buf.append(app.processName);
2963            buf.append(" for ");
2964            buf.append(hostingType);
2965            if (hostingNameStr != null) {
2966                buf.append(" ");
2967                buf.append(hostingNameStr);
2968            }
2969            buf.append(": pid=");
2970            buf.append(startResult.pid);
2971            buf.append(" uid=");
2972            buf.append(uid);
2973            buf.append(" gids={");
2974            if (gids != null) {
2975                for (int gi=0; gi<gids.length; gi++) {
2976                    if (gi != 0) buf.append(", ");
2977                    buf.append(gids[gi]);
2978
2979                }
2980            }
2981            buf.append("}");
2982            if (requiredAbi != null) {
2983                buf.append(" abi=");
2984                buf.append(requiredAbi);
2985            }
2986            Slog.i(TAG, buf.toString());
2987            app.setPid(startResult.pid);
2988            app.usingWrapper = startResult.usingWrapper;
2989            app.removed = false;
2990            synchronized (mPidsSelfLocked) {
2991                this.mPidsSelfLocked.put(startResult.pid, app);
2992                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2993                msg.obj = app;
2994                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2995                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2996            }
2997            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2998                    app.processName, app.info.uid);
2999            if (app.isolated) {
3000                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3001            }
3002        } catch (RuntimeException e) {
3003            // XXX do better error recovery.
3004            app.setPid(0);
3005            Slog.e(TAG, "Failure starting process " + app.processName, e);
3006        }
3007    }
3008
3009    void updateUsageStats(ActivityRecord component, boolean resumed) {
3010        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3011        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3012        if (resumed) {
3013            mUsageStatsService.noteResumeComponent(component.realActivity);
3014            synchronized (stats) {
3015                stats.noteActivityResumedLocked(component.app.uid);
3016            }
3017        } else {
3018            mUsageStatsService.notePauseComponent(component.realActivity);
3019            synchronized (stats) {
3020                stats.noteActivityPausedLocked(component.app.uid);
3021            }
3022        }
3023    }
3024
3025    Intent getHomeIntent() {
3026        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3027        intent.setComponent(mTopComponent);
3028        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3029            intent.addCategory(Intent.CATEGORY_HOME);
3030        }
3031        return intent;
3032    }
3033
3034    boolean startHomeActivityLocked(int userId) {
3035        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3036                && mTopAction == null) {
3037            // We are running in factory test mode, but unable to find
3038            // the factory test app, so just sit around displaying the
3039            // error message and don't try to start anything.
3040            return false;
3041        }
3042        Intent intent = getHomeIntent();
3043        ActivityInfo aInfo =
3044            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3045        if (aInfo != null) {
3046            intent.setComponent(new ComponentName(
3047                    aInfo.applicationInfo.packageName, aInfo.name));
3048            // Don't do this if the home app is currently being
3049            // instrumented.
3050            aInfo = new ActivityInfo(aInfo);
3051            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3052            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3053                    aInfo.applicationInfo.uid, true);
3054            if (app == null || app.instrumentationClass == null) {
3055                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3056                mStackSupervisor.startHomeActivity(intent, aInfo);
3057            }
3058        }
3059
3060        return true;
3061    }
3062
3063    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3064        ActivityInfo ai = null;
3065        ComponentName comp = intent.getComponent();
3066        try {
3067            if (comp != null) {
3068                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3069            } else {
3070                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3071                        intent,
3072                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3073                            flags, userId);
3074
3075                if (info != null) {
3076                    ai = info.activityInfo;
3077                }
3078            }
3079        } catch (RemoteException e) {
3080            // ignore
3081        }
3082
3083        return ai;
3084    }
3085
3086    /**
3087     * Starts the "new version setup screen" if appropriate.
3088     */
3089    void startSetupActivityLocked() {
3090        // Only do this once per boot.
3091        if (mCheckedForSetup) {
3092            return;
3093        }
3094
3095        // We will show this screen if the current one is a different
3096        // version than the last one shown, and we are not running in
3097        // low-level factory test mode.
3098        final ContentResolver resolver = mContext.getContentResolver();
3099        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3100                Settings.Global.getInt(resolver,
3101                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3102            mCheckedForSetup = true;
3103
3104            // See if we should be showing the platform update setup UI.
3105            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3106            List<ResolveInfo> ris = mContext.getPackageManager()
3107                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3108
3109            // We don't allow third party apps to replace this.
3110            ResolveInfo ri = null;
3111            for (int i=0; ris != null && i<ris.size(); i++) {
3112                if ((ris.get(i).activityInfo.applicationInfo.flags
3113                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3114                    ri = ris.get(i);
3115                    break;
3116                }
3117            }
3118
3119            if (ri != null) {
3120                String vers = ri.activityInfo.metaData != null
3121                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3122                        : null;
3123                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3124                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3125                            Intent.METADATA_SETUP_VERSION);
3126                }
3127                String lastVers = Settings.Secure.getString(
3128                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3129                if (vers != null && !vers.equals(lastVers)) {
3130                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3131                    intent.setComponent(new ComponentName(
3132                            ri.activityInfo.packageName, ri.activityInfo.name));
3133                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3134                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3135                }
3136            }
3137        }
3138    }
3139
3140    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3141        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3142    }
3143
3144    void enforceNotIsolatedCaller(String caller) {
3145        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3146            throw new SecurityException("Isolated process not allowed to call " + caller);
3147        }
3148    }
3149
3150    @Override
3151    public int getFrontActivityScreenCompatMode() {
3152        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3153        synchronized (this) {
3154            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3155        }
3156    }
3157
3158    @Override
3159    public void setFrontActivityScreenCompatMode(int mode) {
3160        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3161                "setFrontActivityScreenCompatMode");
3162        synchronized (this) {
3163            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3164        }
3165    }
3166
3167    @Override
3168    public int getPackageScreenCompatMode(String packageName) {
3169        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3170        synchronized (this) {
3171            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3172        }
3173    }
3174
3175    @Override
3176    public void setPackageScreenCompatMode(String packageName, int mode) {
3177        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3178                "setPackageScreenCompatMode");
3179        synchronized (this) {
3180            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3181        }
3182    }
3183
3184    @Override
3185    public boolean getPackageAskScreenCompat(String packageName) {
3186        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3187        synchronized (this) {
3188            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3189        }
3190    }
3191
3192    @Override
3193    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3194        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3195                "setPackageAskScreenCompat");
3196        synchronized (this) {
3197            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3198        }
3199    }
3200
3201    private void dispatchProcessesChanged() {
3202        int N;
3203        synchronized (this) {
3204            N = mPendingProcessChanges.size();
3205            if (mActiveProcessChanges.length < N) {
3206                mActiveProcessChanges = new ProcessChangeItem[N];
3207            }
3208            mPendingProcessChanges.toArray(mActiveProcessChanges);
3209            mAvailProcessChanges.addAll(mPendingProcessChanges);
3210            mPendingProcessChanges.clear();
3211            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3212        }
3213
3214        int i = mProcessObservers.beginBroadcast();
3215        while (i > 0) {
3216            i--;
3217            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3218            if (observer != null) {
3219                try {
3220                    for (int j=0; j<N; j++) {
3221                        ProcessChangeItem item = mActiveProcessChanges[j];
3222                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3223                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3224                                    + item.pid + " uid=" + item.uid + ": "
3225                                    + item.foregroundActivities);
3226                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3227                                    item.foregroundActivities);
3228                        }
3229                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3230                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3231                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3232                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3233                        }
3234                    }
3235                } catch (RemoteException e) {
3236                }
3237            }
3238        }
3239        mProcessObservers.finishBroadcast();
3240    }
3241
3242    private void dispatchProcessDied(int pid, int uid) {
3243        int i = mProcessObservers.beginBroadcast();
3244        while (i > 0) {
3245            i--;
3246            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3247            if (observer != null) {
3248                try {
3249                    observer.onProcessDied(pid, uid);
3250                } catch (RemoteException e) {
3251                }
3252            }
3253        }
3254        mProcessObservers.finishBroadcast();
3255    }
3256
3257    final void doPendingActivityLaunchesLocked(boolean doResume) {
3258        final int N = mPendingActivityLaunches.size();
3259        if (N <= 0) {
3260            return;
3261        }
3262        for (int i=0; i<N; i++) {
3263            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3264            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3265                    doResume && i == (N-1), null);
3266        }
3267        mPendingActivityLaunches.clear();
3268    }
3269
3270    @Override
3271    public final int startActivity(IApplicationThread caller, String callingPackage,
3272            Intent intent, String resolvedType, IBinder resultTo,
3273            String resultWho, int requestCode, int startFlags,
3274            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3275        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3276                resultWho, requestCode,
3277                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3278    }
3279
3280    @Override
3281    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3282            Intent intent, String resolvedType, IBinder resultTo,
3283            String resultWho, int requestCode, int startFlags,
3284            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3285        enforceNotIsolatedCaller("startActivity");
3286        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3287                false, true, "startActivity", null);
3288        // TODO: Switch to user app stacks here.
3289        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3290                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3291                null, null, options, userId, null);
3292    }
3293
3294    @Override
3295    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3296            Intent intent, String resolvedType, IBinder resultTo,
3297            String resultWho, int requestCode, int startFlags, String profileFile,
3298            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3299        enforceNotIsolatedCaller("startActivityAndWait");
3300        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3301                false, true, "startActivityAndWait", null);
3302        WaitResult res = new WaitResult();
3303        // TODO: Switch to user app stacks here.
3304        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3305                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3306                res, null, options, UserHandle.getCallingUserId(), null);
3307        return res;
3308    }
3309
3310    @Override
3311    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3312            Intent intent, String resolvedType, IBinder resultTo,
3313            String resultWho, int requestCode, int startFlags, Configuration config,
3314            Bundle options, int userId) {
3315        enforceNotIsolatedCaller("startActivityWithConfig");
3316        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3317                false, true, "startActivityWithConfig", null);
3318        // TODO: Switch to user app stacks here.
3319        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3320                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3321                null, null, null, config, options, userId, null);
3322        return ret;
3323    }
3324
3325    @Override
3326    public int startActivityIntentSender(IApplicationThread caller,
3327            IntentSender intent, Intent fillInIntent, String resolvedType,
3328            IBinder resultTo, String resultWho, int requestCode,
3329            int flagsMask, int flagsValues, Bundle options) {
3330        enforceNotIsolatedCaller("startActivityIntentSender");
3331        // Refuse possible leaked file descriptors
3332        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3333            throw new IllegalArgumentException("File descriptors passed in Intent");
3334        }
3335
3336        IIntentSender sender = intent.getTarget();
3337        if (!(sender instanceof PendingIntentRecord)) {
3338            throw new IllegalArgumentException("Bad PendingIntent object");
3339        }
3340
3341        PendingIntentRecord pir = (PendingIntentRecord)sender;
3342
3343        synchronized (this) {
3344            // If this is coming from the currently resumed activity, it is
3345            // effectively saying that app switches are allowed at this point.
3346            final ActivityStack stack = getFocusedStack();
3347            if (stack.mResumedActivity != null &&
3348                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3349                mAppSwitchesAllowedTime = 0;
3350            }
3351        }
3352        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3353                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3354        return ret;
3355    }
3356
3357    @Override
3358    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3359            Intent intent, String resolvedType, IVoiceInteractionSession session,
3360            IVoiceInteractor interactor, int startFlags, String profileFile,
3361            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3362        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3363                != PackageManager.PERMISSION_GRANTED) {
3364            String msg = "Permission Denial: startVoiceActivity() from pid="
3365                    + Binder.getCallingPid()
3366                    + ", uid=" + Binder.getCallingUid()
3367                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3368            Slog.w(TAG, msg);
3369            throw new SecurityException(msg);
3370        }
3371        if (session == null || interactor == null) {
3372            throw new NullPointerException("null session or interactor");
3373        }
3374        userId = handleIncomingUser(callingPid, callingUid, userId,
3375                false, true, "startVoiceActivity", null);
3376        // TODO: Switch to user app stacks here.
3377        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3378                resolvedType, session, interactor, null, null, 0, startFlags,
3379                profileFile, profileFd, null, null, options, userId, null);
3380    }
3381
3382    @Override
3383    public boolean startNextMatchingActivity(IBinder callingActivity,
3384            Intent intent, Bundle options) {
3385        // Refuse possible leaked file descriptors
3386        if (intent != null && intent.hasFileDescriptors() == true) {
3387            throw new IllegalArgumentException("File descriptors passed in Intent");
3388        }
3389
3390        synchronized (this) {
3391            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3392            if (r == null) {
3393                ActivityOptions.abort(options);
3394                return false;
3395            }
3396            if (r.app == null || r.app.thread == null) {
3397                // The caller is not running...  d'oh!
3398                ActivityOptions.abort(options);
3399                return false;
3400            }
3401            intent = new Intent(intent);
3402            // The caller is not allowed to change the data.
3403            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3404            // And we are resetting to find the next component...
3405            intent.setComponent(null);
3406
3407            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3408
3409            ActivityInfo aInfo = null;
3410            try {
3411                List<ResolveInfo> resolves =
3412                    AppGlobals.getPackageManager().queryIntentActivities(
3413                            intent, r.resolvedType,
3414                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3415                            UserHandle.getCallingUserId());
3416
3417                // Look for the original activity in the list...
3418                final int N = resolves != null ? resolves.size() : 0;
3419                for (int i=0; i<N; i++) {
3420                    ResolveInfo rInfo = resolves.get(i);
3421                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3422                            && rInfo.activityInfo.name.equals(r.info.name)) {
3423                        // We found the current one...  the next matching is
3424                        // after it.
3425                        i++;
3426                        if (i<N) {
3427                            aInfo = resolves.get(i).activityInfo;
3428                        }
3429                        if (debug) {
3430                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3431                                    + "/" + r.info.name);
3432                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3433                                    + "/" + aInfo.name);
3434                        }
3435                        break;
3436                    }
3437                }
3438            } catch (RemoteException e) {
3439            }
3440
3441            if (aInfo == null) {
3442                // Nobody who is next!
3443                ActivityOptions.abort(options);
3444                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3445                return false;
3446            }
3447
3448            intent.setComponent(new ComponentName(
3449                    aInfo.applicationInfo.packageName, aInfo.name));
3450            intent.setFlags(intent.getFlags()&~(
3451                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3452                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3453                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3454                    Intent.FLAG_ACTIVITY_NEW_TASK));
3455
3456            // Okay now we need to start the new activity, replacing the
3457            // currently running activity.  This is a little tricky because
3458            // we want to start the new one as if the current one is finished,
3459            // but not finish the current one first so that there is no flicker.
3460            // And thus...
3461            final boolean wasFinishing = r.finishing;
3462            r.finishing = true;
3463
3464            // Propagate reply information over to the new activity.
3465            final ActivityRecord resultTo = r.resultTo;
3466            final String resultWho = r.resultWho;
3467            final int requestCode = r.requestCode;
3468            r.resultTo = null;
3469            if (resultTo != null) {
3470                resultTo.removeResultsLocked(r, resultWho, requestCode);
3471            }
3472
3473            final long origId = Binder.clearCallingIdentity();
3474            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3475                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3476                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3477                    options, false, null, null);
3478            Binder.restoreCallingIdentity(origId);
3479
3480            r.finishing = wasFinishing;
3481            if (res != ActivityManager.START_SUCCESS) {
3482                return false;
3483            }
3484            return true;
3485        }
3486    }
3487
3488    final int startActivityInPackage(int uid, String callingPackage,
3489            Intent intent, String resolvedType, IBinder resultTo,
3490            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3491                    IActivityContainer container) {
3492
3493        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3494                false, true, "startActivityInPackage", null);
3495
3496        // TODO: Switch to user app stacks here.
3497        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3498                null, null, resultTo, resultWho, requestCode, startFlags,
3499                null, null, null, null, options, userId, container);
3500        return ret;
3501    }
3502
3503    @Override
3504    public final int startActivities(IApplicationThread caller, String callingPackage,
3505            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3506            int userId) {
3507        enforceNotIsolatedCaller("startActivities");
3508        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3509                false, true, "startActivity", null);
3510        // TODO: Switch to user app stacks here.
3511        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3512                resolvedTypes, resultTo, options, userId);
3513        return ret;
3514    }
3515
3516    final int startActivitiesInPackage(int uid, String callingPackage,
3517            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3518            Bundle options, int userId) {
3519
3520        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3521                false, true, "startActivityInPackage", null);
3522        // TODO: Switch to user app stacks here.
3523        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3524                resultTo, options, userId);
3525        return ret;
3526    }
3527
3528    final void addRecentTaskLocked(TaskRecord task) {
3529        int N = mRecentTasks.size();
3530        // Quick case: check if the top-most recent task is the same.
3531        if (N > 0 && mRecentTasks.get(0) == task) {
3532            return;
3533        }
3534        // Another quick case: never add voice sessions.
3535        if (task.voiceSession != null) {
3536            return;
3537        }
3538        // Remove any existing entries that are the same kind of task.
3539        final Intent intent = task.intent;
3540        final boolean document = intent != null && intent.isDocument();
3541        final ComponentName comp = intent.getComponent();
3542
3543        int maxRecents = task.maxRecents - 1;
3544        for (int i=0; i<N; i++) {
3545            TaskRecord tr = mRecentTasks.get(i);
3546            if (task != tr) {
3547                if (task.userId != tr.userId) {
3548                    continue;
3549                }
3550                final Intent trIntent = tr.intent;
3551                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3552                    (intent == null || !intent.filterEquals(trIntent))) {
3553                    continue;
3554                }
3555                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3556                if (document && trIsDocument) {
3557                    // These are the same document activity (not necessarily the same doc).
3558                    if (maxRecents > 0) {
3559                        --maxRecents;
3560                        continue;
3561                    }
3562                    // Hit the maximum number of documents for this task. Fall through
3563                    // and remove this document from recents.
3564                } else if (document || trIsDocument) {
3565                    // Only one of these is a document. Not the droid we're looking for.
3566                    continue;
3567                }
3568            }
3569
3570            // Either task and tr are the same or, their affinities match or their intents match
3571            // and neither of them is a document, or they are documents using the same activity
3572            // and their maxRecents has been reached.
3573            tr.disposeThumbnail();
3574            mRecentTasks.remove(i);
3575            i--;
3576            N--;
3577            if (task.intent == null) {
3578                // If the new recent task we are adding is not fully
3579                // specified, then replace it with the existing recent task.
3580                task = tr;
3581            }
3582            mTaskPersister.notify(tr, false);
3583        }
3584        if (N >= MAX_RECENT_TASKS) {
3585            mRecentTasks.remove(N-1).disposeThumbnail();
3586        }
3587        mRecentTasks.add(0, task);
3588    }
3589
3590    @Override
3591    public void reportActivityFullyDrawn(IBinder token) {
3592        synchronized (this) {
3593            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3594            if (r == null) {
3595                return;
3596            }
3597            r.reportFullyDrawnLocked();
3598        }
3599    }
3600
3601    @Override
3602    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3603        synchronized (this) {
3604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3605            if (r == null) {
3606                return;
3607            }
3608            final long origId = Binder.clearCallingIdentity();
3609            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3610            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3611                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3612            if (config != null) {
3613                r.frozenBeforeDestroy = true;
3614                if (!updateConfigurationLocked(config, r, false, false)) {
3615                    mStackSupervisor.resumeTopActivitiesLocked();
3616                }
3617            }
3618            Binder.restoreCallingIdentity(origId);
3619        }
3620    }
3621
3622    @Override
3623    public int getRequestedOrientation(IBinder token) {
3624        synchronized (this) {
3625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3626            if (r == null) {
3627                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3628            }
3629            return mWindowManager.getAppOrientation(r.appToken);
3630        }
3631    }
3632
3633    /**
3634     * This is the internal entry point for handling Activity.finish().
3635     *
3636     * @param token The Binder token referencing the Activity we want to finish.
3637     * @param resultCode Result code, if any, from this Activity.
3638     * @param resultData Result data (Intent), if any, from this Activity.
3639     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3640     *            the root Activity in the task.
3641     *
3642     * @return Returns true if the activity successfully finished, or false if it is still running.
3643     */
3644    @Override
3645    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3646            boolean finishTask) {
3647        // Refuse possible leaked file descriptors
3648        if (resultData != null && resultData.hasFileDescriptors() == true) {
3649            throw new IllegalArgumentException("File descriptors passed in Intent");
3650        }
3651
3652        synchronized(this) {
3653            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3654            if (r == null) {
3655                return true;
3656            }
3657            // Keep track of the root activity of the task before we finish it
3658            TaskRecord tr = r.task;
3659            ActivityRecord rootR = tr.getRootActivity();
3660            if (mController != null) {
3661                // Find the first activity that is not finishing.
3662                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3663                if (next != null) {
3664                    // ask watcher if this is allowed
3665                    boolean resumeOK = true;
3666                    try {
3667                        resumeOK = mController.activityResuming(next.packageName);
3668                    } catch (RemoteException e) {
3669                        mController = null;
3670                        Watchdog.getInstance().setActivityController(null);
3671                    }
3672
3673                    if (!resumeOK) {
3674                        return false;
3675                    }
3676                }
3677            }
3678            final long origId = Binder.clearCallingIdentity();
3679            try {
3680                boolean res;
3681                if (finishTask && r == rootR) {
3682                    // If requested, remove the task that is associated to this activity only if it
3683                    // was the root activity in the task.  The result code and data is ignored because
3684                    // we don't support returning them across task boundaries.
3685                    res = removeTaskByIdLocked(tr.taskId, 0);
3686                } else {
3687                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3688                            resultData, "app-request", true);
3689                }
3690                return res;
3691            } finally {
3692                Binder.restoreCallingIdentity(origId);
3693            }
3694        }
3695    }
3696
3697    @Override
3698    public final void finishHeavyWeightApp() {
3699        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3700                != PackageManager.PERMISSION_GRANTED) {
3701            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3702                    + Binder.getCallingPid()
3703                    + ", uid=" + Binder.getCallingUid()
3704                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3705            Slog.w(TAG, msg);
3706            throw new SecurityException(msg);
3707        }
3708
3709        synchronized(this) {
3710            if (mHeavyWeightProcess == null) {
3711                return;
3712            }
3713
3714            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3715                    mHeavyWeightProcess.activities);
3716            for (int i=0; i<activities.size(); i++) {
3717                ActivityRecord r = activities.get(i);
3718                if (!r.finishing) {
3719                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3720                            null, "finish-heavy", true);
3721                }
3722            }
3723
3724            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3725                    mHeavyWeightProcess.userId, 0));
3726            mHeavyWeightProcess = null;
3727        }
3728    }
3729
3730    @Override
3731    public void crashApplication(int uid, int initialPid, String packageName,
3732            String message) {
3733        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3734                != PackageManager.PERMISSION_GRANTED) {
3735            String msg = "Permission Denial: crashApplication() from pid="
3736                    + Binder.getCallingPid()
3737                    + ", uid=" + Binder.getCallingUid()
3738                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3739            Slog.w(TAG, msg);
3740            throw new SecurityException(msg);
3741        }
3742
3743        synchronized(this) {
3744            ProcessRecord proc = null;
3745
3746            // Figure out which process to kill.  We don't trust that initialPid
3747            // still has any relation to current pids, so must scan through the
3748            // list.
3749            synchronized (mPidsSelfLocked) {
3750                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3751                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3752                    if (p.uid != uid) {
3753                        continue;
3754                    }
3755                    if (p.pid == initialPid) {
3756                        proc = p;
3757                        break;
3758                    }
3759                    if (p.pkgList.containsKey(packageName)) {
3760                        proc = p;
3761                    }
3762                }
3763            }
3764
3765            if (proc == null) {
3766                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3767                        + " initialPid=" + initialPid
3768                        + " packageName=" + packageName);
3769                return;
3770            }
3771
3772            if (proc.thread != null) {
3773                if (proc.pid == Process.myPid()) {
3774                    Log.w(TAG, "crashApplication: trying to crash self!");
3775                    return;
3776                }
3777                long ident = Binder.clearCallingIdentity();
3778                try {
3779                    proc.thread.scheduleCrash(message);
3780                } catch (RemoteException e) {
3781                }
3782                Binder.restoreCallingIdentity(ident);
3783            }
3784        }
3785    }
3786
3787    @Override
3788    public final void finishSubActivity(IBinder token, String resultWho,
3789            int requestCode) {
3790        synchronized(this) {
3791            final long origId = Binder.clearCallingIdentity();
3792            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3793            if (r != null) {
3794                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3795            }
3796            Binder.restoreCallingIdentity(origId);
3797        }
3798    }
3799
3800    @Override
3801    public boolean finishActivityAffinity(IBinder token) {
3802        synchronized(this) {
3803            final long origId = Binder.clearCallingIdentity();
3804            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3805            boolean res = false;
3806            if (r != null) {
3807                res = r.task.stack.finishActivityAffinityLocked(r);
3808            }
3809            Binder.restoreCallingIdentity(origId);
3810            return res;
3811        }
3812    }
3813
3814    @Override
3815    public boolean willActivityBeVisible(IBinder token) {
3816        synchronized(this) {
3817            ActivityStack stack = ActivityRecord.getStackLocked(token);
3818            if (stack != null) {
3819                return stack.willActivityBeVisibleLocked(token);
3820            }
3821            return false;
3822        }
3823    }
3824
3825    @Override
3826    public void overridePendingTransition(IBinder token, String packageName,
3827            int enterAnim, int exitAnim) {
3828        synchronized(this) {
3829            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3830            if (self == null) {
3831                return;
3832            }
3833
3834            final long origId = Binder.clearCallingIdentity();
3835
3836            if (self.state == ActivityState.RESUMED
3837                    || self.state == ActivityState.PAUSING) {
3838                mWindowManager.overridePendingAppTransition(packageName,
3839                        enterAnim, exitAnim, null);
3840            }
3841
3842            Binder.restoreCallingIdentity(origId);
3843        }
3844    }
3845
3846    /**
3847     * Main function for removing an existing process from the activity manager
3848     * as a result of that process going away.  Clears out all connections
3849     * to the process.
3850     */
3851    private final void handleAppDiedLocked(ProcessRecord app,
3852            boolean restarting, boolean allowRestart) {
3853        int pid = app.pid;
3854        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3855        if (!restarting) {
3856            removeLruProcessLocked(app);
3857            if (pid > 0) {
3858                ProcessList.remove(pid);
3859            }
3860        }
3861
3862        if (mProfileProc == app) {
3863            clearProfilerLocked();
3864        }
3865
3866        // Remove this application's activities from active lists.
3867        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3868
3869        app.activities.clear();
3870
3871        if (app.instrumentationClass != null) {
3872            Slog.w(TAG, "Crash of app " + app.processName
3873                  + " running instrumentation " + app.instrumentationClass);
3874            Bundle info = new Bundle();
3875            info.putString("shortMsg", "Process crashed.");
3876            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3877        }
3878
3879        if (!restarting) {
3880            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3881                // If there was nothing to resume, and we are not already
3882                // restarting this process, but there is a visible activity that
3883                // is hosted by the process...  then make sure all visible
3884                // activities are running, taking care of restarting this
3885                // process.
3886                if (hasVisibleActivities) {
3887                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3888                }
3889            }
3890        }
3891    }
3892
3893    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3894        IBinder threadBinder = thread.asBinder();
3895        // Find the application record.
3896        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3897            ProcessRecord rec = mLruProcesses.get(i);
3898            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3899                return i;
3900            }
3901        }
3902        return -1;
3903    }
3904
3905    final ProcessRecord getRecordForAppLocked(
3906            IApplicationThread thread) {
3907        if (thread == null) {
3908            return null;
3909        }
3910
3911        int appIndex = getLRURecordIndexForAppLocked(thread);
3912        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3913    }
3914
3915    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3916        // If there are no longer any background processes running,
3917        // and the app that died was not running instrumentation,
3918        // then tell everyone we are now low on memory.
3919        boolean haveBg = false;
3920        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3921            ProcessRecord rec = mLruProcesses.get(i);
3922            if (rec.thread != null
3923                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3924                haveBg = true;
3925                break;
3926            }
3927        }
3928
3929        if (!haveBg) {
3930            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3931            if (doReport) {
3932                long now = SystemClock.uptimeMillis();
3933                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3934                    doReport = false;
3935                } else {
3936                    mLastMemUsageReportTime = now;
3937                }
3938            }
3939            final ArrayList<ProcessMemInfo> memInfos
3940                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3941            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3942            long now = SystemClock.uptimeMillis();
3943            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3944                ProcessRecord rec = mLruProcesses.get(i);
3945                if (rec == dyingProc || rec.thread == null) {
3946                    continue;
3947                }
3948                if (doReport) {
3949                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3950                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3951                }
3952                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3953                    // The low memory report is overriding any current
3954                    // state for a GC request.  Make sure to do
3955                    // heavy/important/visible/foreground processes first.
3956                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3957                        rec.lastRequestedGc = 0;
3958                    } else {
3959                        rec.lastRequestedGc = rec.lastLowMemory;
3960                    }
3961                    rec.reportLowMemory = true;
3962                    rec.lastLowMemory = now;
3963                    mProcessesToGc.remove(rec);
3964                    addProcessToGcListLocked(rec);
3965                }
3966            }
3967            if (doReport) {
3968                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3969                mHandler.sendMessage(msg);
3970            }
3971            scheduleAppGcsLocked();
3972        }
3973    }
3974
3975    final void appDiedLocked(ProcessRecord app, int pid,
3976            IApplicationThread thread) {
3977
3978        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3979        synchronized (stats) {
3980            stats.noteProcessDiedLocked(app.info.uid, pid);
3981        }
3982
3983        // Clean up already done if the process has been re-started.
3984        if (app.pid == pid && app.thread != null &&
3985                app.thread.asBinder() == thread.asBinder()) {
3986            boolean doLowMem = app.instrumentationClass == null;
3987            boolean doOomAdj = doLowMem;
3988            if (!app.killedByAm) {
3989                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3990                        + ") has died.");
3991                mAllowLowerMemLevel = true;
3992            } else {
3993                // Note that we always want to do oom adj to update our state with the
3994                // new number of procs.
3995                mAllowLowerMemLevel = false;
3996                doLowMem = false;
3997            }
3998            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3999            if (DEBUG_CLEANUP) Slog.v(
4000                TAG, "Dying app: " + app + ", pid: " + pid
4001                + ", thread: " + thread.asBinder());
4002            handleAppDiedLocked(app, false, true);
4003
4004            if (doOomAdj) {
4005                updateOomAdjLocked();
4006            }
4007            if (doLowMem) {
4008                doLowMemReportIfNeededLocked(app);
4009            }
4010        } else if (app.pid != pid) {
4011            // A new process has already been started.
4012            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4013                    + ") has died and restarted (pid " + app.pid + ").");
4014            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4015        } else if (DEBUG_PROCESSES) {
4016            Slog.d(TAG, "Received spurious death notification for thread "
4017                    + thread.asBinder());
4018        }
4019    }
4020
4021    /**
4022     * If a stack trace dump file is configured, dump process stack traces.
4023     * @param clearTraces causes the dump file to be erased prior to the new
4024     *    traces being written, if true; when false, the new traces will be
4025     *    appended to any existing file content.
4026     * @param firstPids of dalvik VM processes to dump stack traces for first
4027     * @param lastPids of dalvik VM processes to dump stack traces for last
4028     * @param nativeProcs optional list of native process names to dump stack crawls
4029     * @return file containing stack traces, or null if no dump file is configured
4030     */
4031    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4032            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4033        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4034        if (tracesPath == null || tracesPath.length() == 0) {
4035            return null;
4036        }
4037
4038        File tracesFile = new File(tracesPath);
4039        try {
4040            File tracesDir = tracesFile.getParentFile();
4041            if (!tracesDir.exists()) {
4042                tracesFile.mkdirs();
4043                if (!SELinux.restorecon(tracesDir)) {
4044                    return null;
4045                }
4046            }
4047            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4048
4049            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4050            tracesFile.createNewFile();
4051            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4052        } catch (IOException e) {
4053            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4054            return null;
4055        }
4056
4057        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4058        return tracesFile;
4059    }
4060
4061    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4062            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4063        // Use a FileObserver to detect when traces finish writing.
4064        // The order of traces is considered important to maintain for legibility.
4065        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4066            @Override
4067            public synchronized void onEvent(int event, String path) { notify(); }
4068        };
4069
4070        try {
4071            observer.startWatching();
4072
4073            // First collect all of the stacks of the most important pids.
4074            if (firstPids != null) {
4075                try {
4076                    int num = firstPids.size();
4077                    for (int i = 0; i < num; i++) {
4078                        synchronized (observer) {
4079                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4080                            observer.wait(200);  // Wait for write-close, give up after 200msec
4081                        }
4082                    }
4083                } catch (InterruptedException e) {
4084                    Log.wtf(TAG, e);
4085                }
4086            }
4087
4088            // Next collect the stacks of the native pids
4089            if (nativeProcs != null) {
4090                int[] pids = Process.getPidsForCommands(nativeProcs);
4091                if (pids != null) {
4092                    for (int pid : pids) {
4093                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4094                    }
4095                }
4096            }
4097
4098            // Lastly, measure CPU usage.
4099            if (processCpuTracker != null) {
4100                processCpuTracker.init();
4101                System.gc();
4102                processCpuTracker.update();
4103                try {
4104                    synchronized (processCpuTracker) {
4105                        processCpuTracker.wait(500); // measure over 1/2 second.
4106                    }
4107                } catch (InterruptedException e) {
4108                }
4109                processCpuTracker.update();
4110
4111                // We'll take the stack crawls of just the top apps using CPU.
4112                final int N = processCpuTracker.countWorkingStats();
4113                int numProcs = 0;
4114                for (int i=0; i<N && numProcs<5; i++) {
4115                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4116                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4117                        numProcs++;
4118                        try {
4119                            synchronized (observer) {
4120                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4121                                observer.wait(200);  // Wait for write-close, give up after 200msec
4122                            }
4123                        } catch (InterruptedException e) {
4124                            Log.wtf(TAG, e);
4125                        }
4126
4127                    }
4128                }
4129            }
4130        } finally {
4131            observer.stopWatching();
4132        }
4133    }
4134
4135    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4136        if (true || IS_USER_BUILD) {
4137            return;
4138        }
4139        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4140        if (tracesPath == null || tracesPath.length() == 0) {
4141            return;
4142        }
4143
4144        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4145        StrictMode.allowThreadDiskWrites();
4146        try {
4147            final File tracesFile = new File(tracesPath);
4148            final File tracesDir = tracesFile.getParentFile();
4149            final File tracesTmp = new File(tracesDir, "__tmp__");
4150            try {
4151                if (!tracesDir.exists()) {
4152                    tracesFile.mkdirs();
4153                    if (!SELinux.restorecon(tracesDir.getPath())) {
4154                        return;
4155                    }
4156                }
4157                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4158
4159                if (tracesFile.exists()) {
4160                    tracesTmp.delete();
4161                    tracesFile.renameTo(tracesTmp);
4162                }
4163                StringBuilder sb = new StringBuilder();
4164                Time tobj = new Time();
4165                tobj.set(System.currentTimeMillis());
4166                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4167                sb.append(": ");
4168                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4169                sb.append(" since ");
4170                sb.append(msg);
4171                FileOutputStream fos = new FileOutputStream(tracesFile);
4172                fos.write(sb.toString().getBytes());
4173                if (app == null) {
4174                    fos.write("\n*** No application process!".getBytes());
4175                }
4176                fos.close();
4177                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4178            } catch (IOException e) {
4179                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4180                return;
4181            }
4182
4183            if (app != null) {
4184                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4185                firstPids.add(app.pid);
4186                dumpStackTraces(tracesPath, firstPids, null, null, null);
4187            }
4188
4189            File lastTracesFile = null;
4190            File curTracesFile = null;
4191            for (int i=9; i>=0; i--) {
4192                String name = String.format(Locale.US, "slow%02d.txt", i);
4193                curTracesFile = new File(tracesDir, name);
4194                if (curTracesFile.exists()) {
4195                    if (lastTracesFile != null) {
4196                        curTracesFile.renameTo(lastTracesFile);
4197                    } else {
4198                        curTracesFile.delete();
4199                    }
4200                }
4201                lastTracesFile = curTracesFile;
4202            }
4203            tracesFile.renameTo(curTracesFile);
4204            if (tracesTmp.exists()) {
4205                tracesTmp.renameTo(tracesFile);
4206            }
4207        } finally {
4208            StrictMode.setThreadPolicy(oldPolicy);
4209        }
4210    }
4211
4212    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4213            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4214        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4215        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4216
4217        if (mController != null) {
4218            try {
4219                // 0 == continue, -1 = kill process immediately
4220                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4221                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4222            } catch (RemoteException e) {
4223                mController = null;
4224                Watchdog.getInstance().setActivityController(null);
4225            }
4226        }
4227
4228        long anrTime = SystemClock.uptimeMillis();
4229        if (MONITOR_CPU_USAGE) {
4230            updateCpuStatsNow();
4231        }
4232
4233        synchronized (this) {
4234            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4235            if (mShuttingDown) {
4236                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4237                return;
4238            } else if (app.notResponding) {
4239                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4240                return;
4241            } else if (app.crashing) {
4242                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4243                return;
4244            }
4245
4246            // In case we come through here for the same app before completing
4247            // this one, mark as anring now so we will bail out.
4248            app.notResponding = true;
4249
4250            // Log the ANR to the event log.
4251            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4252                    app.processName, app.info.flags, annotation);
4253
4254            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4255            firstPids.add(app.pid);
4256
4257            int parentPid = app.pid;
4258            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4259            if (parentPid != app.pid) firstPids.add(parentPid);
4260
4261            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4262
4263            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4264                ProcessRecord r = mLruProcesses.get(i);
4265                if (r != null && r.thread != null) {
4266                    int pid = r.pid;
4267                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4268                        if (r.persistent) {
4269                            firstPids.add(pid);
4270                        } else {
4271                            lastPids.put(pid, Boolean.TRUE);
4272                        }
4273                    }
4274                }
4275            }
4276        }
4277
4278        // Log the ANR to the main log.
4279        StringBuilder info = new StringBuilder();
4280        info.setLength(0);
4281        info.append("ANR in ").append(app.processName);
4282        if (activity != null && activity.shortComponentName != null) {
4283            info.append(" (").append(activity.shortComponentName).append(")");
4284        }
4285        info.append("\n");
4286        info.append("PID: ").append(app.pid).append("\n");
4287        if (annotation != null) {
4288            info.append("Reason: ").append(annotation).append("\n");
4289        }
4290        if (parent != null && parent != activity) {
4291            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4292        }
4293
4294        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4295
4296        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4297                NATIVE_STACKS_OF_INTEREST);
4298
4299        String cpuInfo = null;
4300        if (MONITOR_CPU_USAGE) {
4301            updateCpuStatsNow();
4302            synchronized (mProcessCpuThread) {
4303                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4304            }
4305            info.append(processCpuTracker.printCurrentLoad());
4306            info.append(cpuInfo);
4307        }
4308
4309        info.append(processCpuTracker.printCurrentState(anrTime));
4310
4311        Slog.e(TAG, info.toString());
4312        if (tracesFile == null) {
4313            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4314            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4315        }
4316
4317        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4318                cpuInfo, tracesFile, null);
4319
4320        if (mController != null) {
4321            try {
4322                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4323                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4324                if (res != 0) {
4325                    if (res < 0 && app.pid != MY_PID) {
4326                        Process.killProcess(app.pid);
4327                    } else {
4328                        synchronized (this) {
4329                            mServices.scheduleServiceTimeoutLocked(app);
4330                        }
4331                    }
4332                    return;
4333                }
4334            } catch (RemoteException e) {
4335                mController = null;
4336                Watchdog.getInstance().setActivityController(null);
4337            }
4338        }
4339
4340        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4341        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4342                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4343
4344        synchronized (this) {
4345            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4346                killUnneededProcessLocked(app, "background ANR");
4347                return;
4348            }
4349
4350            // Set the app's notResponding state, and look up the errorReportReceiver
4351            makeAppNotRespondingLocked(app,
4352                    activity != null ? activity.shortComponentName : null,
4353                    annotation != null ? "ANR " + annotation : "ANR",
4354                    info.toString());
4355
4356            // Bring up the infamous App Not Responding dialog
4357            Message msg = Message.obtain();
4358            HashMap<String, Object> map = new HashMap<String, Object>();
4359            msg.what = SHOW_NOT_RESPONDING_MSG;
4360            msg.obj = map;
4361            msg.arg1 = aboveSystem ? 1 : 0;
4362            map.put("app", app);
4363            if (activity != null) {
4364                map.put("activity", activity);
4365            }
4366
4367            mHandler.sendMessage(msg);
4368        }
4369    }
4370
4371    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4372        if (!mLaunchWarningShown) {
4373            mLaunchWarningShown = true;
4374            mHandler.post(new Runnable() {
4375                @Override
4376                public void run() {
4377                    synchronized (ActivityManagerService.this) {
4378                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4379                        d.show();
4380                        mHandler.postDelayed(new Runnable() {
4381                            @Override
4382                            public void run() {
4383                                synchronized (ActivityManagerService.this) {
4384                                    d.dismiss();
4385                                    mLaunchWarningShown = false;
4386                                }
4387                            }
4388                        }, 4000);
4389                    }
4390                }
4391            });
4392        }
4393    }
4394
4395    @Override
4396    public boolean clearApplicationUserData(final String packageName,
4397            final IPackageDataObserver observer, int userId) {
4398        enforceNotIsolatedCaller("clearApplicationUserData");
4399        int uid = Binder.getCallingUid();
4400        int pid = Binder.getCallingPid();
4401        userId = handleIncomingUser(pid, uid,
4402                userId, false, true, "clearApplicationUserData", null);
4403        long callingId = Binder.clearCallingIdentity();
4404        try {
4405            IPackageManager pm = AppGlobals.getPackageManager();
4406            int pkgUid = -1;
4407            synchronized(this) {
4408                try {
4409                    pkgUid = pm.getPackageUid(packageName, userId);
4410                } catch (RemoteException e) {
4411                }
4412                if (pkgUid == -1) {
4413                    Slog.w(TAG, "Invalid packageName: " + packageName);
4414                    if (observer != null) {
4415                        try {
4416                            observer.onRemoveCompleted(packageName, false);
4417                        } catch (RemoteException e) {
4418                            Slog.i(TAG, "Observer no longer exists.");
4419                        }
4420                    }
4421                    return false;
4422                }
4423                if (uid == pkgUid || checkComponentPermission(
4424                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4425                        pid, uid, -1, true)
4426                        == PackageManager.PERMISSION_GRANTED) {
4427                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4428                } else {
4429                    throw new SecurityException("PID " + pid + " does not have permission "
4430                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4431                                    + " of package " + packageName);
4432                }
4433            }
4434
4435            try {
4436                // Clear application user data
4437                pm.clearApplicationUserData(packageName, observer, userId);
4438
4439                // Remove all permissions granted from/to this package
4440                removeUriPermissionsForPackageLocked(packageName, userId, true);
4441
4442                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4443                        Uri.fromParts("package", packageName, null));
4444                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4445                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4446                        null, null, 0, null, null, null, false, false, userId);
4447            } catch (RemoteException e) {
4448            }
4449        } finally {
4450            Binder.restoreCallingIdentity(callingId);
4451        }
4452        return true;
4453    }
4454
4455    @Override
4456    public void killBackgroundProcesses(final String packageName, int userId) {
4457        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4458                != PackageManager.PERMISSION_GRANTED &&
4459                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4460                        != PackageManager.PERMISSION_GRANTED) {
4461            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4462                    + Binder.getCallingPid()
4463                    + ", uid=" + Binder.getCallingUid()
4464                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4465            Slog.w(TAG, msg);
4466            throw new SecurityException(msg);
4467        }
4468
4469        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4470                userId, true, true, "killBackgroundProcesses", null);
4471        long callingId = Binder.clearCallingIdentity();
4472        try {
4473            IPackageManager pm = AppGlobals.getPackageManager();
4474            synchronized(this) {
4475                int appId = -1;
4476                try {
4477                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4478                } catch (RemoteException e) {
4479                }
4480                if (appId == -1) {
4481                    Slog.w(TAG, "Invalid packageName: " + packageName);
4482                    return;
4483                }
4484                killPackageProcessesLocked(packageName, appId, userId,
4485                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4486            }
4487        } finally {
4488            Binder.restoreCallingIdentity(callingId);
4489        }
4490    }
4491
4492    @Override
4493    public void killAllBackgroundProcesses() {
4494        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4495                != PackageManager.PERMISSION_GRANTED) {
4496            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4497                    + Binder.getCallingPid()
4498                    + ", uid=" + Binder.getCallingUid()
4499                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4500            Slog.w(TAG, msg);
4501            throw new SecurityException(msg);
4502        }
4503
4504        long callingId = Binder.clearCallingIdentity();
4505        try {
4506            synchronized(this) {
4507                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4508                final int NP = mProcessNames.getMap().size();
4509                for (int ip=0; ip<NP; ip++) {
4510                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4511                    final int NA = apps.size();
4512                    for (int ia=0; ia<NA; ia++) {
4513                        ProcessRecord app = apps.valueAt(ia);
4514                        if (app.persistent) {
4515                            // we don't kill persistent processes
4516                            continue;
4517                        }
4518                        if (app.removed) {
4519                            procs.add(app);
4520                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4521                            app.removed = true;
4522                            procs.add(app);
4523                        }
4524                    }
4525                }
4526
4527                int N = procs.size();
4528                for (int i=0; i<N; i++) {
4529                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4530                }
4531                mAllowLowerMemLevel = true;
4532                updateOomAdjLocked();
4533                doLowMemReportIfNeededLocked(null);
4534            }
4535        } finally {
4536            Binder.restoreCallingIdentity(callingId);
4537        }
4538    }
4539
4540    @Override
4541    public void forceStopPackage(final String packageName, int userId) {
4542        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4543                != PackageManager.PERMISSION_GRANTED) {
4544            String msg = "Permission Denial: forceStopPackage() from pid="
4545                    + Binder.getCallingPid()
4546                    + ", uid=" + Binder.getCallingUid()
4547                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4548            Slog.w(TAG, msg);
4549            throw new SecurityException(msg);
4550        }
4551        final int callingPid = Binder.getCallingPid();
4552        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4553                userId, true, true, "forceStopPackage", null);
4554        long callingId = Binder.clearCallingIdentity();
4555        try {
4556            IPackageManager pm = AppGlobals.getPackageManager();
4557            synchronized(this) {
4558                int[] users = userId == UserHandle.USER_ALL
4559                        ? getUsersLocked() : new int[] { userId };
4560                for (int user : users) {
4561                    int pkgUid = -1;
4562                    try {
4563                        pkgUid = pm.getPackageUid(packageName, user);
4564                    } catch (RemoteException e) {
4565                    }
4566                    if (pkgUid == -1) {
4567                        Slog.w(TAG, "Invalid packageName: " + packageName);
4568                        continue;
4569                    }
4570                    try {
4571                        pm.setPackageStoppedState(packageName, true, user);
4572                    } catch (RemoteException e) {
4573                    } catch (IllegalArgumentException e) {
4574                        Slog.w(TAG, "Failed trying to unstop package "
4575                                + packageName + ": " + e);
4576                    }
4577                    if (isUserRunningLocked(user, false)) {
4578                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4579                    }
4580                }
4581            }
4582        } finally {
4583            Binder.restoreCallingIdentity(callingId);
4584        }
4585    }
4586
4587    /*
4588     * The pkg name and app id have to be specified.
4589     */
4590    @Override
4591    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4592        if (pkg == null) {
4593            return;
4594        }
4595        // Make sure the uid is valid.
4596        if (appid < 0) {
4597            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4598            return;
4599        }
4600        int callerUid = Binder.getCallingUid();
4601        // Only the system server can kill an application
4602        if (callerUid == Process.SYSTEM_UID) {
4603            // Post an aysnc message to kill the application
4604            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4605            msg.arg1 = appid;
4606            msg.arg2 = 0;
4607            Bundle bundle = new Bundle();
4608            bundle.putString("pkg", pkg);
4609            bundle.putString("reason", reason);
4610            msg.obj = bundle;
4611            mHandler.sendMessage(msg);
4612        } else {
4613            throw new SecurityException(callerUid + " cannot kill pkg: " +
4614                    pkg);
4615        }
4616    }
4617
4618    @Override
4619    public void closeSystemDialogs(String reason) {
4620        enforceNotIsolatedCaller("closeSystemDialogs");
4621
4622        final int pid = Binder.getCallingPid();
4623        final int uid = Binder.getCallingUid();
4624        final long origId = Binder.clearCallingIdentity();
4625        try {
4626            synchronized (this) {
4627                // Only allow this from foreground processes, so that background
4628                // applications can't abuse it to prevent system UI from being shown.
4629                if (uid >= Process.FIRST_APPLICATION_UID) {
4630                    ProcessRecord proc;
4631                    synchronized (mPidsSelfLocked) {
4632                        proc = mPidsSelfLocked.get(pid);
4633                    }
4634                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4635                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4636                                + " from background process " + proc);
4637                        return;
4638                    }
4639                }
4640                closeSystemDialogsLocked(reason);
4641            }
4642        } finally {
4643            Binder.restoreCallingIdentity(origId);
4644        }
4645    }
4646
4647    void closeSystemDialogsLocked(String reason) {
4648        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4649        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4650                | Intent.FLAG_RECEIVER_FOREGROUND);
4651        if (reason != null) {
4652            intent.putExtra("reason", reason);
4653        }
4654        mWindowManager.closeSystemDialogs(reason);
4655
4656        mStackSupervisor.closeSystemDialogsLocked();
4657
4658        broadcastIntentLocked(null, null, intent, null,
4659                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4660                Process.SYSTEM_UID, UserHandle.USER_ALL);
4661    }
4662
4663    @Override
4664    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4665        enforceNotIsolatedCaller("getProcessMemoryInfo");
4666        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4667        for (int i=pids.length-1; i>=0; i--) {
4668            ProcessRecord proc;
4669            int oomAdj;
4670            synchronized (this) {
4671                synchronized (mPidsSelfLocked) {
4672                    proc = mPidsSelfLocked.get(pids[i]);
4673                    oomAdj = proc != null ? proc.setAdj : 0;
4674                }
4675            }
4676            infos[i] = new Debug.MemoryInfo();
4677            Debug.getMemoryInfo(pids[i], infos[i]);
4678            if (proc != null) {
4679                synchronized (this) {
4680                    if (proc.thread != null && proc.setAdj == oomAdj) {
4681                        // Record this for posterity if the process has been stable.
4682                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4683                                infos[i].getTotalUss(), false, proc.pkgList);
4684                    }
4685                }
4686            }
4687        }
4688        return infos;
4689    }
4690
4691    @Override
4692    public long[] getProcessPss(int[] pids) {
4693        enforceNotIsolatedCaller("getProcessPss");
4694        long[] pss = new long[pids.length];
4695        for (int i=pids.length-1; i>=0; i--) {
4696            ProcessRecord proc;
4697            int oomAdj;
4698            synchronized (this) {
4699                synchronized (mPidsSelfLocked) {
4700                    proc = mPidsSelfLocked.get(pids[i]);
4701                    oomAdj = proc != null ? proc.setAdj : 0;
4702                }
4703            }
4704            long[] tmpUss = new long[1];
4705            pss[i] = Debug.getPss(pids[i], tmpUss);
4706            if (proc != null) {
4707                synchronized (this) {
4708                    if (proc.thread != null && proc.setAdj == oomAdj) {
4709                        // Record this for posterity if the process has been stable.
4710                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4711                    }
4712                }
4713            }
4714        }
4715        return pss;
4716    }
4717
4718    @Override
4719    public void killApplicationProcess(String processName, int uid) {
4720        if (processName == null) {
4721            return;
4722        }
4723
4724        int callerUid = Binder.getCallingUid();
4725        // Only the system server can kill an application
4726        if (callerUid == Process.SYSTEM_UID) {
4727            synchronized (this) {
4728                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4729                if (app != null && app.thread != null) {
4730                    try {
4731                        app.thread.scheduleSuicide();
4732                    } catch (RemoteException e) {
4733                        // If the other end already died, then our work here is done.
4734                    }
4735                } else {
4736                    Slog.w(TAG, "Process/uid not found attempting kill of "
4737                            + processName + " / " + uid);
4738                }
4739            }
4740        } else {
4741            throw new SecurityException(callerUid + " cannot kill app process: " +
4742                    processName);
4743        }
4744    }
4745
4746    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4747        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4748                false, true, false, false, UserHandle.getUserId(uid), reason);
4749        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4750                Uri.fromParts("package", packageName, null));
4751        if (!mProcessesReady) {
4752            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4753                    | Intent.FLAG_RECEIVER_FOREGROUND);
4754        }
4755        intent.putExtra(Intent.EXTRA_UID, uid);
4756        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4757        broadcastIntentLocked(null, null, intent,
4758                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4759                false, false,
4760                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4761    }
4762
4763    private void forceStopUserLocked(int userId, String reason) {
4764        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4765        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4766        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4767                | Intent.FLAG_RECEIVER_FOREGROUND);
4768        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4769        broadcastIntentLocked(null, null, intent,
4770                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4771                false, false,
4772                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4773    }
4774
4775    private final boolean killPackageProcessesLocked(String packageName, int appId,
4776            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4777            boolean doit, boolean evenPersistent, String reason) {
4778        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4779
4780        // Remove all processes this package may have touched: all with the
4781        // same UID (except for the system or root user), and all whose name
4782        // matches the package name.
4783        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4784        final int NP = mProcessNames.getMap().size();
4785        for (int ip=0; ip<NP; ip++) {
4786            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4787            final int NA = apps.size();
4788            for (int ia=0; ia<NA; ia++) {
4789                ProcessRecord app = apps.valueAt(ia);
4790                if (app.persistent && !evenPersistent) {
4791                    // we don't kill persistent processes
4792                    continue;
4793                }
4794                if (app.removed) {
4795                    if (doit) {
4796                        procs.add(app);
4797                    }
4798                    continue;
4799                }
4800
4801                // Skip process if it doesn't meet our oom adj requirement.
4802                if (app.setAdj < minOomAdj) {
4803                    continue;
4804                }
4805
4806                // If no package is specified, we call all processes under the
4807                // give user id.
4808                if (packageName == null) {
4809                    if (app.userId != userId) {
4810                        continue;
4811                    }
4812                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4813                        continue;
4814                    }
4815                // Package has been specified, we want to hit all processes
4816                // that match it.  We need to qualify this by the processes
4817                // that are running under the specified app and user ID.
4818                } else {
4819                    if (UserHandle.getAppId(app.uid) != appId) {
4820                        continue;
4821                    }
4822                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4823                        continue;
4824                    }
4825                    if (!app.pkgList.containsKey(packageName)) {
4826                        continue;
4827                    }
4828                }
4829
4830                // Process has passed all conditions, kill it!
4831                if (!doit) {
4832                    return true;
4833                }
4834                app.removed = true;
4835                procs.add(app);
4836            }
4837        }
4838
4839        int N = procs.size();
4840        for (int i=0; i<N; i++) {
4841            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4842        }
4843        updateOomAdjLocked();
4844        return N > 0;
4845    }
4846
4847    private final boolean forceStopPackageLocked(String name, int appId,
4848            boolean callerWillRestart, boolean purgeCache, boolean doit,
4849            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4850        int i;
4851        int N;
4852
4853        if (userId == UserHandle.USER_ALL && name == null) {
4854            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4855        }
4856
4857        if (appId < 0 && name != null) {
4858            try {
4859                appId = UserHandle.getAppId(
4860                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4861            } catch (RemoteException e) {
4862            }
4863        }
4864
4865        if (doit) {
4866            if (name != null) {
4867                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4868                        + " user=" + userId + ": " + reason);
4869            } else {
4870                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4871            }
4872
4873            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4874            for (int ip=pmap.size()-1; ip>=0; ip--) {
4875                SparseArray<Long> ba = pmap.valueAt(ip);
4876                for (i=ba.size()-1; i>=0; i--) {
4877                    boolean remove = false;
4878                    final int entUid = ba.keyAt(i);
4879                    if (name != null) {
4880                        if (userId == UserHandle.USER_ALL) {
4881                            if (UserHandle.getAppId(entUid) == appId) {
4882                                remove = true;
4883                            }
4884                        } else {
4885                            if (entUid == UserHandle.getUid(userId, appId)) {
4886                                remove = true;
4887                            }
4888                        }
4889                    } else if (UserHandle.getUserId(entUid) == userId) {
4890                        remove = true;
4891                    }
4892                    if (remove) {
4893                        ba.removeAt(i);
4894                    }
4895                }
4896                if (ba.size() == 0) {
4897                    pmap.removeAt(ip);
4898                }
4899            }
4900        }
4901
4902        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4903                -100, callerWillRestart, true, doit, evenPersistent,
4904                name == null ? ("stop user " + userId) : ("stop " + name));
4905
4906        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4907            if (!doit) {
4908                return true;
4909            }
4910            didSomething = true;
4911        }
4912
4913        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4914            if (!doit) {
4915                return true;
4916            }
4917            didSomething = true;
4918        }
4919
4920        if (name == null) {
4921            // Remove all sticky broadcasts from this user.
4922            mStickyBroadcasts.remove(userId);
4923        }
4924
4925        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4926        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4927                userId, providers)) {
4928            if (!doit) {
4929                return true;
4930            }
4931            didSomething = true;
4932        }
4933        N = providers.size();
4934        for (i=0; i<N; i++) {
4935            removeDyingProviderLocked(null, providers.get(i), true);
4936        }
4937
4938        // Remove transient permissions granted from/to this package/user
4939        removeUriPermissionsForPackageLocked(name, userId, false);
4940
4941        if (name == null || uninstalling) {
4942            // Remove pending intents.  For now we only do this when force
4943            // stopping users, because we have some problems when doing this
4944            // for packages -- app widgets are not currently cleaned up for
4945            // such packages, so they can be left with bad pending intents.
4946            if (mIntentSenderRecords.size() > 0) {
4947                Iterator<WeakReference<PendingIntentRecord>> it
4948                        = mIntentSenderRecords.values().iterator();
4949                while (it.hasNext()) {
4950                    WeakReference<PendingIntentRecord> wpir = it.next();
4951                    if (wpir == null) {
4952                        it.remove();
4953                        continue;
4954                    }
4955                    PendingIntentRecord pir = wpir.get();
4956                    if (pir == null) {
4957                        it.remove();
4958                        continue;
4959                    }
4960                    if (name == null) {
4961                        // Stopping user, remove all objects for the user.
4962                        if (pir.key.userId != userId) {
4963                            // Not the same user, skip it.
4964                            continue;
4965                        }
4966                    } else {
4967                        if (UserHandle.getAppId(pir.uid) != appId) {
4968                            // Different app id, skip it.
4969                            continue;
4970                        }
4971                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4972                            // Different user, skip it.
4973                            continue;
4974                        }
4975                        if (!pir.key.packageName.equals(name)) {
4976                            // Different package, skip it.
4977                            continue;
4978                        }
4979                    }
4980                    if (!doit) {
4981                        return true;
4982                    }
4983                    didSomething = true;
4984                    it.remove();
4985                    pir.canceled = true;
4986                    if (pir.key.activity != null) {
4987                        pir.key.activity.pendingResults.remove(pir.ref);
4988                    }
4989                }
4990            }
4991        }
4992
4993        if (doit) {
4994            if (purgeCache && name != null) {
4995                AttributeCache ac = AttributeCache.instance();
4996                if (ac != null) {
4997                    ac.removePackage(name);
4998                }
4999            }
5000            if (mBooted) {
5001                mStackSupervisor.resumeTopActivitiesLocked();
5002                mStackSupervisor.scheduleIdleLocked();
5003            }
5004        }
5005
5006        return didSomething;
5007    }
5008
5009    private final boolean removeProcessLocked(ProcessRecord app,
5010            boolean callerWillRestart, boolean allowRestart, String reason) {
5011        final String name = app.processName;
5012        final int uid = app.uid;
5013        if (DEBUG_PROCESSES) Slog.d(
5014            TAG, "Force removing proc " + app.toShortString() + " (" + name
5015            + "/" + uid + ")");
5016
5017        mProcessNames.remove(name, uid);
5018        mIsolatedProcesses.remove(app.uid);
5019        if (mHeavyWeightProcess == app) {
5020            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5021                    mHeavyWeightProcess.userId, 0));
5022            mHeavyWeightProcess = null;
5023        }
5024        boolean needRestart = false;
5025        if (app.pid > 0 && app.pid != MY_PID) {
5026            int pid = app.pid;
5027            synchronized (mPidsSelfLocked) {
5028                mPidsSelfLocked.remove(pid);
5029                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5030            }
5031            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5032                    app.processName, app.info.uid);
5033            if (app.isolated) {
5034                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5035            }
5036            killUnneededProcessLocked(app, reason);
5037            handleAppDiedLocked(app, true, allowRestart);
5038            removeLruProcessLocked(app);
5039
5040            if (app.persistent && !app.isolated) {
5041                if (!callerWillRestart) {
5042                    addAppLocked(app.info, false, null /* ABI override */);
5043                } else {
5044                    needRestart = true;
5045                }
5046            }
5047        } else {
5048            mRemovedProcesses.add(app);
5049        }
5050
5051        return needRestart;
5052    }
5053
5054    private final void processStartTimedOutLocked(ProcessRecord app) {
5055        final int pid = app.pid;
5056        boolean gone = false;
5057        synchronized (mPidsSelfLocked) {
5058            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5059            if (knownApp != null && knownApp.thread == null) {
5060                mPidsSelfLocked.remove(pid);
5061                gone = true;
5062            }
5063        }
5064
5065        if (gone) {
5066            Slog.w(TAG, "Process " + app + " failed to attach");
5067            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5068                    pid, app.uid, app.processName);
5069            mProcessNames.remove(app.processName, app.uid);
5070            mIsolatedProcesses.remove(app.uid);
5071            if (mHeavyWeightProcess == app) {
5072                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5073                        mHeavyWeightProcess.userId, 0));
5074                mHeavyWeightProcess = null;
5075            }
5076            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5077                    app.processName, app.info.uid);
5078            if (app.isolated) {
5079                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5080            }
5081            // Take care of any launching providers waiting for this process.
5082            checkAppInLaunchingProvidersLocked(app, true);
5083            // Take care of any services that are waiting for the process.
5084            mServices.processStartTimedOutLocked(app);
5085            killUnneededProcessLocked(app, "start timeout");
5086            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5087                Slog.w(TAG, "Unattached app died before backup, skipping");
5088                try {
5089                    IBackupManager bm = IBackupManager.Stub.asInterface(
5090                            ServiceManager.getService(Context.BACKUP_SERVICE));
5091                    bm.agentDisconnected(app.info.packageName);
5092                } catch (RemoteException e) {
5093                    // Can't happen; the backup manager is local
5094                }
5095            }
5096            if (isPendingBroadcastProcessLocked(pid)) {
5097                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5098                skipPendingBroadcastLocked(pid);
5099            }
5100        } else {
5101            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5102        }
5103    }
5104
5105    private final boolean attachApplicationLocked(IApplicationThread thread,
5106            int pid) {
5107
5108        // Find the application record that is being attached...  either via
5109        // the pid if we are running in multiple processes, or just pull the
5110        // next app record if we are emulating process with anonymous threads.
5111        ProcessRecord app;
5112        if (pid != MY_PID && pid >= 0) {
5113            synchronized (mPidsSelfLocked) {
5114                app = mPidsSelfLocked.get(pid);
5115            }
5116        } else {
5117            app = null;
5118        }
5119
5120        if (app == null) {
5121            Slog.w(TAG, "No pending application record for pid " + pid
5122                    + " (IApplicationThread " + thread + "); dropping process");
5123            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5124            if (pid > 0 && pid != MY_PID) {
5125                Process.killProcessQuiet(pid);
5126            } else {
5127                try {
5128                    thread.scheduleExit();
5129                } catch (Exception e) {
5130                    // Ignore exceptions.
5131                }
5132            }
5133            return false;
5134        }
5135
5136        // If this application record is still attached to a previous
5137        // process, clean it up now.
5138        if (app.thread != null) {
5139            handleAppDiedLocked(app, true, true);
5140        }
5141
5142        // Tell the process all about itself.
5143
5144        if (localLOGV) Slog.v(
5145                TAG, "Binding process pid " + pid + " to record " + app);
5146
5147        final String processName = app.processName;
5148        try {
5149            AppDeathRecipient adr = new AppDeathRecipient(
5150                    app, pid, thread);
5151            thread.asBinder().linkToDeath(adr, 0);
5152            app.deathRecipient = adr;
5153        } catch (RemoteException e) {
5154            app.resetPackageList(mProcessStats);
5155            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5156            return false;
5157        }
5158
5159        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5160
5161        app.makeActive(thread, mProcessStats);
5162        app.curAdj = app.setAdj = -100;
5163        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5164        app.forcingToForeground = null;
5165        updateProcessForegroundLocked(app, false, false);
5166        app.hasShownUi = false;
5167        app.debugging = false;
5168        app.cached = false;
5169
5170        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5171
5172        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5173        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5174
5175        if (!normalMode) {
5176            Slog.i(TAG, "Launching preboot mode app: " + app);
5177        }
5178
5179        if (localLOGV) Slog.v(
5180            TAG, "New app record " + app
5181            + " thread=" + thread.asBinder() + " pid=" + pid);
5182        try {
5183            int testMode = IApplicationThread.DEBUG_OFF;
5184            if (mDebugApp != null && mDebugApp.equals(processName)) {
5185                testMode = mWaitForDebugger
5186                    ? IApplicationThread.DEBUG_WAIT
5187                    : IApplicationThread.DEBUG_ON;
5188                app.debugging = true;
5189                if (mDebugTransient) {
5190                    mDebugApp = mOrigDebugApp;
5191                    mWaitForDebugger = mOrigWaitForDebugger;
5192                }
5193            }
5194            String profileFile = app.instrumentationProfileFile;
5195            ParcelFileDescriptor profileFd = null;
5196            boolean profileAutoStop = false;
5197            if (mProfileApp != null && mProfileApp.equals(processName)) {
5198                mProfileProc = app;
5199                profileFile = mProfileFile;
5200                profileFd = mProfileFd;
5201                profileAutoStop = mAutoStopProfiler;
5202            }
5203            boolean enableOpenGlTrace = false;
5204            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5205                enableOpenGlTrace = true;
5206                mOpenGlTraceApp = null;
5207            }
5208
5209            // If the app is being launched for restore or full backup, set it up specially
5210            boolean isRestrictedBackupMode = false;
5211            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5212                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5213                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5214                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5215            }
5216
5217            ensurePackageDexOpt(app.instrumentationInfo != null
5218                    ? app.instrumentationInfo.packageName
5219                    : app.info.packageName);
5220            if (app.instrumentationClass != null) {
5221                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5222            }
5223            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5224                    + processName + " with config " + mConfiguration);
5225            ApplicationInfo appInfo = app.instrumentationInfo != null
5226                    ? app.instrumentationInfo : app.info;
5227            app.compat = compatibilityInfoForPackageLocked(appInfo);
5228            if (profileFd != null) {
5229                profileFd = profileFd.dup();
5230            }
5231            thread.bindApplication(processName, appInfo, providers,
5232                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5233                    app.instrumentationArguments, app.instrumentationWatcher,
5234                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5235                    isRestrictedBackupMode || !normalMode, app.persistent,
5236                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5237                    mCoreSettingsObserver.getCoreSettingsLocked());
5238            updateLruProcessLocked(app, false, null);
5239            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5240        } catch (Exception e) {
5241            // todo: Yikes!  What should we do?  For now we will try to
5242            // start another process, but that could easily get us in
5243            // an infinite loop of restarting processes...
5244            Slog.w(TAG, "Exception thrown during bind!", e);
5245
5246            app.resetPackageList(mProcessStats);
5247            app.unlinkDeathRecipient();
5248            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5249            return false;
5250        }
5251
5252        // Remove this record from the list of starting applications.
5253        mPersistentStartingProcesses.remove(app);
5254        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5255                "Attach application locked removing on hold: " + app);
5256        mProcessesOnHold.remove(app);
5257
5258        boolean badApp = false;
5259        boolean didSomething = false;
5260
5261        // See if the top visible activity is waiting to run in this process...
5262        if (normalMode) {
5263            try {
5264                if (mStackSupervisor.attachApplicationLocked(app)) {
5265                    didSomething = true;
5266                }
5267            } catch (Exception e) {
5268                badApp = true;
5269            }
5270        }
5271
5272        // Find any services that should be running in this process...
5273        if (!badApp) {
5274            try {
5275                didSomething |= mServices.attachApplicationLocked(app, processName);
5276            } catch (Exception e) {
5277                badApp = true;
5278            }
5279        }
5280
5281        // Check if a next-broadcast receiver is in this process...
5282        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5283            try {
5284                didSomething |= sendPendingBroadcastsLocked(app);
5285            } catch (Exception e) {
5286                // If the app died trying to launch the receiver we declare it 'bad'
5287                badApp = true;
5288            }
5289        }
5290
5291        // Check whether the next backup agent is in this process...
5292        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5293            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5294            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5295            try {
5296                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5297                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5298                        mBackupTarget.backupMode);
5299            } catch (Exception e) {
5300                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5301                e.printStackTrace();
5302            }
5303        }
5304
5305        if (badApp) {
5306            // todo: Also need to kill application to deal with all
5307            // kinds of exceptions.
5308            handleAppDiedLocked(app, false, true);
5309            return false;
5310        }
5311
5312        if (!didSomething) {
5313            updateOomAdjLocked();
5314        }
5315
5316        return true;
5317    }
5318
5319    @Override
5320    public final void attachApplication(IApplicationThread thread) {
5321        synchronized (this) {
5322            int callingPid = Binder.getCallingPid();
5323            final long origId = Binder.clearCallingIdentity();
5324            attachApplicationLocked(thread, callingPid);
5325            Binder.restoreCallingIdentity(origId);
5326        }
5327    }
5328
5329    @Override
5330    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5331        final long origId = Binder.clearCallingIdentity();
5332        synchronized (this) {
5333            ActivityStack stack = ActivityRecord.getStackLocked(token);
5334            if (stack != null) {
5335                ActivityRecord r =
5336                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5337                if (stopProfiling) {
5338                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5339                        try {
5340                            mProfileFd.close();
5341                        } catch (IOException e) {
5342                        }
5343                        clearProfilerLocked();
5344                    }
5345                }
5346            }
5347        }
5348        Binder.restoreCallingIdentity(origId);
5349    }
5350
5351    void enableScreenAfterBoot() {
5352        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5353                SystemClock.uptimeMillis());
5354        mWindowManager.enableScreenAfterBoot();
5355
5356        synchronized (this) {
5357            updateEventDispatchingLocked();
5358        }
5359    }
5360
5361    @Override
5362    public void showBootMessage(final CharSequence msg, final boolean always) {
5363        enforceNotIsolatedCaller("showBootMessage");
5364        mWindowManager.showBootMessage(msg, always);
5365    }
5366
5367    @Override
5368    public void dismissKeyguardOnNextActivity() {
5369        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5370        final long token = Binder.clearCallingIdentity();
5371        try {
5372            synchronized (this) {
5373                if (DEBUG_LOCKSCREEN) logLockScreen("");
5374                if (mLockScreenShown) {
5375                    mLockScreenShown = false;
5376                    comeOutOfSleepIfNeededLocked();
5377                }
5378                mStackSupervisor.setDismissKeyguard(true);
5379            }
5380        } finally {
5381            Binder.restoreCallingIdentity(token);
5382        }
5383    }
5384
5385    final void finishBooting() {
5386        // Register receivers to handle package update events
5387        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5388
5389        synchronized (this) {
5390            // Ensure that any processes we had put on hold are now started
5391            // up.
5392            final int NP = mProcessesOnHold.size();
5393            if (NP > 0) {
5394                ArrayList<ProcessRecord> procs =
5395                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5396                for (int ip=0; ip<NP; ip++) {
5397                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5398                            + procs.get(ip));
5399                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5400                }
5401            }
5402
5403            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5404                // Start looking for apps that are abusing wake locks.
5405                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5406                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5407                // Tell anyone interested that we are done booting!
5408                SystemProperties.set("sys.boot_completed", "1");
5409                SystemProperties.set("dev.bootcomplete", "1");
5410                for (int i=0; i<mStartedUsers.size(); i++) {
5411                    UserStartedState uss = mStartedUsers.valueAt(i);
5412                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5413                        uss.mState = UserStartedState.STATE_RUNNING;
5414                        final int userId = mStartedUsers.keyAt(i);
5415                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5416                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5417                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5418                        broadcastIntentLocked(null, null, intent, null,
5419                                new IIntentReceiver.Stub() {
5420                                    @Override
5421                                    public void performReceive(Intent intent, int resultCode,
5422                                            String data, Bundle extras, boolean ordered,
5423                                            boolean sticky, int sendingUser) {
5424                                        synchronized (ActivityManagerService.this) {
5425                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5426                                                    true, false);
5427                                        }
5428                                    }
5429                                },
5430                                0, null, null,
5431                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5432                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5433                                userId);
5434                    }
5435                }
5436                scheduleStartProfilesLocked();
5437            }
5438        }
5439    }
5440
5441    final void ensureBootCompleted() {
5442        boolean booting;
5443        boolean enableScreen;
5444        synchronized (this) {
5445            booting = mBooting;
5446            mBooting = false;
5447            enableScreen = !mBooted;
5448            mBooted = true;
5449        }
5450
5451        if (booting) {
5452            finishBooting();
5453        }
5454
5455        if (enableScreen) {
5456            enableScreenAfterBoot();
5457        }
5458    }
5459
5460    @Override
5461    public final void activityResumed(IBinder token) {
5462        final long origId = Binder.clearCallingIdentity();
5463        synchronized(this) {
5464            ActivityStack stack = ActivityRecord.getStackLocked(token);
5465            if (stack != null) {
5466                ActivityRecord.activityResumedLocked(token);
5467            }
5468        }
5469        Binder.restoreCallingIdentity(origId);
5470    }
5471
5472    @Override
5473    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5474        final long origId = Binder.clearCallingIdentity();
5475        synchronized(this) {
5476            ActivityStack stack = ActivityRecord.getStackLocked(token);
5477            if (stack != null) {
5478                stack.activityPausedLocked(token, false, persistentState);
5479            }
5480        }
5481        Binder.restoreCallingIdentity(origId);
5482    }
5483
5484    @Override
5485    public final void activityStopped(IBinder token, Bundle icicle,
5486            PersistableBundle persistentState, CharSequence description) {
5487        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5488
5489        // Refuse possible leaked file descriptors
5490        if (icicle != null && icicle.hasFileDescriptors()) {
5491            throw new IllegalArgumentException("File descriptors passed in Bundle");
5492        }
5493
5494        final long origId = Binder.clearCallingIdentity();
5495
5496        synchronized (this) {
5497            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5498            if (r != null) {
5499                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5500            }
5501        }
5502
5503        trimApplications();
5504
5505        Binder.restoreCallingIdentity(origId);
5506    }
5507
5508    @Override
5509    public final void activityDestroyed(IBinder token) {
5510        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5511        synchronized (this) {
5512            ActivityStack stack = ActivityRecord.getStackLocked(token);
5513            if (stack != null) {
5514                stack.activityDestroyedLocked(token);
5515            }
5516        }
5517    }
5518
5519    @Override
5520    public String getCallingPackage(IBinder token) {
5521        synchronized (this) {
5522            ActivityRecord r = getCallingRecordLocked(token);
5523            return r != null ? r.info.packageName : null;
5524        }
5525    }
5526
5527    @Override
5528    public ComponentName getCallingActivity(IBinder token) {
5529        synchronized (this) {
5530            ActivityRecord r = getCallingRecordLocked(token);
5531            return r != null ? r.intent.getComponent() : null;
5532        }
5533    }
5534
5535    private ActivityRecord getCallingRecordLocked(IBinder token) {
5536        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5537        if (r == null) {
5538            return null;
5539        }
5540        return r.resultTo;
5541    }
5542
5543    @Override
5544    public ComponentName getActivityClassForToken(IBinder token) {
5545        synchronized(this) {
5546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5547            if (r == null) {
5548                return null;
5549            }
5550            return r.intent.getComponent();
5551        }
5552    }
5553
5554    @Override
5555    public String getPackageForToken(IBinder token) {
5556        synchronized(this) {
5557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5558            if (r == null) {
5559                return null;
5560            }
5561            return r.packageName;
5562        }
5563    }
5564
5565    @Override
5566    public IIntentSender getIntentSender(int type,
5567            String packageName, IBinder token, String resultWho,
5568            int requestCode, Intent[] intents, String[] resolvedTypes,
5569            int flags, Bundle options, int userId) {
5570        enforceNotIsolatedCaller("getIntentSender");
5571        // Refuse possible leaked file descriptors
5572        if (intents != null) {
5573            if (intents.length < 1) {
5574                throw new IllegalArgumentException("Intents array length must be >= 1");
5575            }
5576            for (int i=0; i<intents.length; i++) {
5577                Intent intent = intents[i];
5578                if (intent != null) {
5579                    if (intent.hasFileDescriptors()) {
5580                        throw new IllegalArgumentException("File descriptors passed in Intent");
5581                    }
5582                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5583                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5584                        throw new IllegalArgumentException(
5585                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5586                    }
5587                    intents[i] = new Intent(intent);
5588                }
5589            }
5590            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5591                throw new IllegalArgumentException(
5592                        "Intent array length does not match resolvedTypes length");
5593            }
5594        }
5595        if (options != null) {
5596            if (options.hasFileDescriptors()) {
5597                throw new IllegalArgumentException("File descriptors passed in options");
5598            }
5599        }
5600
5601        synchronized(this) {
5602            int callingUid = Binder.getCallingUid();
5603            int origUserId = userId;
5604            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5605                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5606                    "getIntentSender", null);
5607            if (origUserId == UserHandle.USER_CURRENT) {
5608                // We don't want to evaluate this until the pending intent is
5609                // actually executed.  However, we do want to always do the
5610                // security checking for it above.
5611                userId = UserHandle.USER_CURRENT;
5612            }
5613            try {
5614                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5615                    int uid = AppGlobals.getPackageManager()
5616                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5617                    if (!UserHandle.isSameApp(callingUid, uid)) {
5618                        String msg = "Permission Denial: getIntentSender() from pid="
5619                            + Binder.getCallingPid()
5620                            + ", uid=" + Binder.getCallingUid()
5621                            + ", (need uid=" + uid + ")"
5622                            + " is not allowed to send as package " + packageName;
5623                        Slog.w(TAG, msg);
5624                        throw new SecurityException(msg);
5625                    }
5626                }
5627
5628                return getIntentSenderLocked(type, packageName, callingUid, userId,
5629                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5630
5631            } catch (RemoteException e) {
5632                throw new SecurityException(e);
5633            }
5634        }
5635    }
5636
5637    IIntentSender getIntentSenderLocked(int type, String packageName,
5638            int callingUid, int userId, IBinder token, String resultWho,
5639            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5640            Bundle options) {
5641        if (DEBUG_MU)
5642            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5643        ActivityRecord activity = null;
5644        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5645            activity = ActivityRecord.isInStackLocked(token);
5646            if (activity == null) {
5647                return null;
5648            }
5649            if (activity.finishing) {
5650                return null;
5651            }
5652        }
5653
5654        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5655        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5656        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5657        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5658                |PendingIntent.FLAG_UPDATE_CURRENT);
5659
5660        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5661                type, packageName, activity, resultWho,
5662                requestCode, intents, resolvedTypes, flags, options, userId);
5663        WeakReference<PendingIntentRecord> ref;
5664        ref = mIntentSenderRecords.get(key);
5665        PendingIntentRecord rec = ref != null ? ref.get() : null;
5666        if (rec != null) {
5667            if (!cancelCurrent) {
5668                if (updateCurrent) {
5669                    if (rec.key.requestIntent != null) {
5670                        rec.key.requestIntent.replaceExtras(intents != null ?
5671                                intents[intents.length - 1] : null);
5672                    }
5673                    if (intents != null) {
5674                        intents[intents.length-1] = rec.key.requestIntent;
5675                        rec.key.allIntents = intents;
5676                        rec.key.allResolvedTypes = resolvedTypes;
5677                    } else {
5678                        rec.key.allIntents = null;
5679                        rec.key.allResolvedTypes = null;
5680                    }
5681                }
5682                return rec;
5683            }
5684            rec.canceled = true;
5685            mIntentSenderRecords.remove(key);
5686        }
5687        if (noCreate) {
5688            return rec;
5689        }
5690        rec = new PendingIntentRecord(this, key, callingUid);
5691        mIntentSenderRecords.put(key, rec.ref);
5692        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5693            if (activity.pendingResults == null) {
5694                activity.pendingResults
5695                        = new HashSet<WeakReference<PendingIntentRecord>>();
5696            }
5697            activity.pendingResults.add(rec.ref);
5698        }
5699        return rec;
5700    }
5701
5702    @Override
5703    public void cancelIntentSender(IIntentSender sender) {
5704        if (!(sender instanceof PendingIntentRecord)) {
5705            return;
5706        }
5707        synchronized(this) {
5708            PendingIntentRecord rec = (PendingIntentRecord)sender;
5709            try {
5710                int uid = AppGlobals.getPackageManager()
5711                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5712                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5713                    String msg = "Permission Denial: cancelIntentSender() from pid="
5714                        + Binder.getCallingPid()
5715                        + ", uid=" + Binder.getCallingUid()
5716                        + " is not allowed to cancel packges "
5717                        + rec.key.packageName;
5718                    Slog.w(TAG, msg);
5719                    throw new SecurityException(msg);
5720                }
5721            } catch (RemoteException e) {
5722                throw new SecurityException(e);
5723            }
5724            cancelIntentSenderLocked(rec, true);
5725        }
5726    }
5727
5728    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5729        rec.canceled = true;
5730        mIntentSenderRecords.remove(rec.key);
5731        if (cleanActivity && rec.key.activity != null) {
5732            rec.key.activity.pendingResults.remove(rec.ref);
5733        }
5734    }
5735
5736    @Override
5737    public String getPackageForIntentSender(IIntentSender pendingResult) {
5738        if (!(pendingResult instanceof PendingIntentRecord)) {
5739            return null;
5740        }
5741        try {
5742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5743            return res.key.packageName;
5744        } catch (ClassCastException e) {
5745        }
5746        return null;
5747    }
5748
5749    @Override
5750    public int getUidForIntentSender(IIntentSender sender) {
5751        if (sender instanceof PendingIntentRecord) {
5752            try {
5753                PendingIntentRecord res = (PendingIntentRecord)sender;
5754                return res.uid;
5755            } catch (ClassCastException e) {
5756            }
5757        }
5758        return -1;
5759    }
5760
5761    @Override
5762    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5763        if (!(pendingResult instanceof PendingIntentRecord)) {
5764            return false;
5765        }
5766        try {
5767            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5768            if (res.key.allIntents == null) {
5769                return false;
5770            }
5771            for (int i=0; i<res.key.allIntents.length; i++) {
5772                Intent intent = res.key.allIntents[i];
5773                if (intent.getPackage() != null && intent.getComponent() != null) {
5774                    return false;
5775                }
5776            }
5777            return true;
5778        } catch (ClassCastException e) {
5779        }
5780        return false;
5781    }
5782
5783    @Override
5784    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5785        if (!(pendingResult instanceof PendingIntentRecord)) {
5786            return false;
5787        }
5788        try {
5789            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5790            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5791                return true;
5792            }
5793            return false;
5794        } catch (ClassCastException e) {
5795        }
5796        return false;
5797    }
5798
5799    @Override
5800    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5801        if (!(pendingResult instanceof PendingIntentRecord)) {
5802            return null;
5803        }
5804        try {
5805            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5806            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5807        } catch (ClassCastException e) {
5808        }
5809        return null;
5810    }
5811
5812    @Override
5813    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5814        if (!(pendingResult instanceof PendingIntentRecord)) {
5815            return null;
5816        }
5817        try {
5818            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5819            Intent intent = res.key.requestIntent;
5820            if (intent != null) {
5821                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5822                        || res.lastTagPrefix.equals(prefix))) {
5823                    return res.lastTag;
5824                }
5825                res.lastTagPrefix = prefix;
5826                StringBuilder sb = new StringBuilder(128);
5827                if (prefix != null) {
5828                    sb.append(prefix);
5829                }
5830                if (intent.getAction() != null) {
5831                    sb.append(intent.getAction());
5832                } else if (intent.getComponent() != null) {
5833                    intent.getComponent().appendShortString(sb);
5834                } else {
5835                    sb.append("?");
5836                }
5837                return res.lastTag = sb.toString();
5838            }
5839        } catch (ClassCastException e) {
5840        }
5841        return null;
5842    }
5843
5844    @Override
5845    public void setProcessLimit(int max) {
5846        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5847                "setProcessLimit()");
5848        synchronized (this) {
5849            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5850            mProcessLimitOverride = max;
5851        }
5852        trimApplications();
5853    }
5854
5855    @Override
5856    public int getProcessLimit() {
5857        synchronized (this) {
5858            return mProcessLimitOverride;
5859        }
5860    }
5861
5862    void foregroundTokenDied(ForegroundToken token) {
5863        synchronized (ActivityManagerService.this) {
5864            synchronized (mPidsSelfLocked) {
5865                ForegroundToken cur
5866                    = mForegroundProcesses.get(token.pid);
5867                if (cur != token) {
5868                    return;
5869                }
5870                mForegroundProcesses.remove(token.pid);
5871                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5872                if (pr == null) {
5873                    return;
5874                }
5875                pr.forcingToForeground = null;
5876                updateProcessForegroundLocked(pr, false, false);
5877            }
5878            updateOomAdjLocked();
5879        }
5880    }
5881
5882    @Override
5883    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5884        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5885                "setProcessForeground()");
5886        synchronized(this) {
5887            boolean changed = false;
5888
5889            synchronized (mPidsSelfLocked) {
5890                ProcessRecord pr = mPidsSelfLocked.get(pid);
5891                if (pr == null && isForeground) {
5892                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5893                    return;
5894                }
5895                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5896                if (oldToken != null) {
5897                    oldToken.token.unlinkToDeath(oldToken, 0);
5898                    mForegroundProcesses.remove(pid);
5899                    if (pr != null) {
5900                        pr.forcingToForeground = null;
5901                    }
5902                    changed = true;
5903                }
5904                if (isForeground && token != null) {
5905                    ForegroundToken newToken = new ForegroundToken() {
5906                        @Override
5907                        public void binderDied() {
5908                            foregroundTokenDied(this);
5909                        }
5910                    };
5911                    newToken.pid = pid;
5912                    newToken.token = token;
5913                    try {
5914                        token.linkToDeath(newToken, 0);
5915                        mForegroundProcesses.put(pid, newToken);
5916                        pr.forcingToForeground = token;
5917                        changed = true;
5918                    } catch (RemoteException e) {
5919                        // If the process died while doing this, we will later
5920                        // do the cleanup with the process death link.
5921                    }
5922                }
5923            }
5924
5925            if (changed) {
5926                updateOomAdjLocked();
5927            }
5928        }
5929    }
5930
5931    // =========================================================
5932    // PERMISSIONS
5933    // =========================================================
5934
5935    static class PermissionController extends IPermissionController.Stub {
5936        ActivityManagerService mActivityManagerService;
5937        PermissionController(ActivityManagerService activityManagerService) {
5938            mActivityManagerService = activityManagerService;
5939        }
5940
5941        @Override
5942        public boolean checkPermission(String permission, int pid, int uid) {
5943            return mActivityManagerService.checkPermission(permission, pid,
5944                    uid) == PackageManager.PERMISSION_GRANTED;
5945        }
5946    }
5947
5948    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5949        @Override
5950        public int checkComponentPermission(String permission, int pid, int uid,
5951                int owningUid, boolean exported) {
5952            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5953                    owningUid, exported);
5954        }
5955
5956        @Override
5957        public Object getAMSLock() {
5958            return ActivityManagerService.this;
5959        }
5960    }
5961
5962    /**
5963     * This can be called with or without the global lock held.
5964     */
5965    int checkComponentPermission(String permission, int pid, int uid,
5966            int owningUid, boolean exported) {
5967        // We might be performing an operation on behalf of an indirect binder
5968        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5969        // client identity accordingly before proceeding.
5970        Identity tlsIdentity = sCallerIdentity.get();
5971        if (tlsIdentity != null) {
5972            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5973                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5974            uid = tlsIdentity.uid;
5975            pid = tlsIdentity.pid;
5976        }
5977
5978        if (pid == MY_PID) {
5979            return PackageManager.PERMISSION_GRANTED;
5980        }
5981
5982        return ActivityManager.checkComponentPermission(permission, uid,
5983                owningUid, exported);
5984    }
5985
5986    /**
5987     * As the only public entry point for permissions checking, this method
5988     * can enforce the semantic that requesting a check on a null global
5989     * permission is automatically denied.  (Internally a null permission
5990     * string is used when calling {@link #checkComponentPermission} in cases
5991     * when only uid-based security is needed.)
5992     *
5993     * This can be called with or without the global lock held.
5994     */
5995    @Override
5996    public int checkPermission(String permission, int pid, int uid) {
5997        if (permission == null) {
5998            return PackageManager.PERMISSION_DENIED;
5999        }
6000        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6001    }
6002
6003    /**
6004     * Binder IPC calls go through the public entry point.
6005     * This can be called with or without the global lock held.
6006     */
6007    int checkCallingPermission(String permission) {
6008        return checkPermission(permission,
6009                Binder.getCallingPid(),
6010                UserHandle.getAppId(Binder.getCallingUid()));
6011    }
6012
6013    /**
6014     * This can be called with or without the global lock held.
6015     */
6016    void enforceCallingPermission(String permission, String func) {
6017        if (checkCallingPermission(permission)
6018                == PackageManager.PERMISSION_GRANTED) {
6019            return;
6020        }
6021
6022        String msg = "Permission Denial: " + func + " from pid="
6023                + Binder.getCallingPid()
6024                + ", uid=" + Binder.getCallingUid()
6025                + " requires " + permission;
6026        Slog.w(TAG, msg);
6027        throw new SecurityException(msg);
6028    }
6029
6030    /**
6031     * Determine if UID is holding permissions required to access {@link Uri} in
6032     * the given {@link ProviderInfo}. Final permission checking is always done
6033     * in {@link ContentProvider}.
6034     */
6035    private final boolean checkHoldingPermissionsLocked(
6036            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6037        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6038                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6039        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6040            return false;
6041        }
6042
6043        if (pi.applicationInfo.uid == uid) {
6044            return true;
6045        } else if (!pi.exported) {
6046            return false;
6047        }
6048
6049        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6050        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6051        try {
6052            // check if target holds top-level <provider> permissions
6053            if (!readMet && pi.readPermission != null
6054                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6055                readMet = true;
6056            }
6057            if (!writeMet && pi.writePermission != null
6058                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6059                writeMet = true;
6060            }
6061
6062            // track if unprotected read/write is allowed; any denied
6063            // <path-permission> below removes this ability
6064            boolean allowDefaultRead = pi.readPermission == null;
6065            boolean allowDefaultWrite = pi.writePermission == null;
6066
6067            // check if target holds any <path-permission> that match uri
6068            final PathPermission[] pps = pi.pathPermissions;
6069            if (pps != null) {
6070                final String path = grantUri.uri.getPath();
6071                int i = pps.length;
6072                while (i > 0 && (!readMet || !writeMet)) {
6073                    i--;
6074                    PathPermission pp = pps[i];
6075                    if (pp.match(path)) {
6076                        if (!readMet) {
6077                            final String pprperm = pp.getReadPermission();
6078                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6079                                    + pprperm + " for " + pp.getPath()
6080                                    + ": match=" + pp.match(path)
6081                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6082                            if (pprperm != null) {
6083                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6084                                    readMet = true;
6085                                } else {
6086                                    allowDefaultRead = false;
6087                                }
6088                            }
6089                        }
6090                        if (!writeMet) {
6091                            final String ppwperm = pp.getWritePermission();
6092                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6093                                    + ppwperm + " for " + pp.getPath()
6094                                    + ": match=" + pp.match(path)
6095                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6096                            if (ppwperm != null) {
6097                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6098                                    writeMet = true;
6099                                } else {
6100                                    allowDefaultWrite = false;
6101                                }
6102                            }
6103                        }
6104                    }
6105                }
6106            }
6107
6108            // grant unprotected <provider> read/write, if not blocked by
6109            // <path-permission> above
6110            if (allowDefaultRead) readMet = true;
6111            if (allowDefaultWrite) writeMet = true;
6112
6113        } catch (RemoteException e) {
6114            return false;
6115        }
6116
6117        return readMet && writeMet;
6118    }
6119
6120    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6121        ProviderInfo pi = null;
6122        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6123        if (cpr != null) {
6124            pi = cpr.info;
6125        } else {
6126            try {
6127                pi = AppGlobals.getPackageManager().resolveContentProvider(
6128                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6129            } catch (RemoteException ex) {
6130            }
6131        }
6132        return pi;
6133    }
6134
6135    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6136        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6137        if (targetUris != null) {
6138            return targetUris.get(grantUri);
6139        }
6140        return null;
6141    }
6142
6143    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6144            String targetPkg, int targetUid, GrantUri grantUri) {
6145        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6146        if (targetUris == null) {
6147            targetUris = Maps.newArrayMap();
6148            mGrantedUriPermissions.put(targetUid, targetUris);
6149        }
6150
6151        UriPermission perm = targetUris.get(grantUri);
6152        if (perm == null) {
6153            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6154            targetUris.put(grantUri, perm);
6155        }
6156
6157        return perm;
6158    }
6159
6160    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6161            final int modeFlags) {
6162        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6163        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6164                : UriPermission.STRENGTH_OWNED;
6165
6166        // Root gets to do everything.
6167        if (uid == 0) {
6168            return true;
6169        }
6170
6171        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6172        if (perms == null) return false;
6173
6174        // First look for exact match
6175        final UriPermission exactPerm = perms.get(grantUri);
6176        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6177            return true;
6178        }
6179
6180        // No exact match, look for prefixes
6181        final int N = perms.size();
6182        for (int i = 0; i < N; i++) {
6183            final UriPermission perm = perms.valueAt(i);
6184            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6185                    && perm.getStrength(modeFlags) >= minStrength) {
6186                return true;
6187            }
6188        }
6189
6190        return false;
6191    }
6192
6193    @Override
6194    public int checkUriPermission(Uri uri, int pid, int uid,
6195            final int modeFlags, int userId) {
6196        enforceNotIsolatedCaller("checkUriPermission");
6197
6198        // Another redirected-binder-call permissions check as in
6199        // {@link checkComponentPermission}.
6200        Identity tlsIdentity = sCallerIdentity.get();
6201        if (tlsIdentity != null) {
6202            uid = tlsIdentity.uid;
6203            pid = tlsIdentity.pid;
6204        }
6205
6206        // Our own process gets to do everything.
6207        if (pid == MY_PID) {
6208            return PackageManager.PERMISSION_GRANTED;
6209        }
6210        synchronized (this) {
6211            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6212                    ? PackageManager.PERMISSION_GRANTED
6213                    : PackageManager.PERMISSION_DENIED;
6214        }
6215    }
6216
6217    /**
6218     * Check if the targetPkg can be granted permission to access uri by
6219     * the callingUid using the given modeFlags.  Throws a security exception
6220     * if callingUid is not allowed to do this.  Returns the uid of the target
6221     * if the URI permission grant should be performed; returns -1 if it is not
6222     * needed (for example targetPkg already has permission to access the URI).
6223     * If you already know the uid of the target, you can supply it in
6224     * lastTargetUid else set that to -1.
6225     */
6226    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6227            final int modeFlags, int lastTargetUid) {
6228        if (!Intent.isAccessUriMode(modeFlags)) {
6229            return -1;
6230        }
6231
6232        if (targetPkg != null) {
6233            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6234                    "Checking grant " + targetPkg + " permission to " + grantUri);
6235        }
6236
6237        final IPackageManager pm = AppGlobals.getPackageManager();
6238
6239        // If this is not a content: uri, we can't do anything with it.
6240        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6241            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6242                    "Can't grant URI permission for non-content URI: " + grantUri);
6243            return -1;
6244        }
6245
6246        final String authority = grantUri.uri.getAuthority();
6247        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6248        if (pi == null) {
6249            Slog.w(TAG, "No content provider found for permission check: " +
6250                    grantUri.uri.toSafeString());
6251            return -1;
6252        }
6253
6254        int targetUid = lastTargetUid;
6255        if (targetUid < 0 && targetPkg != null) {
6256            try {
6257                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6258                if (targetUid < 0) {
6259                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6260                            "Can't grant URI permission no uid for: " + targetPkg);
6261                    return -1;
6262                }
6263            } catch (RemoteException ex) {
6264                return -1;
6265            }
6266        }
6267
6268        if (targetUid >= 0) {
6269            // First...  does the target actually need this permission?
6270            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6271                // No need to grant the target this permission.
6272                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6273                        "Target " + targetPkg + " already has full permission to " + grantUri);
6274                return -1;
6275            }
6276        } else {
6277            // First...  there is no target package, so can anyone access it?
6278            boolean allowed = pi.exported;
6279            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6280                if (pi.readPermission != null) {
6281                    allowed = false;
6282                }
6283            }
6284            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6285                if (pi.writePermission != null) {
6286                    allowed = false;
6287                }
6288            }
6289            if (allowed) {
6290                return -1;
6291            }
6292        }
6293
6294        // Second...  is the provider allowing granting of URI permissions?
6295        if (!pi.grantUriPermissions) {
6296            throw new SecurityException("Provider " + pi.packageName
6297                    + "/" + pi.name
6298                    + " does not allow granting of Uri permissions (uri "
6299                    + grantUri + ")");
6300        }
6301        if (pi.uriPermissionPatterns != null) {
6302            final int N = pi.uriPermissionPatterns.length;
6303            boolean allowed = false;
6304            for (int i=0; i<N; i++) {
6305                if (pi.uriPermissionPatterns[i] != null
6306                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6307                    allowed = true;
6308                    break;
6309                }
6310            }
6311            if (!allowed) {
6312                throw new SecurityException("Provider " + pi.packageName
6313                        + "/" + pi.name
6314                        + " does not allow granting of permission to path of Uri "
6315                        + grantUri);
6316            }
6317        }
6318
6319        // Third...  does the caller itself have permission to access
6320        // this uri?
6321        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6322            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6323                // Require they hold a strong enough Uri permission
6324                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6325                    throw new SecurityException("Uid " + callingUid
6326                            + " does not have permission to uri " + grantUri);
6327                }
6328            }
6329        }
6330        return targetUid;
6331    }
6332
6333    @Override
6334    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6335            final int modeFlags, int userId) {
6336        enforceNotIsolatedCaller("checkGrantUriPermission");
6337        synchronized(this) {
6338            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6339                    new GrantUri(userId, uri, false), modeFlags, -1);
6340        }
6341    }
6342
6343    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6344            final int modeFlags, UriPermissionOwner owner) {
6345        if (!Intent.isAccessUriMode(modeFlags)) {
6346            return;
6347        }
6348
6349        // So here we are: the caller has the assumed permission
6350        // to the uri, and the target doesn't.  Let's now give this to
6351        // the target.
6352
6353        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6354                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6355
6356        final String authority = grantUri.uri.getAuthority();
6357        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6358        if (pi == null) {
6359            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6360            return;
6361        }
6362
6363        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6364            grantUri.prefix = true;
6365        }
6366        final UriPermission perm = findOrCreateUriPermissionLocked(
6367                pi.packageName, targetPkg, targetUid, grantUri);
6368        perm.grantModes(modeFlags, owner);
6369    }
6370
6371    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6372            final int modeFlags, UriPermissionOwner owner) {
6373        if (targetPkg == null) {
6374            throw new NullPointerException("targetPkg");
6375        }
6376
6377        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6378                -1);
6379        if (targetUid < 0) {
6380            return;
6381        }
6382
6383        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6384                owner);
6385    }
6386
6387    static class NeededUriGrants extends ArrayList<GrantUri> {
6388        final String targetPkg;
6389        final int targetUid;
6390        final int flags;
6391
6392        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6393            this.targetPkg = targetPkg;
6394            this.targetUid = targetUid;
6395            this.flags = flags;
6396        }
6397    }
6398
6399    /**
6400     * Like checkGrantUriPermissionLocked, but takes an Intent.
6401     */
6402    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6403            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6404        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6405                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6406                + " clip=" + (intent != null ? intent.getClipData() : null)
6407                + " from " + intent + "; flags=0x"
6408                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6409
6410        if (targetPkg == null) {
6411            throw new NullPointerException("targetPkg");
6412        }
6413
6414        if (intent == null) {
6415            return null;
6416        }
6417        Uri data = intent.getData();
6418        ClipData clip = intent.getClipData();
6419        if (data == null && clip == null) {
6420            return null;
6421        }
6422        final IPackageManager pm = AppGlobals.getPackageManager();
6423        int targetUid;
6424        if (needed != null) {
6425            targetUid = needed.targetUid;
6426        } else {
6427            try {
6428                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6429            } catch (RemoteException ex) {
6430                return null;
6431            }
6432            if (targetUid < 0) {
6433                if (DEBUG_URI_PERMISSION) {
6434                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6435                            + " on user " + targetUserId);
6436                }
6437                return null;
6438            }
6439        }
6440        if (data != null) {
6441            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6442            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6443                    targetUid);
6444            if (targetUid > 0) {
6445                if (needed == null) {
6446                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6447                }
6448                needed.add(grantUri);
6449            }
6450        }
6451        if (clip != null) {
6452            for (int i=0; i<clip.getItemCount(); i++) {
6453                Uri uri = clip.getItemAt(i).getUri();
6454                if (uri != null) {
6455                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6456                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6457                            targetUid);
6458                    if (targetUid > 0) {
6459                        if (needed == null) {
6460                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6461                        }
6462                        needed.add(grantUri);
6463                    }
6464                } else {
6465                    Intent clipIntent = clip.getItemAt(i).getIntent();
6466                    if (clipIntent != null) {
6467                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6468                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6469                        if (newNeeded != null) {
6470                            needed = newNeeded;
6471                        }
6472                    }
6473                }
6474            }
6475        }
6476
6477        return needed;
6478    }
6479
6480    /**
6481     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6482     */
6483    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6484            UriPermissionOwner owner) {
6485        if (needed != null) {
6486            for (int i=0; i<needed.size(); i++) {
6487                GrantUri grantUri = needed.get(i);
6488                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6489                        grantUri, needed.flags, owner);
6490            }
6491        }
6492    }
6493
6494    void grantUriPermissionFromIntentLocked(int callingUid,
6495            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6496        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6497                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6498        if (needed == null) {
6499            return;
6500        }
6501
6502        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6503    }
6504
6505    @Override
6506    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6507            final int modeFlags, int userId) {
6508        enforceNotIsolatedCaller("grantUriPermission");
6509        GrantUri grantUri = new GrantUri(userId, uri, false);
6510        synchronized(this) {
6511            final ProcessRecord r = getRecordForAppLocked(caller);
6512            if (r == null) {
6513                throw new SecurityException("Unable to find app for caller "
6514                        + caller
6515                        + " when granting permission to uri " + grantUri);
6516            }
6517            if (targetPkg == null) {
6518                throw new IllegalArgumentException("null target");
6519            }
6520            if (grantUri == null) {
6521                throw new IllegalArgumentException("null uri");
6522            }
6523
6524            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6525                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6526                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6527                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6528
6529            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6530        }
6531    }
6532
6533    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6534        if (perm.modeFlags == 0) {
6535            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6536                    perm.targetUid);
6537            if (perms != null) {
6538                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6539                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6540
6541                perms.remove(perm.uri);
6542                if (perms.isEmpty()) {
6543                    mGrantedUriPermissions.remove(perm.targetUid);
6544                }
6545            }
6546        }
6547    }
6548
6549    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6550        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6551
6552        final IPackageManager pm = AppGlobals.getPackageManager();
6553        final String authority = grantUri.uri.getAuthority();
6554        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6555        if (pi == null) {
6556            Slog.w(TAG, "No content provider found for permission revoke: "
6557                    + grantUri.toSafeString());
6558            return;
6559        }
6560
6561        // Does the caller have this permission on the URI?
6562        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6563            // Right now, if you are not the original owner of the permission,
6564            // you are not allowed to revoke it.
6565            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6566                throw new SecurityException("Uid " + callingUid
6567                        + " does not have permission to uri " + grantUri);
6568            //}
6569        }
6570
6571        boolean persistChanged = false;
6572
6573        // Go through all of the permissions and remove any that match.
6574        int N = mGrantedUriPermissions.size();
6575        for (int i = 0; i < N; i++) {
6576            final int targetUid = mGrantedUriPermissions.keyAt(i);
6577            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6578
6579            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6580                final UriPermission perm = it.next();
6581                if (perm.uri.sourceUserId == grantUri.sourceUserId
6582                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6583                    if (DEBUG_URI_PERMISSION)
6584                        Slog.v(TAG,
6585                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6586                    persistChanged |= perm.revokeModes(
6587                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6588                    if (perm.modeFlags == 0) {
6589                        it.remove();
6590                    }
6591                }
6592            }
6593
6594            if (perms.isEmpty()) {
6595                mGrantedUriPermissions.remove(targetUid);
6596                N--;
6597                i--;
6598            }
6599        }
6600
6601        if (persistChanged) {
6602            schedulePersistUriGrants();
6603        }
6604    }
6605
6606    @Override
6607    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6608            int userId) {
6609        enforceNotIsolatedCaller("revokeUriPermission");
6610        synchronized(this) {
6611            final ProcessRecord r = getRecordForAppLocked(caller);
6612            if (r == null) {
6613                throw new SecurityException("Unable to find app for caller "
6614                        + caller
6615                        + " when revoking permission to uri " + uri);
6616            }
6617            if (uri == null) {
6618                Slog.w(TAG, "revokeUriPermission: null uri");
6619                return;
6620            }
6621
6622            if (!Intent.isAccessUriMode(modeFlags)) {
6623                return;
6624            }
6625
6626            final IPackageManager pm = AppGlobals.getPackageManager();
6627            final String authority = uri.getAuthority();
6628            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6629            if (pi == null) {
6630                Slog.w(TAG, "No content provider found for permission revoke: "
6631                        + uri.toSafeString());
6632                return;
6633            }
6634
6635            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6636        }
6637    }
6638
6639    /**
6640     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6641     * given package.
6642     *
6643     * @param packageName Package name to match, or {@code null} to apply to all
6644     *            packages.
6645     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6646     *            to all users.
6647     * @param persistable If persistable grants should be removed.
6648     */
6649    private void removeUriPermissionsForPackageLocked(
6650            String packageName, int userHandle, boolean persistable) {
6651        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6652            throw new IllegalArgumentException("Must narrow by either package or user");
6653        }
6654
6655        boolean persistChanged = false;
6656
6657        int N = mGrantedUriPermissions.size();
6658        for (int i = 0; i < N; i++) {
6659            final int targetUid = mGrantedUriPermissions.keyAt(i);
6660            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6661
6662            // Only inspect grants matching user
6663            if (userHandle == UserHandle.USER_ALL
6664                    || userHandle == UserHandle.getUserId(targetUid)) {
6665                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6666                    final UriPermission perm = it.next();
6667
6668                    // Only inspect grants matching package
6669                    if (packageName == null || perm.sourcePkg.equals(packageName)
6670                            || perm.targetPkg.equals(packageName)) {
6671                        persistChanged |= perm.revokeModes(
6672                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6673
6674                        // Only remove when no modes remain; any persisted grants
6675                        // will keep this alive.
6676                        if (perm.modeFlags == 0) {
6677                            it.remove();
6678                        }
6679                    }
6680                }
6681
6682                if (perms.isEmpty()) {
6683                    mGrantedUriPermissions.remove(targetUid);
6684                    N--;
6685                    i--;
6686                }
6687            }
6688        }
6689
6690        if (persistChanged) {
6691            schedulePersistUriGrants();
6692        }
6693    }
6694
6695    @Override
6696    public IBinder newUriPermissionOwner(String name) {
6697        enforceNotIsolatedCaller("newUriPermissionOwner");
6698        synchronized(this) {
6699            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6700            return owner.getExternalTokenLocked();
6701        }
6702    }
6703
6704    @Override
6705    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6706            final int modeFlags, int userId) {
6707        synchronized(this) {
6708            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6709            if (owner == null) {
6710                throw new IllegalArgumentException("Unknown owner: " + token);
6711            }
6712            if (fromUid != Binder.getCallingUid()) {
6713                if (Binder.getCallingUid() != Process.myUid()) {
6714                    // Only system code can grant URI permissions on behalf
6715                    // of other users.
6716                    throw new SecurityException("nice try");
6717                }
6718            }
6719            if (targetPkg == null) {
6720                throw new IllegalArgumentException("null target");
6721            }
6722            if (uri == null) {
6723                throw new IllegalArgumentException("null uri");
6724            }
6725
6726            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6727                    modeFlags, owner);
6728        }
6729    }
6730
6731    @Override
6732    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6733        synchronized(this) {
6734            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6735            if (owner == null) {
6736                throw new IllegalArgumentException("Unknown owner: " + token);
6737            }
6738
6739            if (uri == null) {
6740                owner.removeUriPermissionsLocked(mode);
6741            } else {
6742                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6743            }
6744        }
6745    }
6746
6747    private void schedulePersistUriGrants() {
6748        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6749            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6750                    10 * DateUtils.SECOND_IN_MILLIS);
6751        }
6752    }
6753
6754    private void writeGrantedUriPermissions() {
6755        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6756
6757        // Snapshot permissions so we can persist without lock
6758        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6759        synchronized (this) {
6760            final int size = mGrantedUriPermissions.size();
6761            for (int i = 0; i < size; i++) {
6762                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6763                for (UriPermission perm : perms.values()) {
6764                    if (perm.persistedModeFlags != 0) {
6765                        persist.add(perm.snapshot());
6766                    }
6767                }
6768            }
6769        }
6770
6771        FileOutputStream fos = null;
6772        try {
6773            fos = mGrantFile.startWrite();
6774
6775            XmlSerializer out = new FastXmlSerializer();
6776            out.setOutput(fos, "utf-8");
6777            out.startDocument(null, true);
6778            out.startTag(null, TAG_URI_GRANTS);
6779            for (UriPermission.Snapshot perm : persist) {
6780                out.startTag(null, TAG_URI_GRANT);
6781                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6782                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6783                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6784                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6785                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6786                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6787                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6788                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6789                out.endTag(null, TAG_URI_GRANT);
6790            }
6791            out.endTag(null, TAG_URI_GRANTS);
6792            out.endDocument();
6793
6794            mGrantFile.finishWrite(fos);
6795        } catch (IOException e) {
6796            if (fos != null) {
6797                mGrantFile.failWrite(fos);
6798            }
6799        }
6800    }
6801
6802    private void readGrantedUriPermissionsLocked() {
6803        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6804
6805        final long now = System.currentTimeMillis();
6806
6807        FileInputStream fis = null;
6808        try {
6809            fis = mGrantFile.openRead();
6810            final XmlPullParser in = Xml.newPullParser();
6811            in.setInput(fis, null);
6812
6813            int type;
6814            while ((type = in.next()) != END_DOCUMENT) {
6815                final String tag = in.getName();
6816                if (type == START_TAG) {
6817                    if (TAG_URI_GRANT.equals(tag)) {
6818                        final int sourceUserId;
6819                        final int targetUserId;
6820                        final int userHandle = readIntAttribute(in,
6821                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6822                        if (userHandle != UserHandle.USER_NULL) {
6823                            // For backwards compatibility.
6824                            sourceUserId = userHandle;
6825                            targetUserId = userHandle;
6826                        } else {
6827                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6828                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6829                        }
6830                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6831                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6832                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6833                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6834                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6835                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6836
6837                        // Sanity check that provider still belongs to source package
6838                        final ProviderInfo pi = getProviderInfoLocked(
6839                                uri.getAuthority(), sourceUserId);
6840                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6841                            int targetUid = -1;
6842                            try {
6843                                targetUid = AppGlobals.getPackageManager()
6844                                        .getPackageUid(targetPkg, targetUserId);
6845                            } catch (RemoteException e) {
6846                            }
6847                            if (targetUid != -1) {
6848                                final UriPermission perm = findOrCreateUriPermissionLocked(
6849                                        sourcePkg, targetPkg, targetUid,
6850                                        new GrantUri(sourceUserId, uri, prefix));
6851                                perm.initPersistedModes(modeFlags, createdTime);
6852                            }
6853                        } else {
6854                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6855                                    + " but instead found " + pi);
6856                        }
6857                    }
6858                }
6859            }
6860        } catch (FileNotFoundException e) {
6861            // Missing grants is okay
6862        } catch (IOException e) {
6863            Log.wtf(TAG, "Failed reading Uri grants", e);
6864        } catch (XmlPullParserException e) {
6865            Log.wtf(TAG, "Failed reading Uri grants", e);
6866        } finally {
6867            IoUtils.closeQuietly(fis);
6868        }
6869    }
6870
6871    @Override
6872    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6873        enforceNotIsolatedCaller("takePersistableUriPermission");
6874
6875        Preconditions.checkFlagsArgument(modeFlags,
6876                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6877
6878        synchronized (this) {
6879            final int callingUid = Binder.getCallingUid();
6880            boolean persistChanged = false;
6881            GrantUri grantUri = new GrantUri(userId, uri, false);
6882
6883            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6884                    new GrantUri(userId, uri, false));
6885            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6886                    new GrantUri(userId, uri, true));
6887
6888            final boolean exactValid = (exactPerm != null)
6889                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6890            final boolean prefixValid = (prefixPerm != null)
6891                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6892
6893            if (!(exactValid || prefixValid)) {
6894                throw new SecurityException("No persistable permission grants found for UID "
6895                        + callingUid + " and Uri " + grantUri.toSafeString());
6896            }
6897
6898            if (exactValid) {
6899                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6900            }
6901            if (prefixValid) {
6902                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6903            }
6904
6905            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6906
6907            if (persistChanged) {
6908                schedulePersistUriGrants();
6909            }
6910        }
6911    }
6912
6913    @Override
6914    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6915        enforceNotIsolatedCaller("releasePersistableUriPermission");
6916
6917        Preconditions.checkFlagsArgument(modeFlags,
6918                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6919
6920        synchronized (this) {
6921            final int callingUid = Binder.getCallingUid();
6922            boolean persistChanged = false;
6923
6924            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6925                    new GrantUri(userId, uri, false));
6926            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6927                    new GrantUri(userId, uri, true));
6928            if (exactPerm == null && prefixPerm == null) {
6929                throw new SecurityException("No permission grants found for UID " + callingUid
6930                        + " and Uri " + uri.toSafeString());
6931            }
6932
6933            if (exactPerm != null) {
6934                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6935                removeUriPermissionIfNeededLocked(exactPerm);
6936            }
6937            if (prefixPerm != null) {
6938                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6939                removeUriPermissionIfNeededLocked(prefixPerm);
6940            }
6941
6942            if (persistChanged) {
6943                schedulePersistUriGrants();
6944            }
6945        }
6946    }
6947
6948    /**
6949     * Prune any older {@link UriPermission} for the given UID until outstanding
6950     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6951     *
6952     * @return if any mutations occured that require persisting.
6953     */
6954    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6955        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6956        if (perms == null) return false;
6957        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6958
6959        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6960        for (UriPermission perm : perms.values()) {
6961            if (perm.persistedModeFlags != 0) {
6962                persisted.add(perm);
6963            }
6964        }
6965
6966        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6967        if (trimCount <= 0) return false;
6968
6969        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6970        for (int i = 0; i < trimCount; i++) {
6971            final UriPermission perm = persisted.get(i);
6972
6973            if (DEBUG_URI_PERMISSION) {
6974                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6975            }
6976
6977            perm.releasePersistableModes(~0);
6978            removeUriPermissionIfNeededLocked(perm);
6979        }
6980
6981        return true;
6982    }
6983
6984    @Override
6985    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6986            String packageName, boolean incoming) {
6987        enforceNotIsolatedCaller("getPersistedUriPermissions");
6988        Preconditions.checkNotNull(packageName, "packageName");
6989
6990        final int callingUid = Binder.getCallingUid();
6991        final IPackageManager pm = AppGlobals.getPackageManager();
6992        try {
6993            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6994            if (packageUid != callingUid) {
6995                throw new SecurityException(
6996                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6997            }
6998        } catch (RemoteException e) {
6999            throw new SecurityException("Failed to verify package name ownership");
7000        }
7001
7002        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7003        synchronized (this) {
7004            if (incoming) {
7005                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7006                        callingUid);
7007                if (perms == null) {
7008                    Slog.w(TAG, "No permission grants found for " + packageName);
7009                } else {
7010                    for (UriPermission perm : perms.values()) {
7011                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7012                            result.add(perm.buildPersistedPublicApiObject());
7013                        }
7014                    }
7015                }
7016            } else {
7017                final int size = mGrantedUriPermissions.size();
7018                for (int i = 0; i < size; i++) {
7019                    final ArrayMap<GrantUri, UriPermission> perms =
7020                            mGrantedUriPermissions.valueAt(i);
7021                    for (UriPermission perm : perms.values()) {
7022                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7023                            result.add(perm.buildPersistedPublicApiObject());
7024                        }
7025                    }
7026                }
7027            }
7028        }
7029        return new ParceledListSlice<android.content.UriPermission>(result);
7030    }
7031
7032    @Override
7033    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7034        synchronized (this) {
7035            ProcessRecord app =
7036                who != null ? getRecordForAppLocked(who) : null;
7037            if (app == null) return;
7038
7039            Message msg = Message.obtain();
7040            msg.what = WAIT_FOR_DEBUGGER_MSG;
7041            msg.obj = app;
7042            msg.arg1 = waiting ? 1 : 0;
7043            mHandler.sendMessage(msg);
7044        }
7045    }
7046
7047    @Override
7048    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7049        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7050        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7051        outInfo.availMem = Process.getFreeMemory();
7052        outInfo.totalMem = Process.getTotalMemory();
7053        outInfo.threshold = homeAppMem;
7054        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7055        outInfo.hiddenAppThreshold = cachedAppMem;
7056        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7057                ProcessList.SERVICE_ADJ);
7058        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7059                ProcessList.VISIBLE_APP_ADJ);
7060        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7061                ProcessList.FOREGROUND_APP_ADJ);
7062    }
7063
7064    // =========================================================
7065    // TASK MANAGEMENT
7066    // =========================================================
7067
7068    @Override
7069    public List<IAppTask> getAppTasks() {
7070        int callingUid = Binder.getCallingUid();
7071        long ident = Binder.clearCallingIdentity();
7072        synchronized(this) {
7073            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7074            try {
7075                if (localLOGV) Slog.v(TAG, "getAppTasks");
7076
7077                final int N = mRecentTasks.size();
7078                for (int i = 0; i < N; i++) {
7079                    TaskRecord tr = mRecentTasks.get(i);
7080                    // Skip tasks that are not created by the caller
7081                    if (tr.creatorUid == callingUid) {
7082                        ActivityManager.RecentTaskInfo taskInfo =
7083                                createRecentTaskInfoFromTaskRecord(tr);
7084                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7085                        list.add(taskImpl);
7086                    }
7087                }
7088            } finally {
7089                Binder.restoreCallingIdentity(ident);
7090            }
7091            return list;
7092        }
7093    }
7094
7095    @Override
7096    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7097        final int callingUid = Binder.getCallingUid();
7098        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7099
7100        synchronized(this) {
7101            if (localLOGV) Slog.v(
7102                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7103
7104            final boolean allowed = checkCallingPermission(
7105                    android.Manifest.permission.GET_TASKS)
7106                    == PackageManager.PERMISSION_GRANTED;
7107            if (!allowed) {
7108                Slog.w(TAG, "getTasks: caller " + callingUid
7109                        + " does not hold GET_TASKS; limiting output");
7110            }
7111
7112            // TODO: Improve with MRU list from all ActivityStacks.
7113            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7114        }
7115
7116        return list;
7117    }
7118
7119    TaskRecord getMostRecentTask() {
7120        return mRecentTasks.get(0);
7121    }
7122
7123    /**
7124     * Creates a new RecentTaskInfo from a TaskRecord.
7125     */
7126    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7127        // Update the task description to reflect any changes in the task stack
7128        tr.updateTaskDescription();
7129
7130        // Compose the recent task info
7131        ActivityManager.RecentTaskInfo rti
7132                = new ActivityManager.RecentTaskInfo();
7133        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7134        rti.persistentId = tr.taskId;
7135        rti.baseIntent = new Intent(tr.getBaseIntent());
7136        rti.origActivity = tr.origActivity;
7137        rti.description = tr.lastDescription;
7138        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7139        rti.userId = tr.userId;
7140        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7141        return rti;
7142    }
7143
7144    @Override
7145    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7146            int flags, int userId) {
7147        final int callingUid = Binder.getCallingUid();
7148        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7149                false, true, "getRecentTasks", null);
7150
7151        synchronized (this) {
7152            final boolean allowed = checkCallingPermission(
7153                    android.Manifest.permission.GET_TASKS)
7154                    == PackageManager.PERMISSION_GRANTED;
7155            if (!allowed) {
7156                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7157                        + " does not hold GET_TASKS; limiting output");
7158            }
7159            final boolean detailed = checkCallingPermission(
7160                    android.Manifest.permission.GET_DETAILED_TASKS)
7161                    == PackageManager.PERMISSION_GRANTED;
7162
7163            IPackageManager pm = AppGlobals.getPackageManager();
7164
7165            final int N = mRecentTasks.size();
7166            ArrayList<ActivityManager.RecentTaskInfo> res
7167                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7168                            maxNum < N ? maxNum : N);
7169
7170            final Set<Integer> includedUsers;
7171            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7172                includedUsers = getProfileIdsLocked(userId);
7173            } else {
7174                includedUsers = new HashSet<Integer>();
7175            }
7176            includedUsers.add(Integer.valueOf(userId));
7177            for (int i=0; i<N && maxNum > 0; i++) {
7178                TaskRecord tr = mRecentTasks.get(i);
7179                // Only add calling user or related users recent tasks
7180                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7181
7182                // Return the entry if desired by the caller.  We always return
7183                // the first entry, because callers always expect this to be the
7184                // foreground app.  We may filter others if the caller has
7185                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7186                // we should exclude the entry.
7187
7188                if (i == 0
7189                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7190                        || (tr.intent == null)
7191                        || ((tr.intent.getFlags()
7192                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7193                    if (!allowed) {
7194                        // If the caller doesn't have the GET_TASKS permission, then only
7195                        // allow them to see a small subset of tasks -- their own and home.
7196                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7197                            continue;
7198                        }
7199                    }
7200
7201                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7202                    if (!detailed) {
7203                        rti.baseIntent.replaceExtras((Bundle)null);
7204                    }
7205
7206                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7207                        // Check whether this activity is currently available.
7208                        try {
7209                            if (rti.origActivity != null) {
7210                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7211                                        == null) {
7212                                    continue;
7213                                }
7214                            } else if (rti.baseIntent != null) {
7215                                if (pm.queryIntentActivities(rti.baseIntent,
7216                                        null, 0, userId) == null) {
7217                                    continue;
7218                                }
7219                            }
7220                        } catch (RemoteException e) {
7221                            // Will never happen.
7222                        }
7223                    }
7224
7225                    res.add(rti);
7226                    maxNum--;
7227                }
7228            }
7229            return res;
7230        }
7231    }
7232
7233    private TaskRecord recentTaskForIdLocked(int id) {
7234        final int N = mRecentTasks.size();
7235            for (int i=0; i<N; i++) {
7236                TaskRecord tr = mRecentTasks.get(i);
7237                if (tr.taskId == id) {
7238                    return tr;
7239                }
7240            }
7241            return null;
7242    }
7243
7244    @Override
7245    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7246        synchronized (this) {
7247            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7248                    "getTaskThumbnails()");
7249            TaskRecord tr = recentTaskForIdLocked(id);
7250            if (tr != null) {
7251                return tr.getTaskThumbnailsLocked();
7252            }
7253        }
7254        return null;
7255    }
7256
7257    @Override
7258    public Bitmap getTaskTopThumbnail(int id) {
7259        synchronized (this) {
7260            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7261                    "getTaskTopThumbnail()");
7262            TaskRecord tr = recentTaskForIdLocked(id);
7263            if (tr != null) {
7264                return tr.getTaskTopThumbnailLocked();
7265            }
7266        }
7267        return null;
7268    }
7269
7270    @Override
7271    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7272        synchronized (this) {
7273            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7274            if (r != null) {
7275                r.taskDescription = td;
7276                r.task.updateTaskDescription();
7277            }
7278        }
7279    }
7280
7281    @Override
7282    public boolean removeSubTask(int taskId, int subTaskIndex) {
7283        synchronized (this) {
7284            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7285                    "removeSubTask()");
7286            long ident = Binder.clearCallingIdentity();
7287            try {
7288                TaskRecord tr = recentTaskForIdLocked(taskId);
7289                if (tr != null) {
7290                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7291                }
7292                return false;
7293            } finally {
7294                Binder.restoreCallingIdentity(ident);
7295            }
7296        }
7297    }
7298
7299    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7300        if (!pr.killedByAm) {
7301            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7302            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7303                    pr.processName, pr.setAdj, reason);
7304            pr.killedByAm = true;
7305            Process.killProcessQuiet(pr.pid);
7306        }
7307    }
7308
7309    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7310        tr.disposeThumbnail();
7311        mRecentTasks.remove(tr);
7312        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7313        Intent baseIntent = new Intent(
7314                tr.intent != null ? tr.intent : tr.affinityIntent);
7315        ComponentName component = baseIntent.getComponent();
7316        if (component == null) {
7317            Slog.w(TAG, "Now component for base intent of task: " + tr);
7318            return;
7319        }
7320
7321        // Find any running services associated with this app.
7322        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7323
7324        if (killProcesses) {
7325            // Find any running processes associated with this app.
7326            final String pkg = component.getPackageName();
7327            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7328            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7329            for (int i=0; i<pmap.size(); i++) {
7330                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7331                for (int j=0; j<uids.size(); j++) {
7332                    ProcessRecord proc = uids.valueAt(j);
7333                    if (proc.userId != tr.userId) {
7334                        continue;
7335                    }
7336                    if (!proc.pkgList.containsKey(pkg)) {
7337                        continue;
7338                    }
7339                    procs.add(proc);
7340                }
7341            }
7342
7343            // Kill the running processes.
7344            for (int i=0; i<procs.size(); i++) {
7345                ProcessRecord pr = procs.get(i);
7346                if (pr == mHomeProcess) {
7347                    // Don't kill the home process along with tasks from the same package.
7348                    continue;
7349                }
7350                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7351                    killUnneededProcessLocked(pr, "remove task");
7352                } else {
7353                    pr.waitingToKill = "remove task";
7354                }
7355            }
7356        }
7357    }
7358
7359    /**
7360     * Removes the task with the specified task id.
7361     *
7362     * @param taskId Identifier of the task to be removed.
7363     * @param flags Additional operational flags.  May be 0 or
7364     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7365     * @return Returns true if the given task was found and removed.
7366     */
7367    private boolean removeTaskByIdLocked(int taskId, int flags) {
7368        TaskRecord tr = recentTaskForIdLocked(taskId);
7369        if (tr != null) {
7370            tr.removeTaskActivitiesLocked(-1, false);
7371            cleanUpRemovedTaskLocked(tr, flags);
7372            if (tr.isPersistable) {
7373                notifyTaskPersisterLocked(tr, true);
7374            }
7375            return true;
7376        }
7377        return false;
7378    }
7379
7380    @Override
7381    public boolean removeTask(int taskId, int flags) {
7382        synchronized (this) {
7383            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7384                    "removeTask()");
7385            long ident = Binder.clearCallingIdentity();
7386            try {
7387                return removeTaskByIdLocked(taskId, flags);
7388            } finally {
7389                Binder.restoreCallingIdentity(ident);
7390            }
7391        }
7392    }
7393
7394    /**
7395     * TODO: Add mController hook
7396     */
7397    @Override
7398    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7399        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7400                "moveTaskToFront()");
7401
7402        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7403        synchronized(this) {
7404            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7405                    Binder.getCallingUid(), "Task to front")) {
7406                ActivityOptions.abort(options);
7407                return;
7408            }
7409            final long origId = Binder.clearCallingIdentity();
7410            try {
7411                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7412                if (task == null) {
7413                    return;
7414                }
7415                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7416                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7417                    return;
7418                }
7419                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7420            } finally {
7421                Binder.restoreCallingIdentity(origId);
7422            }
7423            ActivityOptions.abort(options);
7424        }
7425    }
7426
7427    @Override
7428    public void moveTaskToBack(int taskId) {
7429        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7430                "moveTaskToBack()");
7431
7432        synchronized(this) {
7433            TaskRecord tr = recentTaskForIdLocked(taskId);
7434            if (tr != null) {
7435                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7436                ActivityStack stack = tr.stack;
7437                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7438                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7439                            Binder.getCallingUid(), "Task to back")) {
7440                        return;
7441                    }
7442                }
7443                final long origId = Binder.clearCallingIdentity();
7444                try {
7445                    stack.moveTaskToBackLocked(taskId, null);
7446                } finally {
7447                    Binder.restoreCallingIdentity(origId);
7448                }
7449            }
7450        }
7451    }
7452
7453    /**
7454     * Moves an activity, and all of the other activities within the same task, to the bottom
7455     * of the history stack.  The activity's order within the task is unchanged.
7456     *
7457     * @param token A reference to the activity we wish to move
7458     * @param nonRoot If false then this only works if the activity is the root
7459     *                of a task; if true it will work for any activity in a task.
7460     * @return Returns true if the move completed, false if not.
7461     */
7462    @Override
7463    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7464        enforceNotIsolatedCaller("moveActivityTaskToBack");
7465        synchronized(this) {
7466            final long origId = Binder.clearCallingIdentity();
7467            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7468            if (taskId >= 0) {
7469                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7470            }
7471            Binder.restoreCallingIdentity(origId);
7472        }
7473        return false;
7474    }
7475
7476    @Override
7477    public void moveTaskBackwards(int task) {
7478        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7479                "moveTaskBackwards()");
7480
7481        synchronized(this) {
7482            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7483                    Binder.getCallingUid(), "Task backwards")) {
7484                return;
7485            }
7486            final long origId = Binder.clearCallingIdentity();
7487            moveTaskBackwardsLocked(task);
7488            Binder.restoreCallingIdentity(origId);
7489        }
7490    }
7491
7492    private final void moveTaskBackwardsLocked(int task) {
7493        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7494    }
7495
7496    @Override
7497    public IBinder getHomeActivityToken() throws RemoteException {
7498        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7499                "getHomeActivityToken()");
7500        synchronized (this) {
7501            return mStackSupervisor.getHomeActivityToken();
7502        }
7503    }
7504
7505    @Override
7506    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7507            IActivityContainerCallback callback) throws RemoteException {
7508        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7509                "createActivityContainer()");
7510        synchronized (this) {
7511            if (parentActivityToken == null) {
7512                throw new IllegalArgumentException("parent token must not be null");
7513            }
7514            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7515            if (r == null) {
7516                return null;
7517            }
7518            if (callback == null) {
7519                throw new IllegalArgumentException("callback must not be null");
7520            }
7521            return mStackSupervisor.createActivityContainer(r, callback);
7522        }
7523    }
7524
7525    @Override
7526    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7527        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7528                "deleteActivityContainer()");
7529        synchronized (this) {
7530            mStackSupervisor.deleteActivityContainer(container);
7531        }
7532    }
7533
7534    @Override
7535    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7536            throws RemoteException {
7537        synchronized (this) {
7538            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7539            if (stack != null) {
7540                return stack.mActivityContainer;
7541            }
7542            return null;
7543        }
7544    }
7545
7546    @Override
7547    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7548        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7549                "moveTaskToStack()");
7550        if (stackId == HOME_STACK_ID) {
7551            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7552                    new RuntimeException("here").fillInStackTrace());
7553        }
7554        synchronized (this) {
7555            long ident = Binder.clearCallingIdentity();
7556            try {
7557                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7558                        + stackId + " toTop=" + toTop);
7559                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7560            } finally {
7561                Binder.restoreCallingIdentity(ident);
7562            }
7563        }
7564    }
7565
7566    @Override
7567    public void resizeStack(int stackBoxId, Rect bounds) {
7568        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7569                "resizeStackBox()");
7570        long ident = Binder.clearCallingIdentity();
7571        try {
7572            mWindowManager.resizeStack(stackBoxId, bounds);
7573        } finally {
7574            Binder.restoreCallingIdentity(ident);
7575        }
7576    }
7577
7578    @Override
7579    public List<StackInfo> getAllStackInfos() {
7580        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7581                "getAllStackInfos()");
7582        long ident = Binder.clearCallingIdentity();
7583        try {
7584            synchronized (this) {
7585                return mStackSupervisor.getAllStackInfosLocked();
7586            }
7587        } finally {
7588            Binder.restoreCallingIdentity(ident);
7589        }
7590    }
7591
7592    @Override
7593    public StackInfo getStackInfo(int stackId) {
7594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7595                "getStackInfo()");
7596        long ident = Binder.clearCallingIdentity();
7597        try {
7598            synchronized (this) {
7599                return mStackSupervisor.getStackInfoLocked(stackId);
7600            }
7601        } finally {
7602            Binder.restoreCallingIdentity(ident);
7603        }
7604    }
7605
7606    @Override
7607    public boolean isInHomeStack(int taskId) {
7608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7609                "getStackInfo()");
7610        long ident = Binder.clearCallingIdentity();
7611        try {
7612            synchronized (this) {
7613                TaskRecord tr = recentTaskForIdLocked(taskId);
7614                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7615            }
7616        } finally {
7617            Binder.restoreCallingIdentity(ident);
7618        }
7619    }
7620
7621    @Override
7622    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7623        synchronized(this) {
7624            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7625        }
7626    }
7627
7628    private boolean isLockTaskAuthorized(ComponentName name) {
7629        final DevicePolicyManager dpm = (DevicePolicyManager)
7630                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7631        return dpm != null && dpm.isLockTaskPermitted(name);
7632    }
7633
7634    private void startLockTaskMode(TaskRecord task) {
7635        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7636            return;
7637        }
7638        long ident = Binder.clearCallingIdentity();
7639        try {
7640            synchronized (this) {
7641                // Since we lost lock on task, make sure it is still there.
7642                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7643                if (task != null) {
7644                    mStackSupervisor.setLockTaskModeLocked(task);
7645                }
7646            }
7647        } finally {
7648            Binder.restoreCallingIdentity(ident);
7649        }
7650    }
7651
7652    @Override
7653    public void startLockTaskMode(int taskId) {
7654        long ident = Binder.clearCallingIdentity();
7655        try {
7656            final TaskRecord task;
7657            synchronized (this) {
7658                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7659            }
7660            if (task != null) {
7661                startLockTaskMode(task);
7662            }
7663        } finally {
7664            Binder.restoreCallingIdentity(ident);
7665        }
7666    }
7667
7668    @Override
7669    public void startLockTaskMode(IBinder token) {
7670        long ident = Binder.clearCallingIdentity();
7671        try {
7672            final TaskRecord task;
7673            synchronized (this) {
7674                final ActivityRecord r = ActivityRecord.forToken(token);
7675                if (r == null) {
7676                    return;
7677                }
7678                task = r.task;
7679            }
7680            if (task != null) {
7681                startLockTaskMode(task);
7682            }
7683        } finally {
7684            Binder.restoreCallingIdentity(ident);
7685        }
7686    }
7687
7688    @Override
7689    public void stopLockTaskMode() {
7690        // Check if the calling task is eligible to use lock task
7691        final int uid = Binder.getCallingUid();
7692        try {
7693            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7694            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7695                return;
7696            }
7697        } catch (RemoteException e) {
7698            Log.d(TAG, "stopLockTaskMode " + e);
7699            return;
7700        }
7701        // Stop lock task
7702        synchronized (this) {
7703            mStackSupervisor.setLockTaskModeLocked(null);
7704        }
7705    }
7706
7707    @Override
7708    public boolean isInLockTaskMode() {
7709        synchronized (this) {
7710            return mStackSupervisor.isInLockTaskMode();
7711        }
7712    }
7713
7714    // =========================================================
7715    // CONTENT PROVIDERS
7716    // =========================================================
7717
7718    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7719        List<ProviderInfo> providers = null;
7720        try {
7721            providers = AppGlobals.getPackageManager().
7722                queryContentProviders(app.processName, app.uid,
7723                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7724        } catch (RemoteException ex) {
7725        }
7726        if (DEBUG_MU)
7727            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7728        int userId = app.userId;
7729        if (providers != null) {
7730            int N = providers.size();
7731            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7732            for (int i=0; i<N; i++) {
7733                ProviderInfo cpi =
7734                    (ProviderInfo)providers.get(i);
7735                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7736                        cpi.name, cpi.flags);
7737                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7738                    // This is a singleton provider, but a user besides the
7739                    // default user is asking to initialize a process it runs
7740                    // in...  well, no, it doesn't actually run in this process,
7741                    // it runs in the process of the default user.  Get rid of it.
7742                    providers.remove(i);
7743                    N--;
7744                    i--;
7745                    continue;
7746                }
7747
7748                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7749                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7750                if (cpr == null) {
7751                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7752                    mProviderMap.putProviderByClass(comp, cpr);
7753                }
7754                if (DEBUG_MU)
7755                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7756                app.pubProviders.put(cpi.name, cpr);
7757                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7758                    // Don't add this if it is a platform component that is marked
7759                    // to run in multiple processes, because this is actually
7760                    // part of the framework so doesn't make sense to track as a
7761                    // separate apk in the process.
7762                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7763                }
7764                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7765            }
7766        }
7767        return providers;
7768    }
7769
7770    /**
7771     * Check if {@link ProcessRecord} has a possible chance at accessing the
7772     * given {@link ProviderInfo}. Final permission checking is always done
7773     * in {@link ContentProvider}.
7774     */
7775    private final String checkContentProviderPermissionLocked(
7776            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7777        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7778        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7779        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7780        // Looking for cross-user grants before to enforce the typical cross-users permissions
7781        if (userId != UserHandle.getUserId(callingUid)) {
7782            if (perms != null) {
7783                for (GrantUri grantUri : perms.keySet()) {
7784                    if (grantUri.sourceUserId == userId) {
7785                        String authority = grantUri.uri.getAuthority();
7786                        if (authority.equals(cpi.authority)) {
7787                            return null;
7788                        }
7789                    }
7790                }
7791            }
7792        }
7793        if (checkUser) {
7794            userId = handleIncomingUser(callingPid, callingUid, userId,
7795                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7796        }
7797        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7798                cpi.applicationInfo.uid, cpi.exported)
7799                == PackageManager.PERMISSION_GRANTED) {
7800            return null;
7801        }
7802        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7803                cpi.applicationInfo.uid, cpi.exported)
7804                == PackageManager.PERMISSION_GRANTED) {
7805            return null;
7806        }
7807
7808        PathPermission[] pps = cpi.pathPermissions;
7809        if (pps != null) {
7810            int i = pps.length;
7811            while (i > 0) {
7812                i--;
7813                PathPermission pp = pps[i];
7814                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7815                        cpi.applicationInfo.uid, cpi.exported)
7816                        == PackageManager.PERMISSION_GRANTED) {
7817                    return null;
7818                }
7819                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7820                        cpi.applicationInfo.uid, cpi.exported)
7821                        == PackageManager.PERMISSION_GRANTED) {
7822                    return null;
7823                }
7824            }
7825        }
7826
7827        if (perms != null) {
7828            for (GrantUri grantUri : perms.keySet()) {
7829                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7830                    return null;
7831                }
7832            }
7833        }
7834
7835        String msg;
7836        if (!cpi.exported) {
7837            msg = "Permission Denial: opening provider " + cpi.name
7838                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7839                    + ", uid=" + callingUid + ") that is not exported from uid "
7840                    + cpi.applicationInfo.uid;
7841        } else {
7842            msg = "Permission Denial: opening provider " + cpi.name
7843                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7844                    + ", uid=" + callingUid + ") requires "
7845                    + cpi.readPermission + " or " + cpi.writePermission;
7846        }
7847        Slog.w(TAG, msg);
7848        return msg;
7849    }
7850
7851    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7852            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7853        if (r != null) {
7854            for (int i=0; i<r.conProviders.size(); i++) {
7855                ContentProviderConnection conn = r.conProviders.get(i);
7856                if (conn.provider == cpr) {
7857                    if (DEBUG_PROVIDER) Slog.v(TAG,
7858                            "Adding provider requested by "
7859                            + r.processName + " from process "
7860                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7861                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7862                    if (stable) {
7863                        conn.stableCount++;
7864                        conn.numStableIncs++;
7865                    } else {
7866                        conn.unstableCount++;
7867                        conn.numUnstableIncs++;
7868                    }
7869                    return conn;
7870                }
7871            }
7872            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7873            if (stable) {
7874                conn.stableCount = 1;
7875                conn.numStableIncs = 1;
7876            } else {
7877                conn.unstableCount = 1;
7878                conn.numUnstableIncs = 1;
7879            }
7880            cpr.connections.add(conn);
7881            r.conProviders.add(conn);
7882            return conn;
7883        }
7884        cpr.addExternalProcessHandleLocked(externalProcessToken);
7885        return null;
7886    }
7887
7888    boolean decProviderCountLocked(ContentProviderConnection conn,
7889            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7890        if (conn != null) {
7891            cpr = conn.provider;
7892            if (DEBUG_PROVIDER) Slog.v(TAG,
7893                    "Removing provider requested by "
7894                    + conn.client.processName + " from process "
7895                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7896                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7897            if (stable) {
7898                conn.stableCount--;
7899            } else {
7900                conn.unstableCount--;
7901            }
7902            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7903                cpr.connections.remove(conn);
7904                conn.client.conProviders.remove(conn);
7905                return true;
7906            }
7907            return false;
7908        }
7909        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7910        return false;
7911    }
7912
7913    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7914            String name, IBinder token, boolean stable, int userId) {
7915        ContentProviderRecord cpr;
7916        ContentProviderConnection conn = null;
7917        ProviderInfo cpi = null;
7918
7919        synchronized(this) {
7920            ProcessRecord r = null;
7921            if (caller != null) {
7922                r = getRecordForAppLocked(caller);
7923                if (r == null) {
7924                    throw new SecurityException(
7925                            "Unable to find app for caller " + caller
7926                          + " (pid=" + Binder.getCallingPid()
7927                          + ") when getting content provider " + name);
7928                }
7929            }
7930
7931            boolean checkCrossUser = true;
7932
7933            // First check if this content provider has been published...
7934            cpr = mProviderMap.getProviderByName(name, userId);
7935            // If that didn't work, check if it exists for user 0 and then
7936            // verify that it's a singleton provider before using it.
7937            if (cpr == null && userId != UserHandle.USER_OWNER) {
7938                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
7939                if (cpr != null) {
7940                    cpi = cpr.info;
7941                    if (isSingleton(cpi.processName, cpi.applicationInfo,
7942                            cpi.name, cpi.flags)
7943                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
7944                        userId = UserHandle.USER_OWNER;
7945                        checkCrossUser = false;
7946                    } else {
7947                        cpr = null;
7948                        cpi = null;
7949                    }
7950                }
7951            }
7952
7953            boolean providerRunning = cpr != null;
7954            if (providerRunning) {
7955                cpi = cpr.info;
7956                String msg;
7957                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
7958                        != null) {
7959                    throw new SecurityException(msg);
7960                }
7961
7962                if (r != null && cpr.canRunHere(r)) {
7963                    // This provider has been published or is in the process
7964                    // of being published...  but it is also allowed to run
7965                    // in the caller's process, so don't make a connection
7966                    // and just let the caller instantiate its own instance.
7967                    ContentProviderHolder holder = cpr.newHolder(null);
7968                    // don't give caller the provider object, it needs
7969                    // to make its own.
7970                    holder.provider = null;
7971                    return holder;
7972                }
7973
7974                final long origId = Binder.clearCallingIdentity();
7975
7976                // In this case the provider instance already exists, so we can
7977                // return it right away.
7978                conn = incProviderCountLocked(r, cpr, token, stable);
7979                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7980                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7981                        // If this is a perceptible app accessing the provider,
7982                        // make sure to count it as being accessed and thus
7983                        // back up on the LRU list.  This is good because
7984                        // content providers are often expensive to start.
7985                        updateLruProcessLocked(cpr.proc, false, null);
7986                    }
7987                }
7988
7989                if (cpr.proc != null) {
7990                    if (false) {
7991                        if (cpr.name.flattenToShortString().equals(
7992                                "com.android.providers.calendar/.CalendarProvider2")) {
7993                            Slog.v(TAG, "****************** KILLING "
7994                                + cpr.name.flattenToShortString());
7995                            Process.killProcess(cpr.proc.pid);
7996                        }
7997                    }
7998                    boolean success = updateOomAdjLocked(cpr.proc);
7999                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8000                    // NOTE: there is still a race here where a signal could be
8001                    // pending on the process even though we managed to update its
8002                    // adj level.  Not sure what to do about this, but at least
8003                    // the race is now smaller.
8004                    if (!success) {
8005                        // Uh oh...  it looks like the provider's process
8006                        // has been killed on us.  We need to wait for a new
8007                        // process to be started, and make sure its death
8008                        // doesn't kill our process.
8009                        Slog.i(TAG,
8010                                "Existing provider " + cpr.name.flattenToShortString()
8011                                + " is crashing; detaching " + r);
8012                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8013                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8014                        if (!lastRef) {
8015                            // This wasn't the last ref our process had on
8016                            // the provider...  we have now been killed, bail.
8017                            return null;
8018                        }
8019                        providerRunning = false;
8020                        conn = null;
8021                    }
8022                }
8023
8024                Binder.restoreCallingIdentity(origId);
8025            }
8026
8027            boolean singleton;
8028            if (!providerRunning) {
8029                try {
8030                    cpi = AppGlobals.getPackageManager().
8031                        resolveContentProvider(name,
8032                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8033                } catch (RemoteException ex) {
8034                }
8035                if (cpi == null) {
8036                    return null;
8037                }
8038                // If the provider is a singleton AND
8039                // (it's a call within the same user || the provider is a
8040                // privileged app)
8041                // Then allow connecting to the singleton provider
8042                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8043                        cpi.name, cpi.flags)
8044                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8045                if (singleton) {
8046                    userId = UserHandle.USER_OWNER;
8047                }
8048                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8049
8050                String msg;
8051                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8052                        != null) {
8053                    throw new SecurityException(msg);
8054                }
8055
8056                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8057                        && !cpi.processName.equals("system")) {
8058                    // If this content provider does not run in the system
8059                    // process, and the system is not yet ready to run other
8060                    // processes, then fail fast instead of hanging.
8061                    throw new IllegalArgumentException(
8062                            "Attempt to launch content provider before system ready");
8063                }
8064
8065                // Make sure that the user who owns this provider is started.  If not,
8066                // we don't want to allow it to run.
8067                if (mStartedUsers.get(userId) == null) {
8068                    Slog.w(TAG, "Unable to launch app "
8069                            + cpi.applicationInfo.packageName + "/"
8070                            + cpi.applicationInfo.uid + " for provider "
8071                            + name + ": user " + userId + " is stopped");
8072                    return null;
8073                }
8074
8075                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8076                cpr = mProviderMap.getProviderByClass(comp, userId);
8077                final boolean firstClass = cpr == null;
8078                if (firstClass) {
8079                    try {
8080                        ApplicationInfo ai =
8081                            AppGlobals.getPackageManager().
8082                                getApplicationInfo(
8083                                        cpi.applicationInfo.packageName,
8084                                        STOCK_PM_FLAGS, userId);
8085                        if (ai == null) {
8086                            Slog.w(TAG, "No package info for content provider "
8087                                    + cpi.name);
8088                            return null;
8089                        }
8090                        ai = getAppInfoForUser(ai, userId);
8091                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8092                    } catch (RemoteException ex) {
8093                        // pm is in same process, this will never happen.
8094                    }
8095                }
8096
8097                if (r != null && cpr.canRunHere(r)) {
8098                    // If this is a multiprocess provider, then just return its
8099                    // info and allow the caller to instantiate it.  Only do
8100                    // this if the provider is the same user as the caller's
8101                    // process, or can run as root (so can be in any process).
8102                    return cpr.newHolder(null);
8103                }
8104
8105                if (DEBUG_PROVIDER) {
8106                    RuntimeException e = new RuntimeException("here");
8107                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8108                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8109                }
8110
8111                // This is single process, and our app is now connecting to it.
8112                // See if we are already in the process of launching this
8113                // provider.
8114                final int N = mLaunchingProviders.size();
8115                int i;
8116                for (i=0; i<N; i++) {
8117                    if (mLaunchingProviders.get(i) == cpr) {
8118                        break;
8119                    }
8120                }
8121
8122                // If the provider is not already being launched, then get it
8123                // started.
8124                if (i >= N) {
8125                    final long origId = Binder.clearCallingIdentity();
8126
8127                    try {
8128                        // Content provider is now in use, its package can't be stopped.
8129                        try {
8130                            AppGlobals.getPackageManager().setPackageStoppedState(
8131                                    cpr.appInfo.packageName, false, userId);
8132                        } catch (RemoteException e) {
8133                        } catch (IllegalArgumentException e) {
8134                            Slog.w(TAG, "Failed trying to unstop package "
8135                                    + cpr.appInfo.packageName + ": " + e);
8136                        }
8137
8138                        // Use existing process if already started
8139                        ProcessRecord proc = getProcessRecordLocked(
8140                                cpi.processName, cpr.appInfo.uid, false);
8141                        if (proc != null && proc.thread != null) {
8142                            if (DEBUG_PROVIDER) {
8143                                Slog.d(TAG, "Installing in existing process " + proc);
8144                            }
8145                            proc.pubProviders.put(cpi.name, cpr);
8146                            try {
8147                                proc.thread.scheduleInstallProvider(cpi);
8148                            } catch (RemoteException e) {
8149                            }
8150                        } else {
8151                            proc = startProcessLocked(cpi.processName,
8152                                    cpr.appInfo, false, 0, "content provider",
8153                                    new ComponentName(cpi.applicationInfo.packageName,
8154                                            cpi.name), false, false, false);
8155                            if (proc == null) {
8156                                Slog.w(TAG, "Unable to launch app "
8157                                        + cpi.applicationInfo.packageName + "/"
8158                                        + cpi.applicationInfo.uid + " for provider "
8159                                        + name + ": process is bad");
8160                                return null;
8161                            }
8162                        }
8163                        cpr.launchingApp = proc;
8164                        mLaunchingProviders.add(cpr);
8165                    } finally {
8166                        Binder.restoreCallingIdentity(origId);
8167                    }
8168                }
8169
8170                // Make sure the provider is published (the same provider class
8171                // may be published under multiple names).
8172                if (firstClass) {
8173                    mProviderMap.putProviderByClass(comp, cpr);
8174                }
8175
8176                mProviderMap.putProviderByName(name, cpr);
8177                conn = incProviderCountLocked(r, cpr, token, stable);
8178                if (conn != null) {
8179                    conn.waiting = true;
8180                }
8181            }
8182        }
8183
8184        // Wait for the provider to be published...
8185        synchronized (cpr) {
8186            while (cpr.provider == null) {
8187                if (cpr.launchingApp == null) {
8188                    Slog.w(TAG, "Unable to launch app "
8189                            + cpi.applicationInfo.packageName + "/"
8190                            + cpi.applicationInfo.uid + " for provider "
8191                            + name + ": launching app became null");
8192                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8193                            UserHandle.getUserId(cpi.applicationInfo.uid),
8194                            cpi.applicationInfo.packageName,
8195                            cpi.applicationInfo.uid, name);
8196                    return null;
8197                }
8198                try {
8199                    if (DEBUG_MU) {
8200                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8201                                + cpr.launchingApp);
8202                    }
8203                    if (conn != null) {
8204                        conn.waiting = true;
8205                    }
8206                    cpr.wait();
8207                } catch (InterruptedException ex) {
8208                } finally {
8209                    if (conn != null) {
8210                        conn.waiting = false;
8211                    }
8212                }
8213            }
8214        }
8215        return cpr != null ? cpr.newHolder(conn) : null;
8216    }
8217
8218    @Override
8219    public final ContentProviderHolder getContentProvider(
8220            IApplicationThread caller, String name, int userId, boolean stable) {
8221        enforceNotIsolatedCaller("getContentProvider");
8222        if (caller == null) {
8223            String msg = "null IApplicationThread when getting content provider "
8224                    + name;
8225            Slog.w(TAG, msg);
8226            throw new SecurityException(msg);
8227        }
8228        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8229        // with cross-user grant.
8230        return getContentProviderImpl(caller, name, null, stable, userId);
8231    }
8232
8233    public ContentProviderHolder getContentProviderExternal(
8234            String name, int userId, IBinder token) {
8235        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8236            "Do not have permission in call getContentProviderExternal()");
8237        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8238                false, true, "getContentProvider", null);
8239        return getContentProviderExternalUnchecked(name, token, userId);
8240    }
8241
8242    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8243            IBinder token, int userId) {
8244        return getContentProviderImpl(null, name, token, true, userId);
8245    }
8246
8247    /**
8248     * Drop a content provider from a ProcessRecord's bookkeeping
8249     */
8250    public void removeContentProvider(IBinder connection, boolean stable) {
8251        enforceNotIsolatedCaller("removeContentProvider");
8252        long ident = Binder.clearCallingIdentity();
8253        try {
8254            synchronized (this) {
8255                ContentProviderConnection conn;
8256                try {
8257                    conn = (ContentProviderConnection)connection;
8258                } catch (ClassCastException e) {
8259                    String msg ="removeContentProvider: " + connection
8260                            + " not a ContentProviderConnection";
8261                    Slog.w(TAG, msg);
8262                    throw new IllegalArgumentException(msg);
8263                }
8264                if (conn == null) {
8265                    throw new NullPointerException("connection is null");
8266                }
8267                if (decProviderCountLocked(conn, null, null, stable)) {
8268                    updateOomAdjLocked();
8269                }
8270            }
8271        } finally {
8272            Binder.restoreCallingIdentity(ident);
8273        }
8274    }
8275
8276    public void removeContentProviderExternal(String name, IBinder token) {
8277        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8278            "Do not have permission in call removeContentProviderExternal()");
8279        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8280    }
8281
8282    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8283        synchronized (this) {
8284            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8285            if(cpr == null) {
8286                //remove from mProvidersByClass
8287                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8288                return;
8289            }
8290
8291            //update content provider record entry info
8292            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8293            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8294            if (localCpr.hasExternalProcessHandles()) {
8295                if (localCpr.removeExternalProcessHandleLocked(token)) {
8296                    updateOomAdjLocked();
8297                } else {
8298                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8299                            + " with no external reference for token: "
8300                            + token + ".");
8301                }
8302            } else {
8303                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8304                        + " with no external references.");
8305            }
8306        }
8307    }
8308
8309    public final void publishContentProviders(IApplicationThread caller,
8310            List<ContentProviderHolder> providers) {
8311        if (providers == null) {
8312            return;
8313        }
8314
8315        enforceNotIsolatedCaller("publishContentProviders");
8316        synchronized (this) {
8317            final ProcessRecord r = getRecordForAppLocked(caller);
8318            if (DEBUG_MU)
8319                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8320            if (r == null) {
8321                throw new SecurityException(
8322                        "Unable to find app for caller " + caller
8323                      + " (pid=" + Binder.getCallingPid()
8324                      + ") when publishing content providers");
8325            }
8326
8327            final long origId = Binder.clearCallingIdentity();
8328
8329            final int N = providers.size();
8330            for (int i=0; i<N; i++) {
8331                ContentProviderHolder src = providers.get(i);
8332                if (src == null || src.info == null || src.provider == null) {
8333                    continue;
8334                }
8335                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8336                if (DEBUG_MU)
8337                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8338                if (dst != null) {
8339                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8340                    mProviderMap.putProviderByClass(comp, dst);
8341                    String names[] = dst.info.authority.split(";");
8342                    for (int j = 0; j < names.length; j++) {
8343                        mProviderMap.putProviderByName(names[j], dst);
8344                    }
8345
8346                    int NL = mLaunchingProviders.size();
8347                    int j;
8348                    for (j=0; j<NL; j++) {
8349                        if (mLaunchingProviders.get(j) == dst) {
8350                            mLaunchingProviders.remove(j);
8351                            j--;
8352                            NL--;
8353                        }
8354                    }
8355                    synchronized (dst) {
8356                        dst.provider = src.provider;
8357                        dst.proc = r;
8358                        dst.notifyAll();
8359                    }
8360                    updateOomAdjLocked(r);
8361                }
8362            }
8363
8364            Binder.restoreCallingIdentity(origId);
8365        }
8366    }
8367
8368    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8369        ContentProviderConnection conn;
8370        try {
8371            conn = (ContentProviderConnection)connection;
8372        } catch (ClassCastException e) {
8373            String msg ="refContentProvider: " + connection
8374                    + " not a ContentProviderConnection";
8375            Slog.w(TAG, msg);
8376            throw new IllegalArgumentException(msg);
8377        }
8378        if (conn == null) {
8379            throw new NullPointerException("connection is null");
8380        }
8381
8382        synchronized (this) {
8383            if (stable > 0) {
8384                conn.numStableIncs += stable;
8385            }
8386            stable = conn.stableCount + stable;
8387            if (stable < 0) {
8388                throw new IllegalStateException("stableCount < 0: " + stable);
8389            }
8390
8391            if (unstable > 0) {
8392                conn.numUnstableIncs += unstable;
8393            }
8394            unstable = conn.unstableCount + unstable;
8395            if (unstable < 0) {
8396                throw new IllegalStateException("unstableCount < 0: " + unstable);
8397            }
8398
8399            if ((stable+unstable) <= 0) {
8400                throw new IllegalStateException("ref counts can't go to zero here: stable="
8401                        + stable + " unstable=" + unstable);
8402            }
8403            conn.stableCount = stable;
8404            conn.unstableCount = unstable;
8405            return !conn.dead;
8406        }
8407    }
8408
8409    public void unstableProviderDied(IBinder connection) {
8410        ContentProviderConnection conn;
8411        try {
8412            conn = (ContentProviderConnection)connection;
8413        } catch (ClassCastException e) {
8414            String msg ="refContentProvider: " + connection
8415                    + " not a ContentProviderConnection";
8416            Slog.w(TAG, msg);
8417            throw new IllegalArgumentException(msg);
8418        }
8419        if (conn == null) {
8420            throw new NullPointerException("connection is null");
8421        }
8422
8423        // Safely retrieve the content provider associated with the connection.
8424        IContentProvider provider;
8425        synchronized (this) {
8426            provider = conn.provider.provider;
8427        }
8428
8429        if (provider == null) {
8430            // Um, yeah, we're way ahead of you.
8431            return;
8432        }
8433
8434        // Make sure the caller is being honest with us.
8435        if (provider.asBinder().pingBinder()) {
8436            // Er, no, still looks good to us.
8437            synchronized (this) {
8438                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8439                        + " says " + conn + " died, but we don't agree");
8440                return;
8441            }
8442        }
8443
8444        // Well look at that!  It's dead!
8445        synchronized (this) {
8446            if (conn.provider.provider != provider) {
8447                // But something changed...  good enough.
8448                return;
8449            }
8450
8451            ProcessRecord proc = conn.provider.proc;
8452            if (proc == null || proc.thread == null) {
8453                // Seems like the process is already cleaned up.
8454                return;
8455            }
8456
8457            // As far as we're concerned, this is just like receiving a
8458            // death notification...  just a bit prematurely.
8459            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8460                    + ") early provider death");
8461            final long ident = Binder.clearCallingIdentity();
8462            try {
8463                appDiedLocked(proc, proc.pid, proc.thread);
8464            } finally {
8465                Binder.restoreCallingIdentity(ident);
8466            }
8467        }
8468    }
8469
8470    @Override
8471    public void appNotRespondingViaProvider(IBinder connection) {
8472        enforceCallingPermission(
8473                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8474
8475        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8476        if (conn == null) {
8477            Slog.w(TAG, "ContentProviderConnection is null");
8478            return;
8479        }
8480
8481        final ProcessRecord host = conn.provider.proc;
8482        if (host == null) {
8483            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8484            return;
8485        }
8486
8487        final long token = Binder.clearCallingIdentity();
8488        try {
8489            appNotResponding(host, null, null, false, "ContentProvider not responding");
8490        } finally {
8491            Binder.restoreCallingIdentity(token);
8492        }
8493    }
8494
8495    public final void installSystemProviders() {
8496        List<ProviderInfo> providers;
8497        synchronized (this) {
8498            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8499            providers = generateApplicationProvidersLocked(app);
8500            if (providers != null) {
8501                for (int i=providers.size()-1; i>=0; i--) {
8502                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8503                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8504                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8505                                + ": not system .apk");
8506                        providers.remove(i);
8507                    }
8508                }
8509            }
8510        }
8511        if (providers != null) {
8512            mSystemThread.installSystemProviders(providers);
8513        }
8514
8515        mCoreSettingsObserver = new CoreSettingsObserver(this);
8516
8517        mUsageStatsService.monitorPackages();
8518    }
8519
8520    /**
8521     * Allows app to retrieve the MIME type of a URI without having permission
8522     * to access its content provider.
8523     *
8524     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8525     *
8526     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8527     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8528     */
8529    public String getProviderMimeType(Uri uri, int userId) {
8530        enforceNotIsolatedCaller("getProviderMimeType");
8531        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8532                userId, false, true, "getProviderMimeType", null);
8533        final String name = uri.getAuthority();
8534        final long ident = Binder.clearCallingIdentity();
8535        ContentProviderHolder holder = null;
8536
8537        try {
8538            holder = getContentProviderExternalUnchecked(name, null, userId);
8539            if (holder != null) {
8540                return holder.provider.getType(uri);
8541            }
8542        } catch (RemoteException e) {
8543            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8544            return null;
8545        } finally {
8546            if (holder != null) {
8547                removeContentProviderExternalUnchecked(name, null, userId);
8548            }
8549            Binder.restoreCallingIdentity(ident);
8550        }
8551
8552        return null;
8553    }
8554
8555    // =========================================================
8556    // GLOBAL MANAGEMENT
8557    // =========================================================
8558
8559    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8560            boolean isolated) {
8561        String proc = customProcess != null ? customProcess : info.processName;
8562        BatteryStatsImpl.Uid.Proc ps = null;
8563        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8564        int uid = info.uid;
8565        if (isolated) {
8566            int userId = UserHandle.getUserId(uid);
8567            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8568            while (true) {
8569                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8570                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8571                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8572                }
8573                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8574                mNextIsolatedProcessUid++;
8575                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8576                    // No process for this uid, use it.
8577                    break;
8578                }
8579                stepsLeft--;
8580                if (stepsLeft <= 0) {
8581                    return null;
8582                }
8583            }
8584        }
8585        return new ProcessRecord(stats, info, proc, uid);
8586    }
8587
8588    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8589            String abiOverride) {
8590        ProcessRecord app;
8591        if (!isolated) {
8592            app = getProcessRecordLocked(info.processName, info.uid, true);
8593        } else {
8594            app = null;
8595        }
8596
8597        if (app == null) {
8598            app = newProcessRecordLocked(info, null, isolated);
8599            mProcessNames.put(info.processName, app.uid, app);
8600            if (isolated) {
8601                mIsolatedProcesses.put(app.uid, app);
8602            }
8603            updateLruProcessLocked(app, false, null);
8604            updateOomAdjLocked();
8605        }
8606
8607        // This package really, really can not be stopped.
8608        try {
8609            AppGlobals.getPackageManager().setPackageStoppedState(
8610                    info.packageName, false, UserHandle.getUserId(app.uid));
8611        } catch (RemoteException e) {
8612        } catch (IllegalArgumentException e) {
8613            Slog.w(TAG, "Failed trying to unstop package "
8614                    + info.packageName + ": " + e);
8615        }
8616
8617        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8618                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8619            app.persistent = true;
8620            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8621        }
8622        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8623            mPersistentStartingProcesses.add(app);
8624            startProcessLocked(app, "added application", app.processName,
8625                    abiOverride);
8626        }
8627
8628        return app;
8629    }
8630
8631    public void unhandledBack() {
8632        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8633                "unhandledBack()");
8634
8635        synchronized(this) {
8636            final long origId = Binder.clearCallingIdentity();
8637            try {
8638                getFocusedStack().unhandledBackLocked();
8639            } finally {
8640                Binder.restoreCallingIdentity(origId);
8641            }
8642        }
8643    }
8644
8645    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8646        enforceNotIsolatedCaller("openContentUri");
8647        final int userId = UserHandle.getCallingUserId();
8648        String name = uri.getAuthority();
8649        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8650        ParcelFileDescriptor pfd = null;
8651        if (cph != null) {
8652            // We record the binder invoker's uid in thread-local storage before
8653            // going to the content provider to open the file.  Later, in the code
8654            // that handles all permissions checks, we look for this uid and use
8655            // that rather than the Activity Manager's own uid.  The effect is that
8656            // we do the check against the caller's permissions even though it looks
8657            // to the content provider like the Activity Manager itself is making
8658            // the request.
8659            sCallerIdentity.set(new Identity(
8660                    Binder.getCallingPid(), Binder.getCallingUid()));
8661            try {
8662                pfd = cph.provider.openFile(null, uri, "r", null);
8663            } catch (FileNotFoundException e) {
8664                // do nothing; pfd will be returned null
8665            } finally {
8666                // Ensure that whatever happens, we clean up the identity state
8667                sCallerIdentity.remove();
8668            }
8669
8670            // We've got the fd now, so we're done with the provider.
8671            removeContentProviderExternalUnchecked(name, null, userId);
8672        } else {
8673            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8674        }
8675        return pfd;
8676    }
8677
8678    // Actually is sleeping or shutting down or whatever else in the future
8679    // is an inactive state.
8680    public boolean isSleepingOrShuttingDown() {
8681        return mSleeping || mShuttingDown;
8682    }
8683
8684    public boolean isSleeping() {
8685        return mSleeping;
8686    }
8687
8688    void goingToSleep() {
8689        synchronized(this) {
8690            mWentToSleep = true;
8691            updateEventDispatchingLocked();
8692            goToSleepIfNeededLocked();
8693        }
8694    }
8695
8696    void finishRunningVoiceLocked() {
8697        if (mRunningVoice) {
8698            mRunningVoice = false;
8699            goToSleepIfNeededLocked();
8700        }
8701    }
8702
8703    void goToSleepIfNeededLocked() {
8704        if (mWentToSleep && !mRunningVoice) {
8705            if (!mSleeping) {
8706                mSleeping = true;
8707                mStackSupervisor.goingToSleepLocked();
8708
8709                // Initialize the wake times of all processes.
8710                checkExcessivePowerUsageLocked(false);
8711                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8712                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8713                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8714            }
8715        }
8716    }
8717
8718    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8719        mTaskPersister.notify(task, flush);
8720    }
8721
8722    @Override
8723    public boolean shutdown(int timeout) {
8724        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8725                != PackageManager.PERMISSION_GRANTED) {
8726            throw new SecurityException("Requires permission "
8727                    + android.Manifest.permission.SHUTDOWN);
8728        }
8729
8730        boolean timedout = false;
8731
8732        synchronized(this) {
8733            mShuttingDown = true;
8734            updateEventDispatchingLocked();
8735            timedout = mStackSupervisor.shutdownLocked(timeout);
8736        }
8737
8738        mAppOpsService.shutdown();
8739        mUsageStatsService.shutdown();
8740        mBatteryStatsService.shutdown();
8741        synchronized (this) {
8742            mProcessStats.shutdownLocked();
8743        }
8744        notifyTaskPersisterLocked(null, true);
8745
8746        return timedout;
8747    }
8748
8749    public final void activitySlept(IBinder token) {
8750        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8751
8752        final long origId = Binder.clearCallingIdentity();
8753
8754        synchronized (this) {
8755            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8756            if (r != null) {
8757                mStackSupervisor.activitySleptLocked(r);
8758            }
8759        }
8760
8761        Binder.restoreCallingIdentity(origId);
8762    }
8763
8764    void logLockScreen(String msg) {
8765        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8766                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8767                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8768                mStackSupervisor.mDismissKeyguardOnNextActivity);
8769    }
8770
8771    private void comeOutOfSleepIfNeededLocked() {
8772        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8773            if (mSleeping) {
8774                mSleeping = false;
8775                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8776            }
8777        }
8778    }
8779
8780    void wakingUp() {
8781        synchronized(this) {
8782            mWentToSleep = false;
8783            updateEventDispatchingLocked();
8784            comeOutOfSleepIfNeededLocked();
8785        }
8786    }
8787
8788    void startRunningVoiceLocked() {
8789        if (!mRunningVoice) {
8790            mRunningVoice = true;
8791            comeOutOfSleepIfNeededLocked();
8792        }
8793    }
8794
8795    private void updateEventDispatchingLocked() {
8796        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8797    }
8798
8799    public void setLockScreenShown(boolean shown) {
8800        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8801                != PackageManager.PERMISSION_GRANTED) {
8802            throw new SecurityException("Requires permission "
8803                    + android.Manifest.permission.DEVICE_POWER);
8804        }
8805
8806        synchronized(this) {
8807            long ident = Binder.clearCallingIdentity();
8808            try {
8809                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8810                mLockScreenShown = shown;
8811                comeOutOfSleepIfNeededLocked();
8812            } finally {
8813                Binder.restoreCallingIdentity(ident);
8814            }
8815        }
8816    }
8817
8818    public void stopAppSwitches() {
8819        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8820                != PackageManager.PERMISSION_GRANTED) {
8821            throw new SecurityException("Requires permission "
8822                    + android.Manifest.permission.STOP_APP_SWITCHES);
8823        }
8824
8825        synchronized(this) {
8826            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8827                    + APP_SWITCH_DELAY_TIME;
8828            mDidAppSwitch = false;
8829            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8830            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8831            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8832        }
8833    }
8834
8835    public void resumeAppSwitches() {
8836        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8837                != PackageManager.PERMISSION_GRANTED) {
8838            throw new SecurityException("Requires permission "
8839                    + android.Manifest.permission.STOP_APP_SWITCHES);
8840        }
8841
8842        synchronized(this) {
8843            // Note that we don't execute any pending app switches... we will
8844            // let those wait until either the timeout, or the next start
8845            // activity request.
8846            mAppSwitchesAllowedTime = 0;
8847        }
8848    }
8849
8850    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8851            String name) {
8852        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8853            return true;
8854        }
8855
8856        final int perm = checkComponentPermission(
8857                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8858                callingUid, -1, true);
8859        if (perm == PackageManager.PERMISSION_GRANTED) {
8860            return true;
8861        }
8862
8863        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8864        return false;
8865    }
8866
8867    public void setDebugApp(String packageName, boolean waitForDebugger,
8868            boolean persistent) {
8869        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8870                "setDebugApp()");
8871
8872        long ident = Binder.clearCallingIdentity();
8873        try {
8874            // Note that this is not really thread safe if there are multiple
8875            // callers into it at the same time, but that's not a situation we
8876            // care about.
8877            if (persistent) {
8878                final ContentResolver resolver = mContext.getContentResolver();
8879                Settings.Global.putString(
8880                    resolver, Settings.Global.DEBUG_APP,
8881                    packageName);
8882                Settings.Global.putInt(
8883                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8884                    waitForDebugger ? 1 : 0);
8885            }
8886
8887            synchronized (this) {
8888                if (!persistent) {
8889                    mOrigDebugApp = mDebugApp;
8890                    mOrigWaitForDebugger = mWaitForDebugger;
8891                }
8892                mDebugApp = packageName;
8893                mWaitForDebugger = waitForDebugger;
8894                mDebugTransient = !persistent;
8895                if (packageName != null) {
8896                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8897                            false, UserHandle.USER_ALL, "set debug app");
8898                }
8899            }
8900        } finally {
8901            Binder.restoreCallingIdentity(ident);
8902        }
8903    }
8904
8905    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
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
8914            mOpenGlTraceApp = processName;
8915        }
8916    }
8917
8918    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8919            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8920        synchronized (this) {
8921            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8922            if (!isDebuggable) {
8923                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8924                    throw new SecurityException("Process not debuggable: " + app.packageName);
8925                }
8926            }
8927            mProfileApp = processName;
8928            mProfileFile = profileFile;
8929            if (mProfileFd != null) {
8930                try {
8931                    mProfileFd.close();
8932                } catch (IOException e) {
8933                }
8934                mProfileFd = null;
8935            }
8936            mProfileFd = profileFd;
8937            mProfileType = 0;
8938            mAutoStopProfiler = autoStopProfiler;
8939        }
8940    }
8941
8942    @Override
8943    public void setAlwaysFinish(boolean enabled) {
8944        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8945                "setAlwaysFinish()");
8946
8947        Settings.Global.putInt(
8948                mContext.getContentResolver(),
8949                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8950
8951        synchronized (this) {
8952            mAlwaysFinishActivities = enabled;
8953        }
8954    }
8955
8956    @Override
8957    public void setActivityController(IActivityController controller) {
8958        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8959                "setActivityController()");
8960        synchronized (this) {
8961            mController = controller;
8962            Watchdog.getInstance().setActivityController(controller);
8963        }
8964    }
8965
8966    @Override
8967    public void setUserIsMonkey(boolean userIsMonkey) {
8968        synchronized (this) {
8969            synchronized (mPidsSelfLocked) {
8970                final int callingPid = Binder.getCallingPid();
8971                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8972                if (precessRecord == null) {
8973                    throw new SecurityException("Unknown process: " + callingPid);
8974                }
8975                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8976                    throw new SecurityException("Only an instrumentation process "
8977                            + "with a UiAutomation can call setUserIsMonkey");
8978                }
8979            }
8980            mUserIsMonkey = userIsMonkey;
8981        }
8982    }
8983
8984    @Override
8985    public boolean isUserAMonkey() {
8986        synchronized (this) {
8987            // If there is a controller also implies the user is a monkey.
8988            return (mUserIsMonkey || mController != null);
8989        }
8990    }
8991
8992    public void requestBugReport() {
8993        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8994        SystemProperties.set("ctl.start", "bugreport");
8995    }
8996
8997    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8998        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8999    }
9000
9001    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9002        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9003            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9004        }
9005        return KEY_DISPATCHING_TIMEOUT;
9006    }
9007
9008    @Override
9009    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9010        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9011                != PackageManager.PERMISSION_GRANTED) {
9012            throw new SecurityException("Requires permission "
9013                    + android.Manifest.permission.FILTER_EVENTS);
9014        }
9015        ProcessRecord proc;
9016        long timeout;
9017        synchronized (this) {
9018            synchronized (mPidsSelfLocked) {
9019                proc = mPidsSelfLocked.get(pid);
9020            }
9021            timeout = getInputDispatchingTimeoutLocked(proc);
9022        }
9023
9024        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9025            return -1;
9026        }
9027
9028        return timeout;
9029    }
9030
9031    /**
9032     * Handle input dispatching timeouts.
9033     * Returns whether input dispatching should be aborted or not.
9034     */
9035    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9036            final ActivityRecord activity, final ActivityRecord parent,
9037            final boolean aboveSystem, String reason) {
9038        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9039                != PackageManager.PERMISSION_GRANTED) {
9040            throw new SecurityException("Requires permission "
9041                    + android.Manifest.permission.FILTER_EVENTS);
9042        }
9043
9044        final String annotation;
9045        if (reason == null) {
9046            annotation = "Input dispatching timed out";
9047        } else {
9048            annotation = "Input dispatching timed out (" + reason + ")";
9049        }
9050
9051        if (proc != null) {
9052            synchronized (this) {
9053                if (proc.debugging) {
9054                    return false;
9055                }
9056
9057                if (mDidDexOpt) {
9058                    // Give more time since we were dexopting.
9059                    mDidDexOpt = false;
9060                    return false;
9061                }
9062
9063                if (proc.instrumentationClass != null) {
9064                    Bundle info = new Bundle();
9065                    info.putString("shortMsg", "keyDispatchingTimedOut");
9066                    info.putString("longMsg", annotation);
9067                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9068                    return true;
9069                }
9070            }
9071            mHandler.post(new Runnable() {
9072                @Override
9073                public void run() {
9074                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9075                }
9076            });
9077        }
9078
9079        return true;
9080    }
9081
9082    public Bundle getAssistContextExtras(int requestType) {
9083        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9084                "getAssistContextExtras()");
9085        PendingAssistExtras pae;
9086        Bundle extras = new Bundle();
9087        synchronized (this) {
9088            ActivityRecord activity = getFocusedStack().mResumedActivity;
9089            if (activity == null) {
9090                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9091                return null;
9092            }
9093            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9094            if (activity.app == null || activity.app.thread == null) {
9095                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9096                return extras;
9097            }
9098            if (activity.app.pid == Binder.getCallingPid()) {
9099                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9100                return extras;
9101            }
9102            pae = new PendingAssistExtras(activity);
9103            try {
9104                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9105                        requestType);
9106                mPendingAssistExtras.add(pae);
9107                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9108            } catch (RemoteException e) {
9109                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9110                return extras;
9111            }
9112        }
9113        synchronized (pae) {
9114            while (!pae.haveResult) {
9115                try {
9116                    pae.wait();
9117                } catch (InterruptedException e) {
9118                }
9119            }
9120            if (pae.result != null) {
9121                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9122            }
9123        }
9124        synchronized (this) {
9125            mPendingAssistExtras.remove(pae);
9126            mHandler.removeCallbacks(pae);
9127        }
9128        return extras;
9129    }
9130
9131    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9132        PendingAssistExtras pae = (PendingAssistExtras)token;
9133        synchronized (pae) {
9134            pae.result = extras;
9135            pae.haveResult = true;
9136            pae.notifyAll();
9137        }
9138    }
9139
9140    public void registerProcessObserver(IProcessObserver observer) {
9141        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9142                "registerProcessObserver()");
9143        synchronized (this) {
9144            mProcessObservers.register(observer);
9145        }
9146    }
9147
9148    @Override
9149    public void unregisterProcessObserver(IProcessObserver observer) {
9150        synchronized (this) {
9151            mProcessObservers.unregister(observer);
9152        }
9153    }
9154
9155    @Override
9156    public boolean convertFromTranslucent(IBinder token) {
9157        final long origId = Binder.clearCallingIdentity();
9158        try {
9159            synchronized (this) {
9160                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9161                if (r == null) {
9162                    return false;
9163                }
9164                if (r.changeWindowTranslucency(true)) {
9165                    mWindowManager.setAppFullscreen(token, true);
9166                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9167                    return true;
9168                }
9169                return false;
9170            }
9171        } finally {
9172            Binder.restoreCallingIdentity(origId);
9173        }
9174    }
9175
9176    @Override
9177    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9178        final long origId = Binder.clearCallingIdentity();
9179        try {
9180            synchronized (this) {
9181                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9182                if (r == null) {
9183                    return false;
9184                }
9185                if (r.changeWindowTranslucency(false)) {
9186                    r.task.stack.convertToTranslucent(r, options);
9187                    mWindowManager.setAppFullscreen(token, false);
9188                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9189                    return true;
9190                }
9191                return false;
9192            }
9193        } finally {
9194            Binder.restoreCallingIdentity(origId);
9195        }
9196    }
9197
9198    @Override
9199    public ActivityOptions getActivityOptions(IBinder token) {
9200        final long origId = Binder.clearCallingIdentity();
9201        try {
9202            synchronized (this) {
9203                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9204                if (r != null) {
9205                    final ActivityOptions activityOptions = r.pendingOptions;
9206                    r.pendingOptions = null;
9207                    return activityOptions;
9208                }
9209                return null;
9210            }
9211        } finally {
9212            Binder.restoreCallingIdentity(origId);
9213        }
9214    }
9215
9216    @Override
9217    public void setImmersive(IBinder token, boolean immersive) {
9218        synchronized(this) {
9219            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9220            if (r == null) {
9221                throw new IllegalArgumentException();
9222            }
9223            r.immersive = immersive;
9224
9225            // update associated state if we're frontmost
9226            if (r == mFocusedActivity) {
9227                if (DEBUG_IMMERSIVE) {
9228                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9229                }
9230                applyUpdateLockStateLocked(r);
9231            }
9232        }
9233    }
9234
9235    @Override
9236    public boolean isImmersive(IBinder token) {
9237        synchronized (this) {
9238            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9239            if (r == null) {
9240                throw new IllegalArgumentException();
9241            }
9242            return r.immersive;
9243        }
9244    }
9245
9246    public boolean isTopActivityImmersive() {
9247        enforceNotIsolatedCaller("startActivity");
9248        synchronized (this) {
9249            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9250            return (r != null) ? r.immersive : false;
9251        }
9252    }
9253
9254    public final void enterSafeMode() {
9255        synchronized(this) {
9256            // It only makes sense to do this before the system is ready
9257            // and started launching other packages.
9258            if (!mSystemReady) {
9259                try {
9260                    AppGlobals.getPackageManager().enterSafeMode();
9261                } catch (RemoteException e) {
9262                }
9263            }
9264
9265            mSafeMode = true;
9266        }
9267    }
9268
9269    public final void showSafeModeOverlay() {
9270        View v = LayoutInflater.from(mContext).inflate(
9271                com.android.internal.R.layout.safe_mode, null);
9272        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9273        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9274        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9275        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9276        lp.gravity = Gravity.BOTTOM | Gravity.START;
9277        lp.format = v.getBackground().getOpacity();
9278        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9279                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9280        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9281        ((WindowManager)mContext.getSystemService(
9282                Context.WINDOW_SERVICE)).addView(v, lp);
9283    }
9284
9285    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9286        if (!(sender instanceof PendingIntentRecord)) {
9287            return;
9288        }
9289        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9290        synchronized (stats) {
9291            if (mBatteryStatsService.isOnBattery()) {
9292                mBatteryStatsService.enforceCallingPermission();
9293                PendingIntentRecord rec = (PendingIntentRecord)sender;
9294                int MY_UID = Binder.getCallingUid();
9295                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9296                BatteryStatsImpl.Uid.Pkg pkg =
9297                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9298                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9299                pkg.incWakeupsLocked();
9300            }
9301        }
9302    }
9303
9304    public boolean killPids(int[] pids, String pReason, boolean secure) {
9305        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9306            throw new SecurityException("killPids only available to the system");
9307        }
9308        String reason = (pReason == null) ? "Unknown" : pReason;
9309        // XXX Note: don't acquire main activity lock here, because the window
9310        // manager calls in with its locks held.
9311
9312        boolean killed = false;
9313        synchronized (mPidsSelfLocked) {
9314            int[] types = new int[pids.length];
9315            int worstType = 0;
9316            for (int i=0; i<pids.length; i++) {
9317                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9318                if (proc != null) {
9319                    int type = proc.setAdj;
9320                    types[i] = type;
9321                    if (type > worstType) {
9322                        worstType = type;
9323                    }
9324                }
9325            }
9326
9327            // If the worst oom_adj is somewhere in the cached proc LRU range,
9328            // then constrain it so we will kill all cached procs.
9329            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9330                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9331                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9332            }
9333
9334            // If this is not a secure call, don't let it kill processes that
9335            // are important.
9336            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9337                worstType = ProcessList.SERVICE_ADJ;
9338            }
9339
9340            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9341            for (int i=0; i<pids.length; i++) {
9342                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9343                if (proc == null) {
9344                    continue;
9345                }
9346                int adj = proc.setAdj;
9347                if (adj >= worstType && !proc.killedByAm) {
9348                    killUnneededProcessLocked(proc, reason);
9349                    killed = true;
9350                }
9351            }
9352        }
9353        return killed;
9354    }
9355
9356    @Override
9357    public void killUid(int uid, String reason) {
9358        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9359            throw new SecurityException("killUid only available to the system");
9360        }
9361        synchronized (this) {
9362            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9363                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9364                    reason != null ? reason : "kill uid");
9365        }
9366    }
9367
9368    @Override
9369    public boolean killProcessesBelowForeground(String reason) {
9370        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9371            throw new SecurityException("killProcessesBelowForeground() only available to system");
9372        }
9373
9374        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9375    }
9376
9377    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9378        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9379            throw new SecurityException("killProcessesBelowAdj() only available to system");
9380        }
9381
9382        boolean killed = false;
9383        synchronized (mPidsSelfLocked) {
9384            final int size = mPidsSelfLocked.size();
9385            for (int i = 0; i < size; i++) {
9386                final int pid = mPidsSelfLocked.keyAt(i);
9387                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9388                if (proc == null) continue;
9389
9390                final int adj = proc.setAdj;
9391                if (adj > belowAdj && !proc.killedByAm) {
9392                    killUnneededProcessLocked(proc, reason);
9393                    killed = true;
9394                }
9395            }
9396        }
9397        return killed;
9398    }
9399
9400    @Override
9401    public void hang(final IBinder who, boolean allowRestart) {
9402        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9403                != PackageManager.PERMISSION_GRANTED) {
9404            throw new SecurityException("Requires permission "
9405                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9406        }
9407
9408        final IBinder.DeathRecipient death = new DeathRecipient() {
9409            @Override
9410            public void binderDied() {
9411                synchronized (this) {
9412                    notifyAll();
9413                }
9414            }
9415        };
9416
9417        try {
9418            who.linkToDeath(death, 0);
9419        } catch (RemoteException e) {
9420            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9421            return;
9422        }
9423
9424        synchronized (this) {
9425            Watchdog.getInstance().setAllowRestart(allowRestart);
9426            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9427            synchronized (death) {
9428                while (who.isBinderAlive()) {
9429                    try {
9430                        death.wait();
9431                    } catch (InterruptedException e) {
9432                    }
9433                }
9434            }
9435            Watchdog.getInstance().setAllowRestart(true);
9436        }
9437    }
9438
9439    @Override
9440    public void restart() {
9441        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9442                != PackageManager.PERMISSION_GRANTED) {
9443            throw new SecurityException("Requires permission "
9444                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9445        }
9446
9447        Log.i(TAG, "Sending shutdown broadcast...");
9448
9449        BroadcastReceiver br = new BroadcastReceiver() {
9450            @Override public void onReceive(Context context, Intent intent) {
9451                // Now the broadcast is done, finish up the low-level shutdown.
9452                Log.i(TAG, "Shutting down activity manager...");
9453                shutdown(10000);
9454                Log.i(TAG, "Shutdown complete, restarting!");
9455                Process.killProcess(Process.myPid());
9456                System.exit(10);
9457            }
9458        };
9459
9460        // First send the high-level shut down broadcast.
9461        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9462        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9463        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9464        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9465        mContext.sendOrderedBroadcastAsUser(intent,
9466                UserHandle.ALL, null, br, mHandler, 0, null, null);
9467        */
9468        br.onReceive(mContext, intent);
9469    }
9470
9471    private long getLowRamTimeSinceIdle(long now) {
9472        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9473    }
9474
9475    @Override
9476    public void performIdleMaintenance() {
9477        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9478                != PackageManager.PERMISSION_GRANTED) {
9479            throw new SecurityException("Requires permission "
9480                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9481        }
9482
9483        synchronized (this) {
9484            final long now = SystemClock.uptimeMillis();
9485            final long timeSinceLastIdle = now - mLastIdleTime;
9486            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9487            mLastIdleTime = now;
9488            mLowRamTimeSinceLastIdle = 0;
9489            if (mLowRamStartTime != 0) {
9490                mLowRamStartTime = now;
9491            }
9492
9493            StringBuilder sb = new StringBuilder(128);
9494            sb.append("Idle maintenance over ");
9495            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9496            sb.append(" low RAM for ");
9497            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9498            Slog.i(TAG, sb.toString());
9499
9500            // If at least 1/3 of our time since the last idle period has been spent
9501            // with RAM low, then we want to kill processes.
9502            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9503
9504            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9505                ProcessRecord proc = mLruProcesses.get(i);
9506                if (proc.notCachedSinceIdle) {
9507                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9508                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9509                        if (doKilling && proc.initialIdlePss != 0
9510                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9511                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9512                                    + " from " + proc.initialIdlePss + ")");
9513                        }
9514                    }
9515                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9516                    proc.notCachedSinceIdle = true;
9517                    proc.initialIdlePss = 0;
9518                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9519                            isSleeping(), now);
9520                }
9521            }
9522
9523            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9524            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9525        }
9526    }
9527
9528    private void retrieveSettings() {
9529        final ContentResolver resolver = mContext.getContentResolver();
9530        String debugApp = Settings.Global.getString(
9531            resolver, Settings.Global.DEBUG_APP);
9532        boolean waitForDebugger = Settings.Global.getInt(
9533            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9534        boolean alwaysFinishActivities = Settings.Global.getInt(
9535            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9536        boolean forceRtl = Settings.Global.getInt(
9537                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9538        // Transfer any global setting for forcing RTL layout, into a System Property
9539        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9540
9541        Configuration configuration = new Configuration();
9542        Settings.System.getConfiguration(resolver, configuration);
9543        if (forceRtl) {
9544            // This will take care of setting the correct layout direction flags
9545            configuration.setLayoutDirection(configuration.locale);
9546        }
9547
9548        synchronized (this) {
9549            mDebugApp = mOrigDebugApp = debugApp;
9550            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9551            mAlwaysFinishActivities = alwaysFinishActivities;
9552            // This happens before any activities are started, so we can
9553            // change mConfiguration in-place.
9554            updateConfigurationLocked(configuration, null, false, true);
9555            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9556        }
9557    }
9558
9559    public boolean testIsSystemReady() {
9560        // no need to synchronize(this) just to read & return the value
9561        return mSystemReady;
9562    }
9563
9564    private static File getCalledPreBootReceiversFile() {
9565        File dataDir = Environment.getDataDirectory();
9566        File systemDir = new File(dataDir, "system");
9567        File fname = new File(systemDir, "called_pre_boots.dat");
9568        return fname;
9569    }
9570
9571    static final int LAST_DONE_VERSION = 10000;
9572
9573    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9574        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9575        File file = getCalledPreBootReceiversFile();
9576        FileInputStream fis = null;
9577        try {
9578            fis = new FileInputStream(file);
9579            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9580            int fvers = dis.readInt();
9581            if (fvers == LAST_DONE_VERSION) {
9582                String vers = dis.readUTF();
9583                String codename = dis.readUTF();
9584                String build = dis.readUTF();
9585                if (android.os.Build.VERSION.RELEASE.equals(vers)
9586                        && android.os.Build.VERSION.CODENAME.equals(codename)
9587                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9588                    int num = dis.readInt();
9589                    while (num > 0) {
9590                        num--;
9591                        String pkg = dis.readUTF();
9592                        String cls = dis.readUTF();
9593                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9594                    }
9595                }
9596            }
9597        } catch (FileNotFoundException e) {
9598        } catch (IOException e) {
9599            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9600        } finally {
9601            if (fis != null) {
9602                try {
9603                    fis.close();
9604                } catch (IOException e) {
9605                }
9606            }
9607        }
9608        return lastDoneReceivers;
9609    }
9610
9611    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9612        File file = getCalledPreBootReceiversFile();
9613        FileOutputStream fos = null;
9614        DataOutputStream dos = null;
9615        try {
9616            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9617            fos = new FileOutputStream(file);
9618            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9619            dos.writeInt(LAST_DONE_VERSION);
9620            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9621            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9622            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9623            dos.writeInt(list.size());
9624            for (int i=0; i<list.size(); i++) {
9625                dos.writeUTF(list.get(i).getPackageName());
9626                dos.writeUTF(list.get(i).getClassName());
9627            }
9628        } catch (IOException e) {
9629            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9630            file.delete();
9631        } finally {
9632            FileUtils.sync(fos);
9633            if (dos != null) {
9634                try {
9635                    dos.close();
9636                } catch (IOException e) {
9637                    // TODO Auto-generated catch block
9638                    e.printStackTrace();
9639                }
9640            }
9641        }
9642    }
9643
9644    public void systemReady(final Runnable goingCallback) {
9645        synchronized(this) {
9646            if (mSystemReady) {
9647                if (goingCallback != null) goingCallback.run();
9648                return;
9649            }
9650
9651            if (mRecentTasks == null) {
9652                mRecentTasks = mTaskPersister.restoreTasksLocked();
9653                if (!mRecentTasks.isEmpty()) {
9654                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9655                }
9656                mTaskPersister.startPersisting();
9657            }
9658
9659            // Check to see if there are any update receivers to run.
9660            if (!mDidUpdate) {
9661                if (mWaitingUpdate) {
9662                    return;
9663                }
9664                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9665                List<ResolveInfo> ris = null;
9666                try {
9667                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9668                            intent, null, 0, 0);
9669                } catch (RemoteException e) {
9670                }
9671                if (ris != null) {
9672                    for (int i=ris.size()-1; i>=0; i--) {
9673                        if ((ris.get(i).activityInfo.applicationInfo.flags
9674                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9675                            ris.remove(i);
9676                        }
9677                    }
9678                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9679
9680                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9681
9682                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9683                    for (int i=0; i<ris.size(); i++) {
9684                        ActivityInfo ai = ris.get(i).activityInfo;
9685                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9686                        if (lastDoneReceivers.contains(comp)) {
9687                            // We already did the pre boot receiver for this app with the current
9688                            // platform version, so don't do it again...
9689                            ris.remove(i);
9690                            i--;
9691                            // ...however, do keep it as one that has been done, so we don't
9692                            // forget about it when rewriting the file of last done receivers.
9693                            doneReceivers.add(comp);
9694                        }
9695                    }
9696
9697                    final int[] users = getUsersLocked();
9698                    for (int i=0; i<ris.size(); i++) {
9699                        ActivityInfo ai = ris.get(i).activityInfo;
9700                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9701                        doneReceivers.add(comp);
9702                        intent.setComponent(comp);
9703                        for (int j=0; j<users.length; j++) {
9704                            IIntentReceiver finisher = null;
9705                            if (i == ris.size()-1 && j == users.length-1) {
9706                                finisher = new IIntentReceiver.Stub() {
9707                                    public void performReceive(Intent intent, int resultCode,
9708                                            String data, Bundle extras, boolean ordered,
9709                                            boolean sticky, int sendingUser) {
9710                                        // The raw IIntentReceiver interface is called
9711                                        // with the AM lock held, so redispatch to
9712                                        // execute our code without the lock.
9713                                        mHandler.post(new Runnable() {
9714                                            public void run() {
9715                                                synchronized (ActivityManagerService.this) {
9716                                                    mDidUpdate = true;
9717                                                }
9718                                                writeLastDonePreBootReceivers(doneReceivers);
9719                                                showBootMessage(mContext.getText(
9720                                                        R.string.android_upgrading_complete),
9721                                                        false);
9722                                                systemReady(goingCallback);
9723                                            }
9724                                        });
9725                                    }
9726                                };
9727                            }
9728                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9729                                    + " for user " + users[j]);
9730                            broadcastIntentLocked(null, null, intent, null, finisher,
9731                                    0, null, null, null, AppOpsManager.OP_NONE,
9732                                    true, false, MY_PID, Process.SYSTEM_UID,
9733                                    users[j]);
9734                            if (finisher != null) {
9735                                mWaitingUpdate = true;
9736                            }
9737                        }
9738                    }
9739                }
9740                if (mWaitingUpdate) {
9741                    return;
9742                }
9743                mDidUpdate = true;
9744            }
9745
9746            mAppOpsService.systemReady();
9747            mUsageStatsService.systemReady();
9748            mSystemReady = true;
9749        }
9750
9751        ArrayList<ProcessRecord> procsToKill = null;
9752        synchronized(mPidsSelfLocked) {
9753            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9754                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9755                if (!isAllowedWhileBooting(proc.info)){
9756                    if (procsToKill == null) {
9757                        procsToKill = new ArrayList<ProcessRecord>();
9758                    }
9759                    procsToKill.add(proc);
9760                }
9761            }
9762        }
9763
9764        synchronized(this) {
9765            if (procsToKill != null) {
9766                for (int i=procsToKill.size()-1; i>=0; i--) {
9767                    ProcessRecord proc = procsToKill.get(i);
9768                    Slog.i(TAG, "Removing system update proc: " + proc);
9769                    removeProcessLocked(proc, true, false, "system update done");
9770                }
9771            }
9772
9773            // Now that we have cleaned up any update processes, we
9774            // are ready to start launching real processes and know that
9775            // we won't trample on them any more.
9776            mProcessesReady = true;
9777        }
9778
9779        Slog.i(TAG, "System now ready");
9780        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9781            SystemClock.uptimeMillis());
9782
9783        synchronized(this) {
9784            // Make sure we have no pre-ready processes sitting around.
9785
9786            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9787                ResolveInfo ri = mContext.getPackageManager()
9788                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9789                                STOCK_PM_FLAGS);
9790                CharSequence errorMsg = null;
9791                if (ri != null) {
9792                    ActivityInfo ai = ri.activityInfo;
9793                    ApplicationInfo app = ai.applicationInfo;
9794                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9795                        mTopAction = Intent.ACTION_FACTORY_TEST;
9796                        mTopData = null;
9797                        mTopComponent = new ComponentName(app.packageName,
9798                                ai.name);
9799                    } else {
9800                        errorMsg = mContext.getResources().getText(
9801                                com.android.internal.R.string.factorytest_not_system);
9802                    }
9803                } else {
9804                    errorMsg = mContext.getResources().getText(
9805                            com.android.internal.R.string.factorytest_no_action);
9806                }
9807                if (errorMsg != null) {
9808                    mTopAction = null;
9809                    mTopData = null;
9810                    mTopComponent = null;
9811                    Message msg = Message.obtain();
9812                    msg.what = SHOW_FACTORY_ERROR_MSG;
9813                    msg.getData().putCharSequence("msg", errorMsg);
9814                    mHandler.sendMessage(msg);
9815                }
9816            }
9817        }
9818
9819        retrieveSettings();
9820
9821        synchronized (this) {
9822            readGrantedUriPermissionsLocked();
9823        }
9824
9825        if (goingCallback != null) goingCallback.run();
9826
9827        mSystemServiceManager.startUser(mCurrentUserId);
9828
9829        synchronized (this) {
9830            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9831                try {
9832                    List apps = AppGlobals.getPackageManager().
9833                        getPersistentApplications(STOCK_PM_FLAGS);
9834                    if (apps != null) {
9835                        int N = apps.size();
9836                        int i;
9837                        for (i=0; i<N; i++) {
9838                            ApplicationInfo info
9839                                = (ApplicationInfo)apps.get(i);
9840                            if (info != null &&
9841                                    !info.packageName.equals("android")) {
9842                                addAppLocked(info, false, null /* ABI override */);
9843                            }
9844                        }
9845                    }
9846                } catch (RemoteException ex) {
9847                    // pm is in same process, this will never happen.
9848                }
9849            }
9850
9851            // Start up initial activity.
9852            mBooting = true;
9853
9854            try {
9855                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9856                    Message msg = Message.obtain();
9857                    msg.what = SHOW_UID_ERROR_MSG;
9858                    mHandler.sendMessage(msg);
9859                }
9860            } catch (RemoteException e) {
9861            }
9862
9863            long ident = Binder.clearCallingIdentity();
9864            try {
9865                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9866                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9867                        | Intent.FLAG_RECEIVER_FOREGROUND);
9868                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9869                broadcastIntentLocked(null, null, intent,
9870                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9871                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9872                intent = new Intent(Intent.ACTION_USER_STARTING);
9873                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9874                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9875                broadcastIntentLocked(null, null, intent,
9876                        null, new IIntentReceiver.Stub() {
9877                            @Override
9878                            public void performReceive(Intent intent, int resultCode, String data,
9879                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9880                                    throws RemoteException {
9881                            }
9882                        }, 0, null, null,
9883                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9884                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9885            } catch (Throwable t) {
9886                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9887            } finally {
9888                Binder.restoreCallingIdentity(ident);
9889            }
9890            mStackSupervisor.resumeTopActivitiesLocked();
9891            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9892        }
9893    }
9894
9895    private boolean makeAppCrashingLocked(ProcessRecord app,
9896            String shortMsg, String longMsg, String stackTrace) {
9897        app.crashing = true;
9898        app.crashingReport = generateProcessError(app,
9899                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9900        startAppProblemLocked(app);
9901        app.stopFreezingAllLocked();
9902        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9903    }
9904
9905    private void makeAppNotRespondingLocked(ProcessRecord app,
9906            String activity, String shortMsg, String longMsg) {
9907        app.notResponding = true;
9908        app.notRespondingReport = generateProcessError(app,
9909                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9910                activity, shortMsg, longMsg, null);
9911        startAppProblemLocked(app);
9912        app.stopFreezingAllLocked();
9913    }
9914
9915    /**
9916     * Generate a process error record, suitable for attachment to a ProcessRecord.
9917     *
9918     * @param app The ProcessRecord in which the error occurred.
9919     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9920     *                      ActivityManager.AppErrorStateInfo
9921     * @param activity The activity associated with the crash, if known.
9922     * @param shortMsg Short message describing the crash.
9923     * @param longMsg Long message describing the crash.
9924     * @param stackTrace Full crash stack trace, may be null.
9925     *
9926     * @return Returns a fully-formed AppErrorStateInfo record.
9927     */
9928    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9929            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9930        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9931
9932        report.condition = condition;
9933        report.processName = app.processName;
9934        report.pid = app.pid;
9935        report.uid = app.info.uid;
9936        report.tag = activity;
9937        report.shortMsg = shortMsg;
9938        report.longMsg = longMsg;
9939        report.stackTrace = stackTrace;
9940
9941        return report;
9942    }
9943
9944    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9945        synchronized (this) {
9946            app.crashing = false;
9947            app.crashingReport = null;
9948            app.notResponding = false;
9949            app.notRespondingReport = null;
9950            if (app.anrDialog == fromDialog) {
9951                app.anrDialog = null;
9952            }
9953            if (app.waitDialog == fromDialog) {
9954                app.waitDialog = null;
9955            }
9956            if (app.pid > 0 && app.pid != MY_PID) {
9957                handleAppCrashLocked(app, null, null, null);
9958                killUnneededProcessLocked(app, "user request after error");
9959            }
9960        }
9961    }
9962
9963    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9964            String stackTrace) {
9965        long now = SystemClock.uptimeMillis();
9966
9967        Long crashTime;
9968        if (!app.isolated) {
9969            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9970        } else {
9971            crashTime = null;
9972        }
9973        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9974            // This process loses!
9975            Slog.w(TAG, "Process " + app.info.processName
9976                    + " has crashed too many times: killing!");
9977            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9978                    app.userId, app.info.processName, app.uid);
9979            mStackSupervisor.handleAppCrashLocked(app);
9980            if (!app.persistent) {
9981                // We don't want to start this process again until the user
9982                // explicitly does so...  but for persistent process, we really
9983                // need to keep it running.  If a persistent process is actually
9984                // repeatedly crashing, then badness for everyone.
9985                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9986                        app.info.processName);
9987                if (!app.isolated) {
9988                    // XXX We don't have a way to mark isolated processes
9989                    // as bad, since they don't have a peristent identity.
9990                    mBadProcesses.put(app.info.processName, app.uid,
9991                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9992                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9993                }
9994                app.bad = true;
9995                app.removed = true;
9996                // Don't let services in this process be restarted and potentially
9997                // annoy the user repeatedly.  Unless it is persistent, since those
9998                // processes run critical code.
9999                removeProcessLocked(app, false, false, "crash");
10000                mStackSupervisor.resumeTopActivitiesLocked();
10001                return false;
10002            }
10003            mStackSupervisor.resumeTopActivitiesLocked();
10004        } else {
10005            mStackSupervisor.finishTopRunningActivityLocked(app);
10006        }
10007
10008        // Bump up the crash count of any services currently running in the proc.
10009        for (int i=app.services.size()-1; i>=0; i--) {
10010            // Any services running in the application need to be placed
10011            // back in the pending list.
10012            ServiceRecord sr = app.services.valueAt(i);
10013            sr.crashCount++;
10014        }
10015
10016        // If the crashing process is what we consider to be the "home process" and it has been
10017        // replaced by a third-party app, clear the package preferred activities from packages
10018        // with a home activity running in the process to prevent a repeatedly crashing app
10019        // from blocking the user to manually clear the list.
10020        final ArrayList<ActivityRecord> activities = app.activities;
10021        if (app == mHomeProcess && activities.size() > 0
10022                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10023            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10024                final ActivityRecord r = activities.get(activityNdx);
10025                if (r.isHomeActivity()) {
10026                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10027                    try {
10028                        ActivityThread.getPackageManager()
10029                                .clearPackagePreferredActivities(r.packageName);
10030                    } catch (RemoteException c) {
10031                        // pm is in same process, this will never happen.
10032                    }
10033                }
10034            }
10035        }
10036
10037        if (!app.isolated) {
10038            // XXX Can't keep track of crash times for isolated processes,
10039            // because they don't have a perisistent identity.
10040            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10041        }
10042
10043        return true;
10044    }
10045
10046    void startAppProblemLocked(ProcessRecord app) {
10047        if (app.userId == mCurrentUserId) {
10048            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10049                    mContext, app.info.packageName, app.info.flags);
10050        } else {
10051            // If this app is not running under the current user, then we
10052            // can't give it a report button because that would require
10053            // launching the report UI under a different user.
10054            app.errorReportReceiver = null;
10055        }
10056        skipCurrentReceiverLocked(app);
10057    }
10058
10059    void skipCurrentReceiverLocked(ProcessRecord app) {
10060        for (BroadcastQueue queue : mBroadcastQueues) {
10061            queue.skipCurrentReceiverLocked(app);
10062        }
10063    }
10064
10065    /**
10066     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10067     * The application process will exit immediately after this call returns.
10068     * @param app object of the crashing app, null for the system server
10069     * @param crashInfo describing the exception
10070     */
10071    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10072        ProcessRecord r = findAppProcess(app, "Crash");
10073        final String processName = app == null ? "system_server"
10074                : (r == null ? "unknown" : r.processName);
10075
10076        handleApplicationCrashInner("crash", r, processName, crashInfo);
10077    }
10078
10079    /* Native crash reporting uses this inner version because it needs to be somewhat
10080     * decoupled from the AM-managed cleanup lifecycle
10081     */
10082    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10083            ApplicationErrorReport.CrashInfo crashInfo) {
10084        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10085                UserHandle.getUserId(Binder.getCallingUid()), processName,
10086                r == null ? -1 : r.info.flags,
10087                crashInfo.exceptionClassName,
10088                crashInfo.exceptionMessage,
10089                crashInfo.throwFileName,
10090                crashInfo.throwLineNumber);
10091
10092        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10093
10094        crashApplication(r, crashInfo);
10095    }
10096
10097    public void handleApplicationStrictModeViolation(
10098            IBinder app,
10099            int violationMask,
10100            StrictMode.ViolationInfo info) {
10101        ProcessRecord r = findAppProcess(app, "StrictMode");
10102        if (r == null) {
10103            return;
10104        }
10105
10106        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10107            Integer stackFingerprint = info.hashCode();
10108            boolean logIt = true;
10109            synchronized (mAlreadyLoggedViolatedStacks) {
10110                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10111                    logIt = false;
10112                    // TODO: sub-sample into EventLog for these, with
10113                    // the info.durationMillis?  Then we'd get
10114                    // the relative pain numbers, without logging all
10115                    // the stack traces repeatedly.  We'd want to do
10116                    // likewise in the client code, which also does
10117                    // dup suppression, before the Binder call.
10118                } else {
10119                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10120                        mAlreadyLoggedViolatedStacks.clear();
10121                    }
10122                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10123                }
10124            }
10125            if (logIt) {
10126                logStrictModeViolationToDropBox(r, info);
10127            }
10128        }
10129
10130        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10131            AppErrorResult result = new AppErrorResult();
10132            synchronized (this) {
10133                final long origId = Binder.clearCallingIdentity();
10134
10135                Message msg = Message.obtain();
10136                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10137                HashMap<String, Object> data = new HashMap<String, Object>();
10138                data.put("result", result);
10139                data.put("app", r);
10140                data.put("violationMask", violationMask);
10141                data.put("info", info);
10142                msg.obj = data;
10143                mHandler.sendMessage(msg);
10144
10145                Binder.restoreCallingIdentity(origId);
10146            }
10147            int res = result.get();
10148            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10149        }
10150    }
10151
10152    // Depending on the policy in effect, there could be a bunch of
10153    // these in quick succession so we try to batch these together to
10154    // minimize disk writes, number of dropbox entries, and maximize
10155    // compression, by having more fewer, larger records.
10156    private void logStrictModeViolationToDropBox(
10157            ProcessRecord process,
10158            StrictMode.ViolationInfo info) {
10159        if (info == null) {
10160            return;
10161        }
10162        final boolean isSystemApp = process == null ||
10163                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10164                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10165        final String processName = process == null ? "unknown" : process.processName;
10166        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10167        final DropBoxManager dbox = (DropBoxManager)
10168                mContext.getSystemService(Context.DROPBOX_SERVICE);
10169
10170        // Exit early if the dropbox isn't configured to accept this report type.
10171        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10172
10173        boolean bufferWasEmpty;
10174        boolean needsFlush;
10175        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10176        synchronized (sb) {
10177            bufferWasEmpty = sb.length() == 0;
10178            appendDropBoxProcessHeaders(process, processName, sb);
10179            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10180            sb.append("System-App: ").append(isSystemApp).append("\n");
10181            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10182            if (info.violationNumThisLoop != 0) {
10183                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10184            }
10185            if (info.numAnimationsRunning != 0) {
10186                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10187            }
10188            if (info.broadcastIntentAction != null) {
10189                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10190            }
10191            if (info.durationMillis != -1) {
10192                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10193            }
10194            if (info.numInstances != -1) {
10195                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10196            }
10197            if (info.tags != null) {
10198                for (String tag : info.tags) {
10199                    sb.append("Span-Tag: ").append(tag).append("\n");
10200                }
10201            }
10202            sb.append("\n");
10203            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10204                sb.append(info.crashInfo.stackTrace);
10205            }
10206            sb.append("\n");
10207
10208            // Only buffer up to ~64k.  Various logging bits truncate
10209            // things at 128k.
10210            needsFlush = (sb.length() > 64 * 1024);
10211        }
10212
10213        // Flush immediately if the buffer's grown too large, or this
10214        // is a non-system app.  Non-system apps are isolated with a
10215        // different tag & policy and not batched.
10216        //
10217        // Batching is useful during internal testing with
10218        // StrictMode settings turned up high.  Without batching,
10219        // thousands of separate files could be created on boot.
10220        if (!isSystemApp || needsFlush) {
10221            new Thread("Error dump: " + dropboxTag) {
10222                @Override
10223                public void run() {
10224                    String report;
10225                    synchronized (sb) {
10226                        report = sb.toString();
10227                        sb.delete(0, sb.length());
10228                        sb.trimToSize();
10229                    }
10230                    if (report.length() != 0) {
10231                        dbox.addText(dropboxTag, report);
10232                    }
10233                }
10234            }.start();
10235            return;
10236        }
10237
10238        // System app batching:
10239        if (!bufferWasEmpty) {
10240            // An existing dropbox-writing thread is outstanding, so
10241            // we don't need to start it up.  The existing thread will
10242            // catch the buffer appends we just did.
10243            return;
10244        }
10245
10246        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10247        // (After this point, we shouldn't access AMS internal data structures.)
10248        new Thread("Error dump: " + dropboxTag) {
10249            @Override
10250            public void run() {
10251                // 5 second sleep to let stacks arrive and be batched together
10252                try {
10253                    Thread.sleep(5000);  // 5 seconds
10254                } catch (InterruptedException e) {}
10255
10256                String errorReport;
10257                synchronized (mStrictModeBuffer) {
10258                    errorReport = mStrictModeBuffer.toString();
10259                    if (errorReport.length() == 0) {
10260                        return;
10261                    }
10262                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10263                    mStrictModeBuffer.trimToSize();
10264                }
10265                dbox.addText(dropboxTag, errorReport);
10266            }
10267        }.start();
10268    }
10269
10270    /**
10271     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10272     * @param app object of the crashing app, null for the system server
10273     * @param tag reported by the caller
10274     * @param crashInfo describing the context of the error
10275     * @return true if the process should exit immediately (WTF is fatal)
10276     */
10277    public boolean handleApplicationWtf(IBinder app, String tag,
10278            ApplicationErrorReport.CrashInfo crashInfo) {
10279        ProcessRecord r = findAppProcess(app, "WTF");
10280        final String processName = app == null ? "system_server"
10281                : (r == null ? "unknown" : r.processName);
10282
10283        EventLog.writeEvent(EventLogTags.AM_WTF,
10284                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10285                processName,
10286                r == null ? -1 : r.info.flags,
10287                tag, crashInfo.exceptionMessage);
10288
10289        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10290
10291        if (r != null && r.pid != Process.myPid() &&
10292                Settings.Global.getInt(mContext.getContentResolver(),
10293                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10294            crashApplication(r, crashInfo);
10295            return true;
10296        } else {
10297            return false;
10298        }
10299    }
10300
10301    /**
10302     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10303     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10304     */
10305    private ProcessRecord findAppProcess(IBinder app, String reason) {
10306        if (app == null) {
10307            return null;
10308        }
10309
10310        synchronized (this) {
10311            final int NP = mProcessNames.getMap().size();
10312            for (int ip=0; ip<NP; ip++) {
10313                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10314                final int NA = apps.size();
10315                for (int ia=0; ia<NA; ia++) {
10316                    ProcessRecord p = apps.valueAt(ia);
10317                    if (p.thread != null && p.thread.asBinder() == app) {
10318                        return p;
10319                    }
10320                }
10321            }
10322
10323            Slog.w(TAG, "Can't find mystery application for " + reason
10324                    + " from pid=" + Binder.getCallingPid()
10325                    + " uid=" + Binder.getCallingUid() + ": " + app);
10326            return null;
10327        }
10328    }
10329
10330    /**
10331     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10332     * to append various headers to the dropbox log text.
10333     */
10334    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10335            StringBuilder sb) {
10336        // Watchdog thread ends up invoking this function (with
10337        // a null ProcessRecord) to add the stack file to dropbox.
10338        // Do not acquire a lock on this (am) in such cases, as it
10339        // could cause a potential deadlock, if and when watchdog
10340        // is invoked due to unavailability of lock on am and it
10341        // would prevent watchdog from killing system_server.
10342        if (process == null) {
10343            sb.append("Process: ").append(processName).append("\n");
10344            return;
10345        }
10346        // Note: ProcessRecord 'process' is guarded by the service
10347        // instance.  (notably process.pkgList, which could otherwise change
10348        // concurrently during execution of this method)
10349        synchronized (this) {
10350            sb.append("Process: ").append(processName).append("\n");
10351            int flags = process.info.flags;
10352            IPackageManager pm = AppGlobals.getPackageManager();
10353            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10354            for (int ip=0; ip<process.pkgList.size(); ip++) {
10355                String pkg = process.pkgList.keyAt(ip);
10356                sb.append("Package: ").append(pkg);
10357                try {
10358                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10359                    if (pi != null) {
10360                        sb.append(" v").append(pi.versionCode);
10361                        if (pi.versionName != null) {
10362                            sb.append(" (").append(pi.versionName).append(")");
10363                        }
10364                    }
10365                } catch (RemoteException e) {
10366                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10367                }
10368                sb.append("\n");
10369            }
10370        }
10371    }
10372
10373    private static String processClass(ProcessRecord process) {
10374        if (process == null || process.pid == MY_PID) {
10375            return "system_server";
10376        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10377            return "system_app";
10378        } else {
10379            return "data_app";
10380        }
10381    }
10382
10383    /**
10384     * Write a description of an error (crash, WTF, ANR) to the drop box.
10385     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10386     * @param process which caused the error, null means the system server
10387     * @param activity which triggered the error, null if unknown
10388     * @param parent activity related to the error, null if unknown
10389     * @param subject line related to the error, null if absent
10390     * @param report in long form describing the error, null if absent
10391     * @param logFile to include in the report, null if none
10392     * @param crashInfo giving an application stack trace, null if absent
10393     */
10394    public void addErrorToDropBox(String eventType,
10395            ProcessRecord process, String processName, ActivityRecord activity,
10396            ActivityRecord parent, String subject,
10397            final String report, final File logFile,
10398            final ApplicationErrorReport.CrashInfo crashInfo) {
10399        // NOTE -- this must never acquire the ActivityManagerService lock,
10400        // otherwise the watchdog may be prevented from resetting the system.
10401
10402        final String dropboxTag = processClass(process) + "_" + eventType;
10403        final DropBoxManager dbox = (DropBoxManager)
10404                mContext.getSystemService(Context.DROPBOX_SERVICE);
10405
10406        // Exit early if the dropbox isn't configured to accept this report type.
10407        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10408
10409        final StringBuilder sb = new StringBuilder(1024);
10410        appendDropBoxProcessHeaders(process, processName, sb);
10411        if (activity != null) {
10412            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10413        }
10414        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10415            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10416        }
10417        if (parent != null && parent != activity) {
10418            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10419        }
10420        if (subject != null) {
10421            sb.append("Subject: ").append(subject).append("\n");
10422        }
10423        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10424        if (Debug.isDebuggerConnected()) {
10425            sb.append("Debugger: Connected\n");
10426        }
10427        sb.append("\n");
10428
10429        // Do the rest in a worker thread to avoid blocking the caller on I/O
10430        // (After this point, we shouldn't access AMS internal data structures.)
10431        Thread worker = new Thread("Error dump: " + dropboxTag) {
10432            @Override
10433            public void run() {
10434                if (report != null) {
10435                    sb.append(report);
10436                }
10437                if (logFile != null) {
10438                    try {
10439                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10440                                    "\n\n[[TRUNCATED]]"));
10441                    } catch (IOException e) {
10442                        Slog.e(TAG, "Error reading " + logFile, e);
10443                    }
10444                }
10445                if (crashInfo != null && crashInfo.stackTrace != null) {
10446                    sb.append(crashInfo.stackTrace);
10447                }
10448
10449                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10450                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10451                if (lines > 0) {
10452                    sb.append("\n");
10453
10454                    // Merge several logcat streams, and take the last N lines
10455                    InputStreamReader input = null;
10456                    try {
10457                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10458                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10459                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10460
10461                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10462                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10463                        input = new InputStreamReader(logcat.getInputStream());
10464
10465                        int num;
10466                        char[] buf = new char[8192];
10467                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10468                    } catch (IOException e) {
10469                        Slog.e(TAG, "Error running logcat", e);
10470                    } finally {
10471                        if (input != null) try { input.close(); } catch (IOException e) {}
10472                    }
10473                }
10474
10475                dbox.addText(dropboxTag, sb.toString());
10476            }
10477        };
10478
10479        if (process == null) {
10480            // If process is null, we are being called from some internal code
10481            // and may be about to die -- run this synchronously.
10482            worker.run();
10483        } else {
10484            worker.start();
10485        }
10486    }
10487
10488    /**
10489     * Bring up the "unexpected error" dialog box for a crashing app.
10490     * Deal with edge cases (intercepts from instrumented applications,
10491     * ActivityController, error intent receivers, that sort of thing).
10492     * @param r the application crashing
10493     * @param crashInfo describing the failure
10494     */
10495    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10496        long timeMillis = System.currentTimeMillis();
10497        String shortMsg = crashInfo.exceptionClassName;
10498        String longMsg = crashInfo.exceptionMessage;
10499        String stackTrace = crashInfo.stackTrace;
10500        if (shortMsg != null && longMsg != null) {
10501            longMsg = shortMsg + ": " + longMsg;
10502        } else if (shortMsg != null) {
10503            longMsg = shortMsg;
10504        }
10505
10506        AppErrorResult result = new AppErrorResult();
10507        synchronized (this) {
10508            if (mController != null) {
10509                try {
10510                    String name = r != null ? r.processName : null;
10511                    int pid = r != null ? r.pid : Binder.getCallingPid();
10512                    if (!mController.appCrashed(name, pid,
10513                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10514                        Slog.w(TAG, "Force-killing crashed app " + name
10515                                + " at watcher's request");
10516                        Process.killProcess(pid);
10517                        return;
10518                    }
10519                } catch (RemoteException e) {
10520                    mController = null;
10521                    Watchdog.getInstance().setActivityController(null);
10522                }
10523            }
10524
10525            final long origId = Binder.clearCallingIdentity();
10526
10527            // If this process is running instrumentation, finish it.
10528            if (r != null && r.instrumentationClass != null) {
10529                Slog.w(TAG, "Error in app " + r.processName
10530                      + " running instrumentation " + r.instrumentationClass + ":");
10531                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10532                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10533                Bundle info = new Bundle();
10534                info.putString("shortMsg", shortMsg);
10535                info.putString("longMsg", longMsg);
10536                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10537                Binder.restoreCallingIdentity(origId);
10538                return;
10539            }
10540
10541            // If we can't identify the process or it's already exceeded its crash quota,
10542            // quit right away without showing a crash dialog.
10543            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10544                Binder.restoreCallingIdentity(origId);
10545                return;
10546            }
10547
10548            Message msg = Message.obtain();
10549            msg.what = SHOW_ERROR_MSG;
10550            HashMap data = new HashMap();
10551            data.put("result", result);
10552            data.put("app", r);
10553            msg.obj = data;
10554            mHandler.sendMessage(msg);
10555
10556            Binder.restoreCallingIdentity(origId);
10557        }
10558
10559        int res = result.get();
10560
10561        Intent appErrorIntent = null;
10562        synchronized (this) {
10563            if (r != null && !r.isolated) {
10564                // XXX Can't keep track of crash time for isolated processes,
10565                // since they don't have a persistent identity.
10566                mProcessCrashTimes.put(r.info.processName, r.uid,
10567                        SystemClock.uptimeMillis());
10568            }
10569            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10570                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10571            }
10572        }
10573
10574        if (appErrorIntent != null) {
10575            try {
10576                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10577            } catch (ActivityNotFoundException e) {
10578                Slog.w(TAG, "bug report receiver dissappeared", e);
10579            }
10580        }
10581    }
10582
10583    Intent createAppErrorIntentLocked(ProcessRecord r,
10584            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10585        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10586        if (report == null) {
10587            return null;
10588        }
10589        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10590        result.setComponent(r.errorReportReceiver);
10591        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10592        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10593        return result;
10594    }
10595
10596    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10597            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10598        if (r.errorReportReceiver == null) {
10599            return null;
10600        }
10601
10602        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10603            return null;
10604        }
10605
10606        ApplicationErrorReport report = new ApplicationErrorReport();
10607        report.packageName = r.info.packageName;
10608        report.installerPackageName = r.errorReportReceiver.getPackageName();
10609        report.processName = r.processName;
10610        report.time = timeMillis;
10611        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10612
10613        if (r.crashing || r.forceCrashReport) {
10614            report.type = ApplicationErrorReport.TYPE_CRASH;
10615            report.crashInfo = crashInfo;
10616        } else if (r.notResponding) {
10617            report.type = ApplicationErrorReport.TYPE_ANR;
10618            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10619
10620            report.anrInfo.activity = r.notRespondingReport.tag;
10621            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10622            report.anrInfo.info = r.notRespondingReport.longMsg;
10623        }
10624
10625        return report;
10626    }
10627
10628    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10629        enforceNotIsolatedCaller("getProcessesInErrorState");
10630        // assume our apps are happy - lazy create the list
10631        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10632
10633        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10634                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10635        int userId = UserHandle.getUserId(Binder.getCallingUid());
10636
10637        synchronized (this) {
10638
10639            // iterate across all processes
10640            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10641                ProcessRecord app = mLruProcesses.get(i);
10642                if (!allUsers && app.userId != userId) {
10643                    continue;
10644                }
10645                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10646                    // This one's in trouble, so we'll generate a report for it
10647                    // crashes are higher priority (in case there's a crash *and* an anr)
10648                    ActivityManager.ProcessErrorStateInfo report = null;
10649                    if (app.crashing) {
10650                        report = app.crashingReport;
10651                    } else if (app.notResponding) {
10652                        report = app.notRespondingReport;
10653                    }
10654
10655                    if (report != null) {
10656                        if (errList == null) {
10657                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10658                        }
10659                        errList.add(report);
10660                    } else {
10661                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10662                                " crashing = " + app.crashing +
10663                                " notResponding = " + app.notResponding);
10664                    }
10665                }
10666            }
10667        }
10668
10669        return errList;
10670    }
10671
10672    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10673        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10674            if (currApp != null) {
10675                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10676            }
10677            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10678        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10679            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10680        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10681            if (currApp != null) {
10682                currApp.lru = 0;
10683            }
10684            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10685        } else if (adj >= ProcessList.SERVICE_ADJ) {
10686            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10687        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10688            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10689        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10690            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10691        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10692            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10693        } else {
10694            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10695        }
10696    }
10697
10698    private void fillInProcMemInfo(ProcessRecord app,
10699            ActivityManager.RunningAppProcessInfo outInfo) {
10700        outInfo.pid = app.pid;
10701        outInfo.uid = app.info.uid;
10702        if (mHeavyWeightProcess == app) {
10703            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10704        }
10705        if (app.persistent) {
10706            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10707        }
10708        if (app.activities.size() > 0) {
10709            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10710        }
10711        outInfo.lastTrimLevel = app.trimMemoryLevel;
10712        int adj = app.curAdj;
10713        outInfo.importance = oomAdjToImportance(adj, outInfo);
10714        outInfo.importanceReasonCode = app.adjTypeCode;
10715        outInfo.processState = app.curProcState;
10716    }
10717
10718    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10719        enforceNotIsolatedCaller("getRunningAppProcesses");
10720        // Lazy instantiation of list
10721        List<ActivityManager.RunningAppProcessInfo> runList = null;
10722        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10723                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10724        int userId = UserHandle.getUserId(Binder.getCallingUid());
10725        synchronized (this) {
10726            // Iterate across all processes
10727            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10728                ProcessRecord app = mLruProcesses.get(i);
10729                if (!allUsers && app.userId != userId) {
10730                    continue;
10731                }
10732                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10733                    // Generate process state info for running application
10734                    ActivityManager.RunningAppProcessInfo currApp =
10735                        new ActivityManager.RunningAppProcessInfo(app.processName,
10736                                app.pid, app.getPackageList());
10737                    fillInProcMemInfo(app, currApp);
10738                    if (app.adjSource instanceof ProcessRecord) {
10739                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10740                        currApp.importanceReasonImportance = oomAdjToImportance(
10741                                app.adjSourceOom, null);
10742                    } else if (app.adjSource instanceof ActivityRecord) {
10743                        ActivityRecord r = (ActivityRecord)app.adjSource;
10744                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10745                    }
10746                    if (app.adjTarget instanceof ComponentName) {
10747                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10748                    }
10749                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10750                    //        + " lru=" + currApp.lru);
10751                    if (runList == null) {
10752                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10753                    }
10754                    runList.add(currApp);
10755                }
10756            }
10757        }
10758        return runList;
10759    }
10760
10761    public List<ApplicationInfo> getRunningExternalApplications() {
10762        enforceNotIsolatedCaller("getRunningExternalApplications");
10763        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10764        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10765        if (runningApps != null && runningApps.size() > 0) {
10766            Set<String> extList = new HashSet<String>();
10767            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10768                if (app.pkgList != null) {
10769                    for (String pkg : app.pkgList) {
10770                        extList.add(pkg);
10771                    }
10772                }
10773            }
10774            IPackageManager pm = AppGlobals.getPackageManager();
10775            for (String pkg : extList) {
10776                try {
10777                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10778                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10779                        retList.add(info);
10780                    }
10781                } catch (RemoteException e) {
10782                }
10783            }
10784        }
10785        return retList;
10786    }
10787
10788    @Override
10789    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10790        enforceNotIsolatedCaller("getMyMemoryState");
10791        synchronized (this) {
10792            ProcessRecord proc;
10793            synchronized (mPidsSelfLocked) {
10794                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10795            }
10796            fillInProcMemInfo(proc, outInfo);
10797        }
10798    }
10799
10800    @Override
10801    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10802        if (checkCallingPermission(android.Manifest.permission.DUMP)
10803                != PackageManager.PERMISSION_GRANTED) {
10804            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10805                    + Binder.getCallingPid()
10806                    + ", uid=" + Binder.getCallingUid()
10807                    + " without permission "
10808                    + android.Manifest.permission.DUMP);
10809            return;
10810        }
10811
10812        boolean dumpAll = false;
10813        boolean dumpClient = false;
10814        String dumpPackage = null;
10815
10816        int opti = 0;
10817        while (opti < args.length) {
10818            String opt = args[opti];
10819            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10820                break;
10821            }
10822            opti++;
10823            if ("-a".equals(opt)) {
10824                dumpAll = true;
10825            } else if ("-c".equals(opt)) {
10826                dumpClient = true;
10827            } else if ("-h".equals(opt)) {
10828                pw.println("Activity manager dump options:");
10829                pw.println("  [-a] [-c] [-h] [cmd] ...");
10830                pw.println("  cmd may be one of:");
10831                pw.println("    a[ctivities]: activity stack state");
10832                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10833                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10834                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10835                pw.println("    o[om]: out of memory management");
10836                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10837                pw.println("    provider [COMP_SPEC]: provider client-side state");
10838                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10839                pw.println("    service [COMP_SPEC]: service client-side state");
10840                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10841                pw.println("    all: dump all activities");
10842                pw.println("    top: dump the top activity");
10843                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10844                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10845                pw.println("    a partial substring in a component name, a");
10846                pw.println("    hex object identifier.");
10847                pw.println("  -a: include all available server state.");
10848                pw.println("  -c: include client state.");
10849                return;
10850            } else {
10851                pw.println("Unknown argument: " + opt + "; use -h for help");
10852            }
10853        }
10854
10855        long origId = Binder.clearCallingIdentity();
10856        boolean more = false;
10857        // Is the caller requesting to dump a particular piece of data?
10858        if (opti < args.length) {
10859            String cmd = args[opti];
10860            opti++;
10861            if ("activities".equals(cmd) || "a".equals(cmd)) {
10862                synchronized (this) {
10863                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10864                }
10865            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10866                String[] newArgs;
10867                String name;
10868                if (opti >= args.length) {
10869                    name = null;
10870                    newArgs = EMPTY_STRING_ARRAY;
10871                } else {
10872                    name = args[opti];
10873                    opti++;
10874                    newArgs = new String[args.length - opti];
10875                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10876                            args.length - opti);
10877                }
10878                synchronized (this) {
10879                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10880                }
10881            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10882                String[] newArgs;
10883                String name;
10884                if (opti >= args.length) {
10885                    name = null;
10886                    newArgs = EMPTY_STRING_ARRAY;
10887                } else {
10888                    name = args[opti];
10889                    opti++;
10890                    newArgs = new String[args.length - opti];
10891                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10892                            args.length - opti);
10893                }
10894                synchronized (this) {
10895                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10896                }
10897            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10898                String[] newArgs;
10899                String name;
10900                if (opti >= args.length) {
10901                    name = null;
10902                    newArgs = EMPTY_STRING_ARRAY;
10903                } else {
10904                    name = args[opti];
10905                    opti++;
10906                    newArgs = new String[args.length - opti];
10907                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10908                            args.length - opti);
10909                }
10910                synchronized (this) {
10911                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10912                }
10913            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10914                synchronized (this) {
10915                    dumpOomLocked(fd, pw, args, opti, true);
10916                }
10917            } else if ("provider".equals(cmd)) {
10918                String[] newArgs;
10919                String name;
10920                if (opti >= args.length) {
10921                    name = null;
10922                    newArgs = EMPTY_STRING_ARRAY;
10923                } else {
10924                    name = args[opti];
10925                    opti++;
10926                    newArgs = new String[args.length - opti];
10927                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10928                }
10929                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10930                    pw.println("No providers match: " + name);
10931                    pw.println("Use -h for help.");
10932                }
10933            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10934                synchronized (this) {
10935                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10936                }
10937            } else if ("service".equals(cmd)) {
10938                String[] newArgs;
10939                String name;
10940                if (opti >= args.length) {
10941                    name = null;
10942                    newArgs = EMPTY_STRING_ARRAY;
10943                } else {
10944                    name = args[opti];
10945                    opti++;
10946                    newArgs = new String[args.length - opti];
10947                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10948                            args.length - opti);
10949                }
10950                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10951                    pw.println("No services match: " + name);
10952                    pw.println("Use -h for help.");
10953                }
10954            } else if ("package".equals(cmd)) {
10955                String[] newArgs;
10956                if (opti >= args.length) {
10957                    pw.println("package: no package name specified");
10958                    pw.println("Use -h for help.");
10959                } else {
10960                    dumpPackage = args[opti];
10961                    opti++;
10962                    newArgs = new String[args.length - opti];
10963                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10964                            args.length - opti);
10965                    args = newArgs;
10966                    opti = 0;
10967                    more = true;
10968                }
10969            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10970                synchronized (this) {
10971                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10972                }
10973            } else {
10974                // Dumping a single activity?
10975                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10976                    pw.println("Bad activity command, or no activities match: " + cmd);
10977                    pw.println("Use -h for help.");
10978                }
10979            }
10980            if (!more) {
10981                Binder.restoreCallingIdentity(origId);
10982                return;
10983            }
10984        }
10985
10986        // No piece of data specified, dump everything.
10987        synchronized (this) {
10988            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10989            pw.println();
10990            if (dumpAll) {
10991                pw.println("-------------------------------------------------------------------------------");
10992            }
10993            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10994            pw.println();
10995            if (dumpAll) {
10996                pw.println("-------------------------------------------------------------------------------");
10997            }
10998            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10999            pw.println();
11000            if (dumpAll) {
11001                pw.println("-------------------------------------------------------------------------------");
11002            }
11003            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11004            pw.println();
11005            if (dumpAll) {
11006                pw.println("-------------------------------------------------------------------------------");
11007            }
11008            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11009            pw.println();
11010            if (dumpAll) {
11011                pw.println("-------------------------------------------------------------------------------");
11012            }
11013            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11014        }
11015        Binder.restoreCallingIdentity(origId);
11016    }
11017
11018    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11019            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11020        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11021
11022        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11023                dumpPackage);
11024        boolean needSep = printedAnything;
11025
11026        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11027                dumpPackage, needSep, "  mFocusedActivity: ");
11028        if (printed) {
11029            printedAnything = true;
11030            needSep = false;
11031        }
11032
11033        if (dumpPackage == null) {
11034            if (needSep) {
11035                pw.println();
11036            }
11037            needSep = true;
11038            printedAnything = true;
11039            mStackSupervisor.dump(pw, "  ");
11040        }
11041
11042        if (mRecentTasks.size() > 0) {
11043            boolean printedHeader = false;
11044
11045            final int N = mRecentTasks.size();
11046            for (int i=0; i<N; i++) {
11047                TaskRecord tr = mRecentTasks.get(i);
11048                if (dumpPackage != null) {
11049                    if (tr.realActivity == null ||
11050                            !dumpPackage.equals(tr.realActivity)) {
11051                        continue;
11052                    }
11053                }
11054                if (!printedHeader) {
11055                    if (needSep) {
11056                        pw.println();
11057                    }
11058                    pw.println("  Recent tasks:");
11059                    printedHeader = true;
11060                    printedAnything = true;
11061                }
11062                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11063                        pw.println(tr);
11064                if (dumpAll) {
11065                    mRecentTasks.get(i).dump(pw, "    ");
11066                }
11067            }
11068        }
11069
11070        if (!printedAnything) {
11071            pw.println("  (nothing)");
11072        }
11073    }
11074
11075    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11076            int opti, boolean dumpAll, String dumpPackage) {
11077        boolean needSep = false;
11078        boolean printedAnything = false;
11079        int numPers = 0;
11080
11081        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11082
11083        if (dumpAll) {
11084            final int NP = mProcessNames.getMap().size();
11085            for (int ip=0; ip<NP; ip++) {
11086                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11087                final int NA = procs.size();
11088                for (int ia=0; ia<NA; ia++) {
11089                    ProcessRecord r = procs.valueAt(ia);
11090                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11091                        continue;
11092                    }
11093                    if (!needSep) {
11094                        pw.println("  All known processes:");
11095                        needSep = true;
11096                        printedAnything = true;
11097                    }
11098                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11099                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11100                        pw.print(" "); pw.println(r);
11101                    r.dump(pw, "    ");
11102                    if (r.persistent) {
11103                        numPers++;
11104                    }
11105                }
11106            }
11107        }
11108
11109        if (mIsolatedProcesses.size() > 0) {
11110            boolean printed = false;
11111            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11112                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11113                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11114                    continue;
11115                }
11116                if (!printed) {
11117                    if (needSep) {
11118                        pw.println();
11119                    }
11120                    pw.println("  Isolated process list (sorted by uid):");
11121                    printedAnything = true;
11122                    printed = true;
11123                    needSep = true;
11124                }
11125                pw.println(String.format("%sIsolated #%2d: %s",
11126                        "    ", i, r.toString()));
11127            }
11128        }
11129
11130        if (mLruProcesses.size() > 0) {
11131            if (needSep) {
11132                pw.println();
11133            }
11134            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11135                    pw.print(" total, non-act at ");
11136                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11137                    pw.print(", non-svc at ");
11138                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11139                    pw.println("):");
11140            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11141            needSep = true;
11142            printedAnything = true;
11143        }
11144
11145        if (dumpAll || dumpPackage != null) {
11146            synchronized (mPidsSelfLocked) {
11147                boolean printed = false;
11148                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11149                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11150                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11151                        continue;
11152                    }
11153                    if (!printed) {
11154                        if (needSep) pw.println();
11155                        needSep = true;
11156                        pw.println("  PID mappings:");
11157                        printed = true;
11158                        printedAnything = true;
11159                    }
11160                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11161                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11162                }
11163            }
11164        }
11165
11166        if (mForegroundProcesses.size() > 0) {
11167            synchronized (mPidsSelfLocked) {
11168                boolean printed = false;
11169                for (int i=0; i<mForegroundProcesses.size(); i++) {
11170                    ProcessRecord r = mPidsSelfLocked.get(
11171                            mForegroundProcesses.valueAt(i).pid);
11172                    if (dumpPackage != null && (r == null
11173                            || !r.pkgList.containsKey(dumpPackage))) {
11174                        continue;
11175                    }
11176                    if (!printed) {
11177                        if (needSep) pw.println();
11178                        needSep = true;
11179                        pw.println("  Foreground Processes:");
11180                        printed = true;
11181                        printedAnything = true;
11182                    }
11183                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11184                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11185                }
11186            }
11187        }
11188
11189        if (mPersistentStartingProcesses.size() > 0) {
11190            if (needSep) pw.println();
11191            needSep = true;
11192            printedAnything = true;
11193            pw.println("  Persisent processes that are starting:");
11194            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11195                    "Starting Norm", "Restarting PERS", dumpPackage);
11196        }
11197
11198        if (mRemovedProcesses.size() > 0) {
11199            if (needSep) pw.println();
11200            needSep = true;
11201            printedAnything = true;
11202            pw.println("  Processes that are being removed:");
11203            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11204                    "Removed Norm", "Removed PERS", dumpPackage);
11205        }
11206
11207        if (mProcessesOnHold.size() > 0) {
11208            if (needSep) pw.println();
11209            needSep = true;
11210            printedAnything = true;
11211            pw.println("  Processes that are on old until the system is ready:");
11212            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11213                    "OnHold Norm", "OnHold PERS", dumpPackage);
11214        }
11215
11216        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11217
11218        if (mProcessCrashTimes.getMap().size() > 0) {
11219            boolean printed = false;
11220            long now = SystemClock.uptimeMillis();
11221            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11222            final int NP = pmap.size();
11223            for (int ip=0; ip<NP; ip++) {
11224                String pname = pmap.keyAt(ip);
11225                SparseArray<Long> uids = pmap.valueAt(ip);
11226                final int N = uids.size();
11227                for (int i=0; i<N; i++) {
11228                    int puid = uids.keyAt(i);
11229                    ProcessRecord r = mProcessNames.get(pname, puid);
11230                    if (dumpPackage != null && (r == null
11231                            || !r.pkgList.containsKey(dumpPackage))) {
11232                        continue;
11233                    }
11234                    if (!printed) {
11235                        if (needSep) pw.println();
11236                        needSep = true;
11237                        pw.println("  Time since processes crashed:");
11238                        printed = true;
11239                        printedAnything = true;
11240                    }
11241                    pw.print("    Process "); pw.print(pname);
11242                            pw.print(" uid "); pw.print(puid);
11243                            pw.print(": last crashed ");
11244                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11245                            pw.println(" ago");
11246                }
11247            }
11248        }
11249
11250        if (mBadProcesses.getMap().size() > 0) {
11251            boolean printed = false;
11252            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11253            final int NP = pmap.size();
11254            for (int ip=0; ip<NP; ip++) {
11255                String pname = pmap.keyAt(ip);
11256                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11257                final int N = uids.size();
11258                for (int i=0; i<N; i++) {
11259                    int puid = uids.keyAt(i);
11260                    ProcessRecord r = mProcessNames.get(pname, puid);
11261                    if (dumpPackage != null && (r == null
11262                            || !r.pkgList.containsKey(dumpPackage))) {
11263                        continue;
11264                    }
11265                    if (!printed) {
11266                        if (needSep) pw.println();
11267                        needSep = true;
11268                        pw.println("  Bad processes:");
11269                        printedAnything = true;
11270                    }
11271                    BadProcessInfo info = uids.valueAt(i);
11272                    pw.print("    Bad process "); pw.print(pname);
11273                            pw.print(" uid "); pw.print(puid);
11274                            pw.print(": crashed at time "); pw.println(info.time);
11275                    if (info.shortMsg != null) {
11276                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11277                    }
11278                    if (info.longMsg != null) {
11279                        pw.print("      Long msg: "); pw.println(info.longMsg);
11280                    }
11281                    if (info.stack != null) {
11282                        pw.println("      Stack:");
11283                        int lastPos = 0;
11284                        for (int pos=0; pos<info.stack.length(); pos++) {
11285                            if (info.stack.charAt(pos) == '\n') {
11286                                pw.print("        ");
11287                                pw.write(info.stack, lastPos, pos-lastPos);
11288                                pw.println();
11289                                lastPos = pos+1;
11290                            }
11291                        }
11292                        if (lastPos < info.stack.length()) {
11293                            pw.print("        ");
11294                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11295                            pw.println();
11296                        }
11297                    }
11298                }
11299            }
11300        }
11301
11302        if (dumpPackage == null) {
11303            pw.println();
11304            needSep = false;
11305            pw.println("  mStartedUsers:");
11306            for (int i=0; i<mStartedUsers.size(); i++) {
11307                UserStartedState uss = mStartedUsers.valueAt(i);
11308                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11309                        pw.print(": "); uss.dump("", pw);
11310            }
11311            pw.print("  mStartedUserArray: [");
11312            for (int i=0; i<mStartedUserArray.length; i++) {
11313                if (i > 0) pw.print(", ");
11314                pw.print(mStartedUserArray[i]);
11315            }
11316            pw.println("]");
11317            pw.print("  mUserLru: [");
11318            for (int i=0; i<mUserLru.size(); i++) {
11319                if (i > 0) pw.print(", ");
11320                pw.print(mUserLru.get(i));
11321            }
11322            pw.println("]");
11323            if (dumpAll) {
11324                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11325            }
11326        }
11327        if (mHomeProcess != null && (dumpPackage == null
11328                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11329            if (needSep) {
11330                pw.println();
11331                needSep = false;
11332            }
11333            pw.println("  mHomeProcess: " + mHomeProcess);
11334        }
11335        if (mPreviousProcess != null && (dumpPackage == null
11336                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11337            if (needSep) {
11338                pw.println();
11339                needSep = false;
11340            }
11341            pw.println("  mPreviousProcess: " + mPreviousProcess);
11342        }
11343        if (dumpAll) {
11344            StringBuilder sb = new StringBuilder(128);
11345            sb.append("  mPreviousProcessVisibleTime: ");
11346            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11347            pw.println(sb);
11348        }
11349        if (mHeavyWeightProcess != null && (dumpPackage == null
11350                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11351            if (needSep) {
11352                pw.println();
11353                needSep = false;
11354            }
11355            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11356        }
11357        if (dumpPackage == null) {
11358            pw.println("  mConfiguration: " + mConfiguration);
11359        }
11360        if (dumpAll) {
11361            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11362            if (mCompatModePackages.getPackages().size() > 0) {
11363                boolean printed = false;
11364                for (Map.Entry<String, Integer> entry
11365                        : mCompatModePackages.getPackages().entrySet()) {
11366                    String pkg = entry.getKey();
11367                    int mode = entry.getValue();
11368                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11369                        continue;
11370                    }
11371                    if (!printed) {
11372                        pw.println("  mScreenCompatPackages:");
11373                        printed = true;
11374                    }
11375                    pw.print("    "); pw.print(pkg); pw.print(": ");
11376                            pw.print(mode); pw.println();
11377                }
11378            }
11379        }
11380        if (dumpPackage == null) {
11381            if (mSleeping || mWentToSleep || mLockScreenShown) {
11382                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11383                        + " mLockScreenShown " + mLockScreenShown);
11384            }
11385            if (mShuttingDown || mRunningVoice) {
11386                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11387            }
11388        }
11389        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11390                || mOrigWaitForDebugger) {
11391            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11392                    || dumpPackage.equals(mOrigDebugApp)) {
11393                if (needSep) {
11394                    pw.println();
11395                    needSep = false;
11396                }
11397                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11398                        + " mDebugTransient=" + mDebugTransient
11399                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11400            }
11401        }
11402        if (mOpenGlTraceApp != null) {
11403            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11404                if (needSep) {
11405                    pw.println();
11406                    needSep = false;
11407                }
11408                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11409            }
11410        }
11411        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11412                || mProfileFd != null) {
11413            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11414                if (needSep) {
11415                    pw.println();
11416                    needSep = false;
11417                }
11418                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11419                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11420                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11421                        + mAutoStopProfiler);
11422            }
11423        }
11424        if (dumpPackage == null) {
11425            if (mAlwaysFinishActivities || mController != null) {
11426                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11427                        + " mController=" + mController);
11428            }
11429            if (dumpAll) {
11430                pw.println("  Total persistent processes: " + numPers);
11431                pw.println("  mProcessesReady=" + mProcessesReady
11432                        + " mSystemReady=" + mSystemReady);
11433                pw.println("  mBooting=" + mBooting
11434                        + " mBooted=" + mBooted
11435                        + " mFactoryTest=" + mFactoryTest);
11436                pw.print("  mLastPowerCheckRealtime=");
11437                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11438                        pw.println("");
11439                pw.print("  mLastPowerCheckUptime=");
11440                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11441                        pw.println("");
11442                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11443                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11444                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11445                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11446                        + " (" + mLruProcesses.size() + " total)"
11447                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11448                        + " mNumServiceProcs=" + mNumServiceProcs
11449                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11450                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11451                        + " mLastMemoryLevel" + mLastMemoryLevel
11452                        + " mLastNumProcesses" + mLastNumProcesses);
11453                long now = SystemClock.uptimeMillis();
11454                pw.print("  mLastIdleTime=");
11455                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11456                        pw.print(" mLowRamSinceLastIdle=");
11457                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11458                        pw.println();
11459            }
11460        }
11461
11462        if (!printedAnything) {
11463            pw.println("  (nothing)");
11464        }
11465    }
11466
11467    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11468            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11469        if (mProcessesToGc.size() > 0) {
11470            boolean printed = false;
11471            long now = SystemClock.uptimeMillis();
11472            for (int i=0; i<mProcessesToGc.size(); i++) {
11473                ProcessRecord proc = mProcessesToGc.get(i);
11474                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11475                    continue;
11476                }
11477                if (!printed) {
11478                    if (needSep) pw.println();
11479                    needSep = true;
11480                    pw.println("  Processes that are waiting to GC:");
11481                    printed = true;
11482                }
11483                pw.print("    Process "); pw.println(proc);
11484                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11485                        pw.print(", last gced=");
11486                        pw.print(now-proc.lastRequestedGc);
11487                        pw.print(" ms ago, last lowMem=");
11488                        pw.print(now-proc.lastLowMemory);
11489                        pw.println(" ms ago");
11490
11491            }
11492        }
11493        return needSep;
11494    }
11495
11496    void printOomLevel(PrintWriter pw, String name, int adj) {
11497        pw.print("    ");
11498        if (adj >= 0) {
11499            pw.print(' ');
11500            if (adj < 10) pw.print(' ');
11501        } else {
11502            if (adj > -10) pw.print(' ');
11503        }
11504        pw.print(adj);
11505        pw.print(": ");
11506        pw.print(name);
11507        pw.print(" (");
11508        pw.print(mProcessList.getMemLevel(adj)/1024);
11509        pw.println(" kB)");
11510    }
11511
11512    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11513            int opti, boolean dumpAll) {
11514        boolean needSep = false;
11515
11516        if (mLruProcesses.size() > 0) {
11517            if (needSep) pw.println();
11518            needSep = true;
11519            pw.println("  OOM levels:");
11520            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11521            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11522            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11523            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11524            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11525            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11526            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11527            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11528            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11529            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11530            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11531            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11532            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11533
11534            if (needSep) pw.println();
11535            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11536                    pw.print(" total, non-act at ");
11537                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11538                    pw.print(", non-svc at ");
11539                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11540                    pw.println("):");
11541            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11542            needSep = true;
11543        }
11544
11545        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11546
11547        pw.println();
11548        pw.println("  mHomeProcess: " + mHomeProcess);
11549        pw.println("  mPreviousProcess: " + mPreviousProcess);
11550        if (mHeavyWeightProcess != null) {
11551            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11552        }
11553
11554        return true;
11555    }
11556
11557    /**
11558     * There are three ways to call this:
11559     *  - no provider specified: dump all the providers
11560     *  - a flattened component name that matched an existing provider was specified as the
11561     *    first arg: dump that one provider
11562     *  - the first arg isn't the flattened component name of an existing provider:
11563     *    dump all providers whose component contains the first arg as a substring
11564     */
11565    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11566            int opti, boolean dumpAll) {
11567        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11568    }
11569
11570    static class ItemMatcher {
11571        ArrayList<ComponentName> components;
11572        ArrayList<String> strings;
11573        ArrayList<Integer> objects;
11574        boolean all;
11575
11576        ItemMatcher() {
11577            all = true;
11578        }
11579
11580        void build(String name) {
11581            ComponentName componentName = ComponentName.unflattenFromString(name);
11582            if (componentName != null) {
11583                if (components == null) {
11584                    components = new ArrayList<ComponentName>();
11585                }
11586                components.add(componentName);
11587                all = false;
11588            } else {
11589                int objectId = 0;
11590                // Not a '/' separated full component name; maybe an object ID?
11591                try {
11592                    objectId = Integer.parseInt(name, 16);
11593                    if (objects == null) {
11594                        objects = new ArrayList<Integer>();
11595                    }
11596                    objects.add(objectId);
11597                    all = false;
11598                } catch (RuntimeException e) {
11599                    // Not an integer; just do string match.
11600                    if (strings == null) {
11601                        strings = new ArrayList<String>();
11602                    }
11603                    strings.add(name);
11604                    all = false;
11605                }
11606            }
11607        }
11608
11609        int build(String[] args, int opti) {
11610            for (; opti<args.length; opti++) {
11611                String name = args[opti];
11612                if ("--".equals(name)) {
11613                    return opti+1;
11614                }
11615                build(name);
11616            }
11617            return opti;
11618        }
11619
11620        boolean match(Object object, ComponentName comp) {
11621            if (all) {
11622                return true;
11623            }
11624            if (components != null) {
11625                for (int i=0; i<components.size(); i++) {
11626                    if (components.get(i).equals(comp)) {
11627                        return true;
11628                    }
11629                }
11630            }
11631            if (objects != null) {
11632                for (int i=0; i<objects.size(); i++) {
11633                    if (System.identityHashCode(object) == objects.get(i)) {
11634                        return true;
11635                    }
11636                }
11637            }
11638            if (strings != null) {
11639                String flat = comp.flattenToString();
11640                for (int i=0; i<strings.size(); i++) {
11641                    if (flat.contains(strings.get(i))) {
11642                        return true;
11643                    }
11644                }
11645            }
11646            return false;
11647        }
11648    }
11649
11650    /**
11651     * There are three things that cmd can be:
11652     *  - a flattened component name that matches an existing activity
11653     *  - the cmd arg isn't the flattened component name of an existing activity:
11654     *    dump all activity whose component contains the cmd as a substring
11655     *  - A hex number of the ActivityRecord object instance.
11656     */
11657    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11658            int opti, boolean dumpAll) {
11659        ArrayList<ActivityRecord> activities;
11660
11661        synchronized (this) {
11662            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11663        }
11664
11665        if (activities.size() <= 0) {
11666            return false;
11667        }
11668
11669        String[] newArgs = new String[args.length - opti];
11670        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11671
11672        TaskRecord lastTask = null;
11673        boolean needSep = false;
11674        for (int i=activities.size()-1; i>=0; i--) {
11675            ActivityRecord r = activities.get(i);
11676            if (needSep) {
11677                pw.println();
11678            }
11679            needSep = true;
11680            synchronized (this) {
11681                if (lastTask != r.task) {
11682                    lastTask = r.task;
11683                    pw.print("TASK "); pw.print(lastTask.affinity);
11684                            pw.print(" id="); pw.println(lastTask.taskId);
11685                    if (dumpAll) {
11686                        lastTask.dump(pw, "  ");
11687                    }
11688                }
11689            }
11690            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11691        }
11692        return true;
11693    }
11694
11695    /**
11696     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11697     * there is a thread associated with the activity.
11698     */
11699    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11700            final ActivityRecord r, String[] args, boolean dumpAll) {
11701        String innerPrefix = prefix + "  ";
11702        synchronized (this) {
11703            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11704                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11705                    pw.print(" pid=");
11706                    if (r.app != null) pw.println(r.app.pid);
11707                    else pw.println("(not running)");
11708            if (dumpAll) {
11709                r.dump(pw, innerPrefix);
11710            }
11711        }
11712        if (r.app != null && r.app.thread != null) {
11713            // flush anything that is already in the PrintWriter since the thread is going
11714            // to write to the file descriptor directly
11715            pw.flush();
11716            try {
11717                TransferPipe tp = new TransferPipe();
11718                try {
11719                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11720                            r.appToken, innerPrefix, args);
11721                    tp.go(fd);
11722                } finally {
11723                    tp.kill();
11724                }
11725            } catch (IOException e) {
11726                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11727            } catch (RemoteException e) {
11728                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11729            }
11730        }
11731    }
11732
11733    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11734            int opti, boolean dumpAll, String dumpPackage) {
11735        boolean needSep = false;
11736        boolean onlyHistory = false;
11737        boolean printedAnything = false;
11738
11739        if ("history".equals(dumpPackage)) {
11740            if (opti < args.length && "-s".equals(args[opti])) {
11741                dumpAll = false;
11742            }
11743            onlyHistory = true;
11744            dumpPackage = null;
11745        }
11746
11747        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11748        if (!onlyHistory && dumpAll) {
11749            if (mRegisteredReceivers.size() > 0) {
11750                boolean printed = false;
11751                Iterator it = mRegisteredReceivers.values().iterator();
11752                while (it.hasNext()) {
11753                    ReceiverList r = (ReceiverList)it.next();
11754                    if (dumpPackage != null && (r.app == null ||
11755                            !dumpPackage.equals(r.app.info.packageName))) {
11756                        continue;
11757                    }
11758                    if (!printed) {
11759                        pw.println("  Registered Receivers:");
11760                        needSep = true;
11761                        printed = true;
11762                        printedAnything = true;
11763                    }
11764                    pw.print("  * "); pw.println(r);
11765                    r.dump(pw, "    ");
11766                }
11767            }
11768
11769            if (mReceiverResolver.dump(pw, needSep ?
11770                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11771                    "    ", dumpPackage, false)) {
11772                needSep = true;
11773                printedAnything = true;
11774            }
11775        }
11776
11777        for (BroadcastQueue q : mBroadcastQueues) {
11778            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11779            printedAnything |= needSep;
11780        }
11781
11782        needSep = true;
11783
11784        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11785            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11786                if (needSep) {
11787                    pw.println();
11788                }
11789                needSep = true;
11790                printedAnything = true;
11791                pw.print("  Sticky broadcasts for user ");
11792                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11793                StringBuilder sb = new StringBuilder(128);
11794                for (Map.Entry<String, ArrayList<Intent>> ent
11795                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11796                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11797                    if (dumpAll) {
11798                        pw.println(":");
11799                        ArrayList<Intent> intents = ent.getValue();
11800                        final int N = intents.size();
11801                        for (int i=0; i<N; i++) {
11802                            sb.setLength(0);
11803                            sb.append("    Intent: ");
11804                            intents.get(i).toShortString(sb, false, true, false, false);
11805                            pw.println(sb.toString());
11806                            Bundle bundle = intents.get(i).getExtras();
11807                            if (bundle != null) {
11808                                pw.print("      ");
11809                                pw.println(bundle.toString());
11810                            }
11811                        }
11812                    } else {
11813                        pw.println("");
11814                    }
11815                }
11816            }
11817        }
11818
11819        if (!onlyHistory && dumpAll) {
11820            pw.println();
11821            for (BroadcastQueue queue : mBroadcastQueues) {
11822                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11823                        + queue.mBroadcastsScheduled);
11824            }
11825            pw.println("  mHandler:");
11826            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11827            needSep = true;
11828            printedAnything = true;
11829        }
11830
11831        if (!printedAnything) {
11832            pw.println("  (nothing)");
11833        }
11834    }
11835
11836    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11837            int opti, boolean dumpAll, String dumpPackage) {
11838        boolean needSep;
11839        boolean printedAnything = false;
11840
11841        ItemMatcher matcher = new ItemMatcher();
11842        matcher.build(args, opti);
11843
11844        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11845
11846        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11847        printedAnything |= needSep;
11848
11849        if (mLaunchingProviders.size() > 0) {
11850            boolean printed = false;
11851            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11852                ContentProviderRecord r = mLaunchingProviders.get(i);
11853                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11854                    continue;
11855                }
11856                if (!printed) {
11857                    if (needSep) pw.println();
11858                    needSep = true;
11859                    pw.println("  Launching content providers:");
11860                    printed = true;
11861                    printedAnything = true;
11862                }
11863                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11864                        pw.println(r);
11865            }
11866        }
11867
11868        if (mGrantedUriPermissions.size() > 0) {
11869            boolean printed = false;
11870            int dumpUid = -2;
11871            if (dumpPackage != null) {
11872                try {
11873                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11874                } catch (NameNotFoundException e) {
11875                    dumpUid = -1;
11876                }
11877            }
11878            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11879                int uid = mGrantedUriPermissions.keyAt(i);
11880                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11881                    continue;
11882                }
11883                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11884                if (!printed) {
11885                    if (needSep) pw.println();
11886                    needSep = true;
11887                    pw.println("  Granted Uri Permissions:");
11888                    printed = true;
11889                    printedAnything = true;
11890                }
11891                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11892                for (UriPermission perm : perms.values()) {
11893                    pw.print("    "); pw.println(perm);
11894                    if (dumpAll) {
11895                        perm.dump(pw, "      ");
11896                    }
11897                }
11898            }
11899        }
11900
11901        if (!printedAnything) {
11902            pw.println("  (nothing)");
11903        }
11904    }
11905
11906    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11907            int opti, boolean dumpAll, String dumpPackage) {
11908        boolean printed = false;
11909
11910        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11911
11912        if (mIntentSenderRecords.size() > 0) {
11913            Iterator<WeakReference<PendingIntentRecord>> it
11914                    = mIntentSenderRecords.values().iterator();
11915            while (it.hasNext()) {
11916                WeakReference<PendingIntentRecord> ref = it.next();
11917                PendingIntentRecord rec = ref != null ? ref.get(): null;
11918                if (dumpPackage != null && (rec == null
11919                        || !dumpPackage.equals(rec.key.packageName))) {
11920                    continue;
11921                }
11922                printed = true;
11923                if (rec != null) {
11924                    pw.print("  * "); pw.println(rec);
11925                    if (dumpAll) {
11926                        rec.dump(pw, "    ");
11927                    }
11928                } else {
11929                    pw.print("  * "); pw.println(ref);
11930                }
11931            }
11932        }
11933
11934        if (!printed) {
11935            pw.println("  (nothing)");
11936        }
11937    }
11938
11939    private static final int dumpProcessList(PrintWriter pw,
11940            ActivityManagerService service, List list,
11941            String prefix, String normalLabel, String persistentLabel,
11942            String dumpPackage) {
11943        int numPers = 0;
11944        final int N = list.size()-1;
11945        for (int i=N; i>=0; i--) {
11946            ProcessRecord r = (ProcessRecord)list.get(i);
11947            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11948                continue;
11949            }
11950            pw.println(String.format("%s%s #%2d: %s",
11951                    prefix, (r.persistent ? persistentLabel : normalLabel),
11952                    i, r.toString()));
11953            if (r.persistent) {
11954                numPers++;
11955            }
11956        }
11957        return numPers;
11958    }
11959
11960    private static final boolean dumpProcessOomList(PrintWriter pw,
11961            ActivityManagerService service, List<ProcessRecord> origList,
11962            String prefix, String normalLabel, String persistentLabel,
11963            boolean inclDetails, String dumpPackage) {
11964
11965        ArrayList<Pair<ProcessRecord, Integer>> list
11966                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11967        for (int i=0; i<origList.size(); i++) {
11968            ProcessRecord r = origList.get(i);
11969            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11970                continue;
11971            }
11972            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11973        }
11974
11975        if (list.size() <= 0) {
11976            return false;
11977        }
11978
11979        Comparator<Pair<ProcessRecord, Integer>> comparator
11980                = new Comparator<Pair<ProcessRecord, Integer>>() {
11981            @Override
11982            public int compare(Pair<ProcessRecord, Integer> object1,
11983                    Pair<ProcessRecord, Integer> object2) {
11984                if (object1.first.setAdj != object2.first.setAdj) {
11985                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11986                }
11987                if (object1.second.intValue() != object2.second.intValue()) {
11988                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11989                }
11990                return 0;
11991            }
11992        };
11993
11994        Collections.sort(list, comparator);
11995
11996        final long curRealtime = SystemClock.elapsedRealtime();
11997        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11998        final long curUptime = SystemClock.uptimeMillis();
11999        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12000
12001        for (int i=list.size()-1; i>=0; i--) {
12002            ProcessRecord r = list.get(i).first;
12003            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12004            char schedGroup;
12005            switch (r.setSchedGroup) {
12006                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12007                    schedGroup = 'B';
12008                    break;
12009                case Process.THREAD_GROUP_DEFAULT:
12010                    schedGroup = 'F';
12011                    break;
12012                default:
12013                    schedGroup = '?';
12014                    break;
12015            }
12016            char foreground;
12017            if (r.foregroundActivities) {
12018                foreground = 'A';
12019            } else if (r.foregroundServices) {
12020                foreground = 'S';
12021            } else {
12022                foreground = ' ';
12023            }
12024            String procState = ProcessList.makeProcStateString(r.curProcState);
12025            pw.print(prefix);
12026            pw.print(r.persistent ? persistentLabel : normalLabel);
12027            pw.print(" #");
12028            int num = (origList.size()-1)-list.get(i).second;
12029            if (num < 10) pw.print(' ');
12030            pw.print(num);
12031            pw.print(": ");
12032            pw.print(oomAdj);
12033            pw.print(' ');
12034            pw.print(schedGroup);
12035            pw.print('/');
12036            pw.print(foreground);
12037            pw.print('/');
12038            pw.print(procState);
12039            pw.print(" trm:");
12040            if (r.trimMemoryLevel < 10) pw.print(' ');
12041            pw.print(r.trimMemoryLevel);
12042            pw.print(' ');
12043            pw.print(r.toShortString());
12044            pw.print(" (");
12045            pw.print(r.adjType);
12046            pw.println(')');
12047            if (r.adjSource != null || r.adjTarget != null) {
12048                pw.print(prefix);
12049                pw.print("    ");
12050                if (r.adjTarget instanceof ComponentName) {
12051                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12052                } else if (r.adjTarget != null) {
12053                    pw.print(r.adjTarget.toString());
12054                } else {
12055                    pw.print("{null}");
12056                }
12057                pw.print("<=");
12058                if (r.adjSource instanceof ProcessRecord) {
12059                    pw.print("Proc{");
12060                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12061                    pw.println("}");
12062                } else if (r.adjSource != null) {
12063                    pw.println(r.adjSource.toString());
12064                } else {
12065                    pw.println("{null}");
12066                }
12067            }
12068            if (inclDetails) {
12069                pw.print(prefix);
12070                pw.print("    ");
12071                pw.print("oom: max="); pw.print(r.maxAdj);
12072                pw.print(" curRaw="); pw.print(r.curRawAdj);
12073                pw.print(" setRaw="); pw.print(r.setRawAdj);
12074                pw.print(" cur="); pw.print(r.curAdj);
12075                pw.print(" set="); pw.println(r.setAdj);
12076                pw.print(prefix);
12077                pw.print("    ");
12078                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12079                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12080                pw.print(" lastPss="); pw.print(r.lastPss);
12081                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12082                pw.print(prefix);
12083                pw.print("    ");
12084                pw.print("keeping="); pw.print(r.keeping);
12085                pw.print(" cached="); pw.print(r.cached);
12086                pw.print(" empty="); pw.print(r.empty);
12087                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12088
12089                if (!r.keeping) {
12090                    if (r.lastWakeTime != 0) {
12091                        long wtime;
12092                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12093                        synchronized (stats) {
12094                            wtime = stats.getProcessWakeTime(r.info.uid,
12095                                    r.pid, curRealtime);
12096                        }
12097                        long timeUsed = wtime - r.lastWakeTime;
12098                        pw.print(prefix);
12099                        pw.print("    ");
12100                        pw.print("keep awake over ");
12101                        TimeUtils.formatDuration(realtimeSince, pw);
12102                        pw.print(" used ");
12103                        TimeUtils.formatDuration(timeUsed, pw);
12104                        pw.print(" (");
12105                        pw.print((timeUsed*100)/realtimeSince);
12106                        pw.println("%)");
12107                    }
12108                    if (r.lastCpuTime != 0) {
12109                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12110                        pw.print(prefix);
12111                        pw.print("    ");
12112                        pw.print("run cpu over ");
12113                        TimeUtils.formatDuration(uptimeSince, pw);
12114                        pw.print(" used ");
12115                        TimeUtils.formatDuration(timeUsed, pw);
12116                        pw.print(" (");
12117                        pw.print((timeUsed*100)/uptimeSince);
12118                        pw.println("%)");
12119                    }
12120                }
12121            }
12122        }
12123        return true;
12124    }
12125
12126    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12127        ArrayList<ProcessRecord> procs;
12128        synchronized (this) {
12129            if (args != null && args.length > start
12130                    && args[start].charAt(0) != '-') {
12131                procs = new ArrayList<ProcessRecord>();
12132                int pid = -1;
12133                try {
12134                    pid = Integer.parseInt(args[start]);
12135                } catch (NumberFormatException e) {
12136                }
12137                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12138                    ProcessRecord proc = mLruProcesses.get(i);
12139                    if (proc.pid == pid) {
12140                        procs.add(proc);
12141                    } else if (proc.processName.equals(args[start])) {
12142                        procs.add(proc);
12143                    }
12144                }
12145                if (procs.size() <= 0) {
12146                    return null;
12147                }
12148            } else {
12149                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12150            }
12151        }
12152        return procs;
12153    }
12154
12155    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12156            PrintWriter pw, String[] args) {
12157        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12158        if (procs == null) {
12159            pw.println("No process found for: " + args[0]);
12160            return;
12161        }
12162
12163        long uptime = SystemClock.uptimeMillis();
12164        long realtime = SystemClock.elapsedRealtime();
12165        pw.println("Applications Graphics Acceleration Info:");
12166        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12167
12168        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12169            ProcessRecord r = procs.get(i);
12170            if (r.thread != null) {
12171                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12172                pw.flush();
12173                try {
12174                    TransferPipe tp = new TransferPipe();
12175                    try {
12176                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12177                        tp.go(fd);
12178                    } finally {
12179                        tp.kill();
12180                    }
12181                } catch (IOException e) {
12182                    pw.println("Failure while dumping the app: " + r);
12183                    pw.flush();
12184                } catch (RemoteException e) {
12185                    pw.println("Got a RemoteException while dumping the app " + r);
12186                    pw.flush();
12187                }
12188            }
12189        }
12190    }
12191
12192    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12193        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12194        if (procs == null) {
12195            pw.println("No process found for: " + args[0]);
12196            return;
12197        }
12198
12199        pw.println("Applications Database Info:");
12200
12201        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12202            ProcessRecord r = procs.get(i);
12203            if (r.thread != null) {
12204                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12205                pw.flush();
12206                try {
12207                    TransferPipe tp = new TransferPipe();
12208                    try {
12209                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12210                        tp.go(fd);
12211                    } finally {
12212                        tp.kill();
12213                    }
12214                } catch (IOException e) {
12215                    pw.println("Failure while dumping the app: " + r);
12216                    pw.flush();
12217                } catch (RemoteException e) {
12218                    pw.println("Got a RemoteException while dumping the app " + r);
12219                    pw.flush();
12220                }
12221            }
12222        }
12223    }
12224
12225    final static class MemItem {
12226        final boolean isProc;
12227        final String label;
12228        final String shortLabel;
12229        final long pss;
12230        final int id;
12231        final boolean hasActivities;
12232        ArrayList<MemItem> subitems;
12233
12234        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12235                boolean _hasActivities) {
12236            isProc = true;
12237            label = _label;
12238            shortLabel = _shortLabel;
12239            pss = _pss;
12240            id = _id;
12241            hasActivities = _hasActivities;
12242        }
12243
12244        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12245            isProc = false;
12246            label = _label;
12247            shortLabel = _shortLabel;
12248            pss = _pss;
12249            id = _id;
12250            hasActivities = false;
12251        }
12252    }
12253
12254    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12255            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12256        if (sort && !isCompact) {
12257            Collections.sort(items, new Comparator<MemItem>() {
12258                @Override
12259                public int compare(MemItem lhs, MemItem rhs) {
12260                    if (lhs.pss < rhs.pss) {
12261                        return 1;
12262                    } else if (lhs.pss > rhs.pss) {
12263                        return -1;
12264                    }
12265                    return 0;
12266                }
12267            });
12268        }
12269
12270        for (int i=0; i<items.size(); i++) {
12271            MemItem mi = items.get(i);
12272            if (!isCompact) {
12273                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12274            } else if (mi.isProc) {
12275                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12276                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12277                pw.println(mi.hasActivities ? ",a" : ",e");
12278            } else {
12279                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12280                pw.println(mi.pss);
12281            }
12282            if (mi.subitems != null) {
12283                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12284                        true, isCompact);
12285            }
12286        }
12287    }
12288
12289    // These are in KB.
12290    static final long[] DUMP_MEM_BUCKETS = new long[] {
12291        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12292        120*1024, 160*1024, 200*1024,
12293        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12294        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12295    };
12296
12297    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12298            boolean stackLike) {
12299        int start = label.lastIndexOf('.');
12300        if (start >= 0) start++;
12301        else start = 0;
12302        int end = label.length();
12303        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12304            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12305                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12306                out.append(bucket);
12307                out.append(stackLike ? "MB." : "MB ");
12308                out.append(label, start, end);
12309                return;
12310            }
12311        }
12312        out.append(memKB/1024);
12313        out.append(stackLike ? "MB." : "MB ");
12314        out.append(label, start, end);
12315    }
12316
12317    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12318            ProcessList.NATIVE_ADJ,
12319            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12320            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12321            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12322            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12323            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12324    };
12325    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12326            "Native",
12327            "System", "Persistent", "Foreground",
12328            "Visible", "Perceptible",
12329            "Heavy Weight", "Backup",
12330            "A Services", "Home",
12331            "Previous", "B Services", "Cached"
12332    };
12333    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12334            "native",
12335            "sys", "pers", "fore",
12336            "vis", "percept",
12337            "heavy", "backup",
12338            "servicea", "home",
12339            "prev", "serviceb", "cached"
12340    };
12341
12342    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12343            long realtime, boolean isCheckinRequest, boolean isCompact) {
12344        if (isCheckinRequest || isCompact) {
12345            // short checkin version
12346            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12347        } else {
12348            pw.println("Applications Memory Usage (kB):");
12349            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12350        }
12351    }
12352
12353    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12354            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12355        boolean dumpDetails = false;
12356        boolean dumpFullDetails = false;
12357        boolean dumpDalvik = false;
12358        boolean oomOnly = false;
12359        boolean isCompact = false;
12360        boolean localOnly = false;
12361
12362        int opti = 0;
12363        while (opti < args.length) {
12364            String opt = args[opti];
12365            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12366                break;
12367            }
12368            opti++;
12369            if ("-a".equals(opt)) {
12370                dumpDetails = true;
12371                dumpFullDetails = true;
12372                dumpDalvik = true;
12373            } else if ("-d".equals(opt)) {
12374                dumpDalvik = true;
12375            } else if ("-c".equals(opt)) {
12376                isCompact = true;
12377            } else if ("--oom".equals(opt)) {
12378                oomOnly = true;
12379            } else if ("--local".equals(opt)) {
12380                localOnly = true;
12381            } else if ("-h".equals(opt)) {
12382                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12383                pw.println("  -a: include all available information for each process.");
12384                pw.println("  -d: include dalvik details when dumping process details.");
12385                pw.println("  -c: dump in a compact machine-parseable representation.");
12386                pw.println("  --oom: only show processes organized by oom adj.");
12387                pw.println("  --local: only collect details locally, don't call process.");
12388                pw.println("If [process] is specified it can be the name or ");
12389                pw.println("pid of a specific process to dump.");
12390                return;
12391            } else {
12392                pw.println("Unknown argument: " + opt + "; use -h for help");
12393            }
12394        }
12395
12396        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12397        long uptime = SystemClock.uptimeMillis();
12398        long realtime = SystemClock.elapsedRealtime();
12399        final long[] tmpLong = new long[1];
12400
12401        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12402        if (procs == null) {
12403            // No Java processes.  Maybe they want to print a native process.
12404            if (args != null && args.length > opti
12405                    && args[opti].charAt(0) != '-') {
12406                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12407                        = new ArrayList<ProcessCpuTracker.Stats>();
12408                updateCpuStatsNow();
12409                int findPid = -1;
12410                try {
12411                    findPid = Integer.parseInt(args[opti]);
12412                } catch (NumberFormatException e) {
12413                }
12414                synchronized (mProcessCpuThread) {
12415                    final int N = mProcessCpuTracker.countStats();
12416                    for (int i=0; i<N; i++) {
12417                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12418                        if (st.pid == findPid || (st.baseName != null
12419                                && st.baseName.equals(args[opti]))) {
12420                            nativeProcs.add(st);
12421                        }
12422                    }
12423                }
12424                if (nativeProcs.size() > 0) {
12425                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12426                            isCompact);
12427                    Debug.MemoryInfo mi = null;
12428                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12429                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12430                        final int pid = r.pid;
12431                        if (!isCheckinRequest && dumpDetails) {
12432                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12433                        }
12434                        if (mi == null) {
12435                            mi = new Debug.MemoryInfo();
12436                        }
12437                        if (dumpDetails || (!brief && !oomOnly)) {
12438                            Debug.getMemoryInfo(pid, mi);
12439                        } else {
12440                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12441                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12442                        }
12443                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12444                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12445                        if (isCheckinRequest) {
12446                            pw.println();
12447                        }
12448                    }
12449                    return;
12450                }
12451            }
12452            pw.println("No process found for: " + args[opti]);
12453            return;
12454        }
12455
12456        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12457            dumpDetails = true;
12458        }
12459
12460        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12461
12462        String[] innerArgs = new String[args.length-opti];
12463        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12464
12465        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12466        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12467        long nativePss=0, dalvikPss=0, otherPss=0;
12468        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12469
12470        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12471        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12472                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12473
12474        long totalPss = 0;
12475        long cachedPss = 0;
12476
12477        Debug.MemoryInfo mi = null;
12478        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12479            final ProcessRecord r = procs.get(i);
12480            final IApplicationThread thread;
12481            final int pid;
12482            final int oomAdj;
12483            final boolean hasActivities;
12484            synchronized (this) {
12485                thread = r.thread;
12486                pid = r.pid;
12487                oomAdj = r.getSetAdjWithServices();
12488                hasActivities = r.activities.size() > 0;
12489            }
12490            if (thread != null) {
12491                if (!isCheckinRequest && dumpDetails) {
12492                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12493                }
12494                if (mi == null) {
12495                    mi = new Debug.MemoryInfo();
12496                }
12497                if (dumpDetails || (!brief && !oomOnly)) {
12498                    Debug.getMemoryInfo(pid, mi);
12499                } else {
12500                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12501                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12502                }
12503                if (dumpDetails) {
12504                    if (localOnly) {
12505                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12506                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12507                        if (isCheckinRequest) {
12508                            pw.println();
12509                        }
12510                    } else {
12511                        try {
12512                            pw.flush();
12513                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12514                                    dumpDalvik, innerArgs);
12515                        } catch (RemoteException e) {
12516                            if (!isCheckinRequest) {
12517                                pw.println("Got RemoteException!");
12518                                pw.flush();
12519                            }
12520                        }
12521                    }
12522                }
12523
12524                final long myTotalPss = mi.getTotalPss();
12525                final long myTotalUss = mi.getTotalUss();
12526
12527                synchronized (this) {
12528                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12529                        // Record this for posterity if the process has been stable.
12530                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12531                    }
12532                }
12533
12534                if (!isCheckinRequest && mi != null) {
12535                    totalPss += myTotalPss;
12536                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12537                            (hasActivities ? " / activities)" : ")"),
12538                            r.processName, myTotalPss, pid, hasActivities);
12539                    procMems.add(pssItem);
12540                    procMemsMap.put(pid, pssItem);
12541
12542                    nativePss += mi.nativePss;
12543                    dalvikPss += mi.dalvikPss;
12544                    otherPss += mi.otherPss;
12545                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12546                        long mem = mi.getOtherPss(j);
12547                        miscPss[j] += mem;
12548                        otherPss -= mem;
12549                    }
12550
12551                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12552                        cachedPss += myTotalPss;
12553                    }
12554
12555                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12556                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12557                                || oomIndex == (oomPss.length-1)) {
12558                            oomPss[oomIndex] += myTotalPss;
12559                            if (oomProcs[oomIndex] == null) {
12560                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12561                            }
12562                            oomProcs[oomIndex].add(pssItem);
12563                            break;
12564                        }
12565                    }
12566                }
12567            }
12568        }
12569
12570        if (!isCheckinRequest && procs.size() > 1) {
12571            // If we are showing aggregations, also look for native processes to
12572            // include so that our aggregations are more accurate.
12573            updateCpuStatsNow();
12574            synchronized (mProcessCpuThread) {
12575                final int N = mProcessCpuTracker.countStats();
12576                for (int i=0; i<N; i++) {
12577                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12578                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12579                        if (mi == null) {
12580                            mi = new Debug.MemoryInfo();
12581                        }
12582                        if (!brief && !oomOnly) {
12583                            Debug.getMemoryInfo(st.pid, mi);
12584                        } else {
12585                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12586                            mi.nativePrivateDirty = (int)tmpLong[0];
12587                        }
12588
12589                        final long myTotalPss = mi.getTotalPss();
12590                        totalPss += myTotalPss;
12591
12592                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12593                                st.name, myTotalPss, st.pid, false);
12594                        procMems.add(pssItem);
12595
12596                        nativePss += mi.nativePss;
12597                        dalvikPss += mi.dalvikPss;
12598                        otherPss += mi.otherPss;
12599                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12600                            long mem = mi.getOtherPss(j);
12601                            miscPss[j] += mem;
12602                            otherPss -= mem;
12603                        }
12604                        oomPss[0] += myTotalPss;
12605                        if (oomProcs[0] == null) {
12606                            oomProcs[0] = new ArrayList<MemItem>();
12607                        }
12608                        oomProcs[0].add(pssItem);
12609                    }
12610                }
12611            }
12612
12613            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12614
12615            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12616            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12617            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12618            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12619                String label = Debug.MemoryInfo.getOtherLabel(j);
12620                catMems.add(new MemItem(label, label, miscPss[j], j));
12621            }
12622
12623            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12624            for (int j=0; j<oomPss.length; j++) {
12625                if (oomPss[j] != 0) {
12626                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12627                            : DUMP_MEM_OOM_LABEL[j];
12628                    MemItem item = new MemItem(label, label, oomPss[j],
12629                            DUMP_MEM_OOM_ADJ[j]);
12630                    item.subitems = oomProcs[j];
12631                    oomMems.add(item);
12632                }
12633            }
12634
12635            if (!brief && !oomOnly && !isCompact) {
12636                pw.println();
12637                pw.println("Total PSS by process:");
12638                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12639                pw.println();
12640            }
12641            if (!isCompact) {
12642                pw.println("Total PSS by OOM adjustment:");
12643            }
12644            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12645            if (!brief && !oomOnly) {
12646                PrintWriter out = categoryPw != null ? categoryPw : pw;
12647                if (!isCompact) {
12648                    out.println();
12649                    out.println("Total PSS by category:");
12650                }
12651                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12652            }
12653            if (!isCompact) {
12654                pw.println();
12655            }
12656            MemInfoReader memInfo = new MemInfoReader();
12657            memInfo.readMemInfo();
12658            if (!brief) {
12659                if (!isCompact) {
12660                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12661                    pw.print(" kB (status ");
12662                    switch (mLastMemoryLevel) {
12663                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12664                            pw.println("normal)");
12665                            break;
12666                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12667                            pw.println("moderate)");
12668                            break;
12669                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12670                            pw.println("low)");
12671                            break;
12672                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12673                            pw.println("critical)");
12674                            break;
12675                        default:
12676                            pw.print(mLastMemoryLevel);
12677                            pw.println(")");
12678                            break;
12679                    }
12680                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12681                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12682                            pw.print(cachedPss); pw.print(" cached pss + ");
12683                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12684                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12685                } else {
12686                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12687                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12688                            + memInfo.getFreeSizeKb()); pw.print(",");
12689                    pw.println(totalPss - cachedPss);
12690                }
12691            }
12692            if (!isCompact) {
12693                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12694                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12695                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12696                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12697                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12698                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12699                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12700                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12701                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12702                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12703                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12704            }
12705            if (!brief) {
12706                if (memInfo.getZramTotalSizeKb() != 0) {
12707                    if (!isCompact) {
12708                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12709                                pw.print(" kB physical used for ");
12710                                pw.print(memInfo.getSwapTotalSizeKb()
12711                                        - memInfo.getSwapFreeSizeKb());
12712                                pw.print(" kB in swap (");
12713                                pw.print(memInfo.getSwapTotalSizeKb());
12714                                pw.println(" kB total swap)");
12715                    } else {
12716                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12717                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12718                                pw.println(memInfo.getSwapFreeSizeKb());
12719                    }
12720                }
12721                final int[] SINGLE_LONG_FORMAT = new int[] {
12722                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12723                };
12724                long[] longOut = new long[1];
12725                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12726                        SINGLE_LONG_FORMAT, null, longOut, null);
12727                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12728                longOut[0] = 0;
12729                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12730                        SINGLE_LONG_FORMAT, null, longOut, null);
12731                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12732                longOut[0] = 0;
12733                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12734                        SINGLE_LONG_FORMAT, null, longOut, null);
12735                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12736                longOut[0] = 0;
12737                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12738                        SINGLE_LONG_FORMAT, null, longOut, null);
12739                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12740                if (!isCompact) {
12741                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12742                        pw.print("      KSM: "); pw.print(sharing);
12743                                pw.print(" kB saved from shared ");
12744                                pw.print(shared); pw.println(" kB");
12745                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12746                                pw.print(voltile); pw.println(" kB volatile");
12747                    }
12748                    pw.print("   Tuning: ");
12749                    pw.print(ActivityManager.staticGetMemoryClass());
12750                    pw.print(" (large ");
12751                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12752                    pw.print("), oom ");
12753                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12754                    pw.print(" kB");
12755                    pw.print(", restore limit ");
12756                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12757                    pw.print(" kB");
12758                    if (ActivityManager.isLowRamDeviceStatic()) {
12759                        pw.print(" (low-ram)");
12760                    }
12761                    if (ActivityManager.isHighEndGfx()) {
12762                        pw.print(" (high-end-gfx)");
12763                    }
12764                    pw.println();
12765                } else {
12766                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12767                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12768                    pw.println(voltile);
12769                    pw.print("tuning,");
12770                    pw.print(ActivityManager.staticGetMemoryClass());
12771                    pw.print(',');
12772                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12773                    pw.print(',');
12774                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12775                    if (ActivityManager.isLowRamDeviceStatic()) {
12776                        pw.print(",low-ram");
12777                    }
12778                    if (ActivityManager.isHighEndGfx()) {
12779                        pw.print(",high-end-gfx");
12780                    }
12781                    pw.println();
12782                }
12783            }
12784        }
12785    }
12786
12787    /**
12788     * Searches array of arguments for the specified string
12789     * @param args array of argument strings
12790     * @param value value to search for
12791     * @return true if the value is contained in the array
12792     */
12793    private static boolean scanArgs(String[] args, String value) {
12794        if (args != null) {
12795            for (String arg : args) {
12796                if (value.equals(arg)) {
12797                    return true;
12798                }
12799            }
12800        }
12801        return false;
12802    }
12803
12804    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12805            ContentProviderRecord cpr, boolean always) {
12806        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12807
12808        if (!inLaunching || always) {
12809            synchronized (cpr) {
12810                cpr.launchingApp = null;
12811                cpr.notifyAll();
12812            }
12813            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12814            String names[] = cpr.info.authority.split(";");
12815            for (int j = 0; j < names.length; j++) {
12816                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12817            }
12818        }
12819
12820        for (int i=0; i<cpr.connections.size(); i++) {
12821            ContentProviderConnection conn = cpr.connections.get(i);
12822            if (conn.waiting) {
12823                // If this connection is waiting for the provider, then we don't
12824                // need to mess with its process unless we are always removing
12825                // or for some reason the provider is not currently launching.
12826                if (inLaunching && !always) {
12827                    continue;
12828                }
12829            }
12830            ProcessRecord capp = conn.client;
12831            conn.dead = true;
12832            if (conn.stableCount > 0) {
12833                if (!capp.persistent && capp.thread != null
12834                        && capp.pid != 0
12835                        && capp.pid != MY_PID) {
12836                    killUnneededProcessLocked(capp, "depends on provider "
12837                            + cpr.name.flattenToShortString()
12838                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12839                }
12840            } else if (capp.thread != null && conn.provider.provider != null) {
12841                try {
12842                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12843                } catch (RemoteException e) {
12844                }
12845                // In the protocol here, we don't expect the client to correctly
12846                // clean up this connection, we'll just remove it.
12847                cpr.connections.remove(i);
12848                conn.client.conProviders.remove(conn);
12849            }
12850        }
12851
12852        if (inLaunching && always) {
12853            mLaunchingProviders.remove(cpr);
12854        }
12855        return inLaunching;
12856    }
12857
12858    /**
12859     * Main code for cleaning up a process when it has gone away.  This is
12860     * called both as a result of the process dying, or directly when stopping
12861     * a process when running in single process mode.
12862     */
12863    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12864            boolean restarting, boolean allowRestart, int index) {
12865        if (index >= 0) {
12866            removeLruProcessLocked(app);
12867            ProcessList.remove(app.pid);
12868        }
12869
12870        mProcessesToGc.remove(app);
12871        mPendingPssProcesses.remove(app);
12872
12873        // Dismiss any open dialogs.
12874        if (app.crashDialog != null && !app.forceCrashReport) {
12875            app.crashDialog.dismiss();
12876            app.crashDialog = null;
12877        }
12878        if (app.anrDialog != null) {
12879            app.anrDialog.dismiss();
12880            app.anrDialog = null;
12881        }
12882        if (app.waitDialog != null) {
12883            app.waitDialog.dismiss();
12884            app.waitDialog = null;
12885        }
12886
12887        app.crashing = false;
12888        app.notResponding = false;
12889
12890        app.resetPackageList(mProcessStats);
12891        app.unlinkDeathRecipient();
12892        app.makeInactive(mProcessStats);
12893        app.forcingToForeground = null;
12894        updateProcessForegroundLocked(app, false, false);
12895        app.foregroundActivities = false;
12896        app.hasShownUi = false;
12897        app.treatLikeActivity = false;
12898        app.hasAboveClient = false;
12899        app.hasClientActivities = false;
12900
12901        mServices.killServicesLocked(app, allowRestart);
12902
12903        boolean restart = false;
12904
12905        // Remove published content providers.
12906        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12907            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12908            final boolean always = app.bad || !allowRestart;
12909            if (removeDyingProviderLocked(app, cpr, always) || always) {
12910                // We left the provider in the launching list, need to
12911                // restart it.
12912                restart = true;
12913            }
12914
12915            cpr.provider = null;
12916            cpr.proc = null;
12917        }
12918        app.pubProviders.clear();
12919
12920        // Take care of any launching providers waiting for this process.
12921        if (checkAppInLaunchingProvidersLocked(app, false)) {
12922            restart = true;
12923        }
12924
12925        // Unregister from connected content providers.
12926        if (!app.conProviders.isEmpty()) {
12927            for (int i=0; i<app.conProviders.size(); i++) {
12928                ContentProviderConnection conn = app.conProviders.get(i);
12929                conn.provider.connections.remove(conn);
12930            }
12931            app.conProviders.clear();
12932        }
12933
12934        // At this point there may be remaining entries in mLaunchingProviders
12935        // where we were the only one waiting, so they are no longer of use.
12936        // Look for these and clean up if found.
12937        // XXX Commented out for now.  Trying to figure out a way to reproduce
12938        // the actual situation to identify what is actually going on.
12939        if (false) {
12940            for (int i=0; i<mLaunchingProviders.size(); i++) {
12941                ContentProviderRecord cpr = (ContentProviderRecord)
12942                        mLaunchingProviders.get(i);
12943                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12944                    synchronized (cpr) {
12945                        cpr.launchingApp = null;
12946                        cpr.notifyAll();
12947                    }
12948                }
12949            }
12950        }
12951
12952        skipCurrentReceiverLocked(app);
12953
12954        // Unregister any receivers.
12955        for (int i=app.receivers.size()-1; i>=0; i--) {
12956            removeReceiverLocked(app.receivers.valueAt(i));
12957        }
12958        app.receivers.clear();
12959
12960        // If the app is undergoing backup, tell the backup manager about it
12961        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12962            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12963                    + mBackupTarget.appInfo + " died during backup");
12964            try {
12965                IBackupManager bm = IBackupManager.Stub.asInterface(
12966                        ServiceManager.getService(Context.BACKUP_SERVICE));
12967                bm.agentDisconnected(app.info.packageName);
12968            } catch (RemoteException e) {
12969                // can't happen; backup manager is local
12970            }
12971        }
12972
12973        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12974            ProcessChangeItem item = mPendingProcessChanges.get(i);
12975            if (item.pid == app.pid) {
12976                mPendingProcessChanges.remove(i);
12977                mAvailProcessChanges.add(item);
12978            }
12979        }
12980        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12981
12982        // If the caller is restarting this app, then leave it in its
12983        // current lists and let the caller take care of it.
12984        if (restarting) {
12985            return;
12986        }
12987
12988        if (!app.persistent || app.isolated) {
12989            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12990                    "Removing non-persistent process during cleanup: " + app);
12991            mProcessNames.remove(app.processName, app.uid);
12992            mIsolatedProcesses.remove(app.uid);
12993            if (mHeavyWeightProcess == app) {
12994                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12995                        mHeavyWeightProcess.userId, 0));
12996                mHeavyWeightProcess = null;
12997            }
12998        } else if (!app.removed) {
12999            // This app is persistent, so we need to keep its record around.
13000            // If it is not already on the pending app list, add it there
13001            // and start a new process for it.
13002            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13003                mPersistentStartingProcesses.add(app);
13004                restart = true;
13005            }
13006        }
13007        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13008                "Clean-up removing on hold: " + app);
13009        mProcessesOnHold.remove(app);
13010
13011        if (app == mHomeProcess) {
13012            mHomeProcess = null;
13013        }
13014        if (app == mPreviousProcess) {
13015            mPreviousProcess = null;
13016        }
13017
13018        if (restart && !app.isolated) {
13019            // We have components that still need to be running in the
13020            // process, so re-launch it.
13021            mProcessNames.put(app.processName, app.uid, app);
13022            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13023        } else if (app.pid > 0 && app.pid != MY_PID) {
13024            // Goodbye!
13025            boolean removed;
13026            synchronized (mPidsSelfLocked) {
13027                mPidsSelfLocked.remove(app.pid);
13028                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13029            }
13030            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13031                    app.processName, app.info.uid);
13032            if (app.isolated) {
13033                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13034            }
13035            app.setPid(0);
13036        }
13037    }
13038
13039    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13040        // Look through the content providers we are waiting to have launched,
13041        // and if any run in this process then either schedule a restart of
13042        // the process or kill the client waiting for it if this process has
13043        // gone bad.
13044        int NL = mLaunchingProviders.size();
13045        boolean restart = false;
13046        for (int i=0; i<NL; i++) {
13047            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13048            if (cpr.launchingApp == app) {
13049                if (!alwaysBad && !app.bad) {
13050                    restart = true;
13051                } else {
13052                    removeDyingProviderLocked(app, cpr, true);
13053                    // cpr should have been removed from mLaunchingProviders
13054                    NL = mLaunchingProviders.size();
13055                    i--;
13056                }
13057            }
13058        }
13059        return restart;
13060    }
13061
13062    // =========================================================
13063    // SERVICES
13064    // =========================================================
13065
13066    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13067            int flags) {
13068        enforceNotIsolatedCaller("getServices");
13069        synchronized (this) {
13070            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13071        }
13072    }
13073
13074    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13075        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13076        synchronized (this) {
13077            return mServices.getRunningServiceControlPanelLocked(name);
13078        }
13079    }
13080
13081    public ComponentName startService(IApplicationThread caller, Intent service,
13082            String resolvedType, int userId) {
13083        enforceNotIsolatedCaller("startService");
13084        // Refuse possible leaked file descriptors
13085        if (service != null && service.hasFileDescriptors() == true) {
13086            throw new IllegalArgumentException("File descriptors passed in Intent");
13087        }
13088
13089        if (DEBUG_SERVICE)
13090            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13091        synchronized(this) {
13092            final int callingPid = Binder.getCallingPid();
13093            final int callingUid = Binder.getCallingUid();
13094            final long origId = Binder.clearCallingIdentity();
13095            ComponentName res = mServices.startServiceLocked(caller, service,
13096                    resolvedType, callingPid, callingUid, userId);
13097            Binder.restoreCallingIdentity(origId);
13098            return res;
13099        }
13100    }
13101
13102    ComponentName startServiceInPackage(int uid,
13103            Intent service, String resolvedType, int userId) {
13104        synchronized(this) {
13105            if (DEBUG_SERVICE)
13106                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13107            final long origId = Binder.clearCallingIdentity();
13108            ComponentName res = mServices.startServiceLocked(null, service,
13109                    resolvedType, -1, uid, userId);
13110            Binder.restoreCallingIdentity(origId);
13111            return res;
13112        }
13113    }
13114
13115    public int stopService(IApplicationThread caller, Intent service,
13116            String resolvedType, int userId) {
13117        enforceNotIsolatedCaller("stopService");
13118        // Refuse possible leaked file descriptors
13119        if (service != null && service.hasFileDescriptors() == true) {
13120            throw new IllegalArgumentException("File descriptors passed in Intent");
13121        }
13122
13123        synchronized(this) {
13124            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13125        }
13126    }
13127
13128    public IBinder peekService(Intent service, String resolvedType) {
13129        enforceNotIsolatedCaller("peekService");
13130        // Refuse possible leaked file descriptors
13131        if (service != null && service.hasFileDescriptors() == true) {
13132            throw new IllegalArgumentException("File descriptors passed in Intent");
13133        }
13134        synchronized(this) {
13135            return mServices.peekServiceLocked(service, resolvedType);
13136        }
13137    }
13138
13139    public boolean stopServiceToken(ComponentName className, IBinder token,
13140            int startId) {
13141        synchronized(this) {
13142            return mServices.stopServiceTokenLocked(className, token, startId);
13143        }
13144    }
13145
13146    public void setServiceForeground(ComponentName className, IBinder token,
13147            int id, Notification notification, boolean removeNotification) {
13148        synchronized(this) {
13149            mServices.setServiceForegroundLocked(className, token, id, notification,
13150                    removeNotification);
13151        }
13152    }
13153
13154    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13155            boolean requireFull, String name, String callerPackage) {
13156        final int callingUserId = UserHandle.getUserId(callingUid);
13157        if (callingUserId != userId) {
13158            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13159                if ((requireFull || checkComponentPermission(
13160                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13161                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13162                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13163                                callingPid, callingUid, -1, true)
13164                                != PackageManager.PERMISSION_GRANTED) {
13165                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13166                        // In this case, they would like to just execute as their
13167                        // owner user instead of failing.
13168                        userId = callingUserId;
13169                    } else {
13170                        StringBuilder builder = new StringBuilder(128);
13171                        builder.append("Permission Denial: ");
13172                        builder.append(name);
13173                        if (callerPackage != null) {
13174                            builder.append(" from ");
13175                            builder.append(callerPackage);
13176                        }
13177                        builder.append(" asks to run as user ");
13178                        builder.append(userId);
13179                        builder.append(" but is calling from user ");
13180                        builder.append(UserHandle.getUserId(callingUid));
13181                        builder.append("; this requires ");
13182                        builder.append(INTERACT_ACROSS_USERS_FULL);
13183                        if (!requireFull) {
13184                            builder.append(" or ");
13185                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13186                        }
13187                        String msg = builder.toString();
13188                        Slog.w(TAG, msg);
13189                        throw new SecurityException(msg);
13190                    }
13191                }
13192            }
13193            if (userId == UserHandle.USER_CURRENT
13194                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13195                // Note that we may be accessing this outside of a lock...
13196                // shouldn't be a big deal, if this is being called outside
13197                // of a locked context there is intrinsically a race with
13198                // the value the caller will receive and someone else changing it.
13199                userId = mCurrentUserId;
13200            }
13201            if (!allowAll && userId < 0) {
13202                throw new IllegalArgumentException(
13203                        "Call does not support special user #" + userId);
13204            }
13205        }
13206        return userId;
13207    }
13208
13209    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13210            String className, int flags) {
13211        boolean result = false;
13212        // For apps that don't have pre-defined UIDs, check for permission
13213        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13214            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13215                if (ActivityManager.checkUidPermission(
13216                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13217                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13218                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13219                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13220                            + " requests FLAG_SINGLE_USER, but app does not hold "
13221                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13222                    Slog.w(TAG, msg);
13223                    throw new SecurityException(msg);
13224                }
13225                // Permission passed
13226                result = true;
13227            }
13228        } else if ("system".equals(componentProcessName)) {
13229            result = true;
13230        } else {
13231            // App with pre-defined UID, check if it's a persistent app
13232            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13233        }
13234        if (DEBUG_MU) {
13235            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13236                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13237        }
13238        return result;
13239    }
13240
13241    /**
13242     * Checks to see if the caller is in the same app as the singleton
13243     * component, or the component is in a special app. It allows special apps
13244     * to export singleton components but prevents exporting singleton
13245     * components for regular apps.
13246     */
13247    boolean isValidSingletonCall(int callingUid, int componentUid) {
13248        int componentAppId = UserHandle.getAppId(componentUid);
13249        return UserHandle.isSameApp(callingUid, componentUid)
13250                || componentAppId == Process.SYSTEM_UID
13251                || componentAppId == Process.PHONE_UID
13252                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13253                        == PackageManager.PERMISSION_GRANTED;
13254    }
13255
13256    public int bindService(IApplicationThread caller, IBinder token,
13257            Intent service, String resolvedType,
13258            IServiceConnection connection, int flags, int userId) {
13259        enforceNotIsolatedCaller("bindService");
13260        // Refuse possible leaked file descriptors
13261        if (service != null && service.hasFileDescriptors() == true) {
13262            throw new IllegalArgumentException("File descriptors passed in Intent");
13263        }
13264
13265        synchronized(this) {
13266            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13267                    connection, flags, userId);
13268        }
13269    }
13270
13271    public boolean unbindService(IServiceConnection connection) {
13272        synchronized (this) {
13273            return mServices.unbindServiceLocked(connection);
13274        }
13275    }
13276
13277    public void publishService(IBinder token, Intent intent, IBinder service) {
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            if (!(token instanceof ServiceRecord)) {
13285                throw new IllegalArgumentException("Invalid service token");
13286            }
13287            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13288        }
13289    }
13290
13291    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13292        // Refuse possible leaked file descriptors
13293        if (intent != null && intent.hasFileDescriptors() == true) {
13294            throw new IllegalArgumentException("File descriptors passed in Intent");
13295        }
13296
13297        synchronized(this) {
13298            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13299        }
13300    }
13301
13302    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13303        synchronized(this) {
13304            if (!(token instanceof ServiceRecord)) {
13305                throw new IllegalArgumentException("Invalid service token");
13306            }
13307            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13308        }
13309    }
13310
13311    // =========================================================
13312    // BACKUP AND RESTORE
13313    // =========================================================
13314
13315    // Cause the target app to be launched if necessary and its backup agent
13316    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13317    // activity manager to announce its creation.
13318    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13319        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13320        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13321
13322        synchronized(this) {
13323            // !!! TODO: currently no check here that we're already bound
13324            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13325            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13326            synchronized (stats) {
13327                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13328            }
13329
13330            // Backup agent is now in use, its package can't be stopped.
13331            try {
13332                AppGlobals.getPackageManager().setPackageStoppedState(
13333                        app.packageName, false, UserHandle.getUserId(app.uid));
13334            } catch (RemoteException e) {
13335            } catch (IllegalArgumentException e) {
13336                Slog.w(TAG, "Failed trying to unstop package "
13337                        + app.packageName + ": " + e);
13338            }
13339
13340            BackupRecord r = new BackupRecord(ss, app, backupMode);
13341            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13342                    ? new ComponentName(app.packageName, app.backupAgentName)
13343                    : new ComponentName("android", "FullBackupAgent");
13344            // startProcessLocked() returns existing proc's record if it's already running
13345            ProcessRecord proc = startProcessLocked(app.processName, app,
13346                    false, 0, "backup", hostingName, false, false, false);
13347            if (proc == null) {
13348                Slog.e(TAG, "Unable to start backup agent process " + r);
13349                return false;
13350            }
13351
13352            r.app = proc;
13353            mBackupTarget = r;
13354            mBackupAppName = app.packageName;
13355
13356            // Try not to kill the process during backup
13357            updateOomAdjLocked(proc);
13358
13359            // If the process is already attached, schedule the creation of the backup agent now.
13360            // If it is not yet live, this will be done when it attaches to the framework.
13361            if (proc.thread != null) {
13362                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13363                try {
13364                    proc.thread.scheduleCreateBackupAgent(app,
13365                            compatibilityInfoForPackageLocked(app), backupMode);
13366                } catch (RemoteException e) {
13367                    // Will time out on the backup manager side
13368                }
13369            } else {
13370                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13371            }
13372            // Invariants: at this point, the target app process exists and the application
13373            // is either already running or in the process of coming up.  mBackupTarget and
13374            // mBackupAppName describe the app, so that when it binds back to the AM we
13375            // know that it's scheduled for a backup-agent operation.
13376        }
13377
13378        return true;
13379    }
13380
13381    @Override
13382    public void clearPendingBackup() {
13383        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13384        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13385
13386        synchronized (this) {
13387            mBackupTarget = null;
13388            mBackupAppName = null;
13389        }
13390    }
13391
13392    // A backup agent has just come up
13393    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13394        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13395                + " = " + agent);
13396
13397        synchronized(this) {
13398            if (!agentPackageName.equals(mBackupAppName)) {
13399                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13400                return;
13401            }
13402        }
13403
13404        long oldIdent = Binder.clearCallingIdentity();
13405        try {
13406            IBackupManager bm = IBackupManager.Stub.asInterface(
13407                    ServiceManager.getService(Context.BACKUP_SERVICE));
13408            bm.agentConnected(agentPackageName, agent);
13409        } catch (RemoteException e) {
13410            // can't happen; the backup manager service is local
13411        } catch (Exception e) {
13412            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13413            e.printStackTrace();
13414        } finally {
13415            Binder.restoreCallingIdentity(oldIdent);
13416        }
13417    }
13418
13419    // done with this agent
13420    public void unbindBackupAgent(ApplicationInfo appInfo) {
13421        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13422        if (appInfo == null) {
13423            Slog.w(TAG, "unbind backup agent for null app");
13424            return;
13425        }
13426
13427        synchronized(this) {
13428            try {
13429                if (mBackupAppName == null) {
13430                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13431                    return;
13432                }
13433
13434                if (!mBackupAppName.equals(appInfo.packageName)) {
13435                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13436                    return;
13437                }
13438
13439                // Not backing this app up any more; reset its OOM adjustment
13440                final ProcessRecord proc = mBackupTarget.app;
13441                updateOomAdjLocked(proc);
13442
13443                // If the app crashed during backup, 'thread' will be null here
13444                if (proc.thread != null) {
13445                    try {
13446                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13447                                compatibilityInfoForPackageLocked(appInfo));
13448                    } catch (Exception e) {
13449                        Slog.e(TAG, "Exception when unbinding backup agent:");
13450                        e.printStackTrace();
13451                    }
13452                }
13453            } finally {
13454                mBackupTarget = null;
13455                mBackupAppName = null;
13456            }
13457        }
13458    }
13459    // =========================================================
13460    // BROADCASTS
13461    // =========================================================
13462
13463    private final List getStickiesLocked(String action, IntentFilter filter,
13464            List cur, int userId) {
13465        final ContentResolver resolver = mContext.getContentResolver();
13466        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13467        if (stickies == null) {
13468            return cur;
13469        }
13470        final ArrayList<Intent> list = stickies.get(action);
13471        if (list == null) {
13472            return cur;
13473        }
13474        int N = list.size();
13475        for (int i=0; i<N; i++) {
13476            Intent intent = list.get(i);
13477            if (filter.match(resolver, intent, true, TAG) >= 0) {
13478                if (cur == null) {
13479                    cur = new ArrayList<Intent>();
13480                }
13481                cur.add(intent);
13482            }
13483        }
13484        return cur;
13485    }
13486
13487    boolean isPendingBroadcastProcessLocked(int pid) {
13488        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13489                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13490    }
13491
13492    void skipPendingBroadcastLocked(int pid) {
13493            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13494            for (BroadcastQueue queue : mBroadcastQueues) {
13495                queue.skipPendingBroadcastLocked(pid);
13496            }
13497    }
13498
13499    // The app just attached; send any pending broadcasts that it should receive
13500    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13501        boolean didSomething = false;
13502        for (BroadcastQueue queue : mBroadcastQueues) {
13503            didSomething |= queue.sendPendingBroadcastsLocked(app);
13504        }
13505        return didSomething;
13506    }
13507
13508    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13509            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13510        enforceNotIsolatedCaller("registerReceiver");
13511        int callingUid;
13512        int callingPid;
13513        synchronized(this) {
13514            ProcessRecord callerApp = null;
13515            if (caller != null) {
13516                callerApp = getRecordForAppLocked(caller);
13517                if (callerApp == null) {
13518                    throw new SecurityException(
13519                            "Unable to find app for caller " + caller
13520                            + " (pid=" + Binder.getCallingPid()
13521                            + ") when registering receiver " + receiver);
13522                }
13523                if (callerApp.info.uid != Process.SYSTEM_UID &&
13524                        !callerApp.pkgList.containsKey(callerPackage) &&
13525                        !"android".equals(callerPackage)) {
13526                    throw new SecurityException("Given caller package " + callerPackage
13527                            + " is not running in process " + callerApp);
13528                }
13529                callingUid = callerApp.info.uid;
13530                callingPid = callerApp.pid;
13531            } else {
13532                callerPackage = null;
13533                callingUid = Binder.getCallingUid();
13534                callingPid = Binder.getCallingPid();
13535            }
13536
13537            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13538                    true, true, "registerReceiver", callerPackage);
13539
13540            List allSticky = null;
13541
13542            // Look for any matching sticky broadcasts...
13543            Iterator actions = filter.actionsIterator();
13544            if (actions != null) {
13545                while (actions.hasNext()) {
13546                    String action = (String)actions.next();
13547                    allSticky = getStickiesLocked(action, filter, allSticky,
13548                            UserHandle.USER_ALL);
13549                    allSticky = getStickiesLocked(action, filter, allSticky,
13550                            UserHandle.getUserId(callingUid));
13551                }
13552            } else {
13553                allSticky = getStickiesLocked(null, filter, allSticky,
13554                        UserHandle.USER_ALL);
13555                allSticky = getStickiesLocked(null, filter, allSticky,
13556                        UserHandle.getUserId(callingUid));
13557            }
13558
13559            // The first sticky in the list is returned directly back to
13560            // the client.
13561            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13562
13563            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13564                    + ": " + sticky);
13565
13566            if (receiver == null) {
13567                return sticky;
13568            }
13569
13570            ReceiverList rl
13571                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13572            if (rl == null) {
13573                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13574                        userId, receiver);
13575                if (rl.app != null) {
13576                    rl.app.receivers.add(rl);
13577                } else {
13578                    try {
13579                        receiver.asBinder().linkToDeath(rl, 0);
13580                    } catch (RemoteException e) {
13581                        return sticky;
13582                    }
13583                    rl.linkedToDeath = true;
13584                }
13585                mRegisteredReceivers.put(receiver.asBinder(), rl);
13586            } else if (rl.uid != callingUid) {
13587                throw new IllegalArgumentException(
13588                        "Receiver requested to register for uid " + callingUid
13589                        + " was previously registered for uid " + rl.uid);
13590            } else if (rl.pid != callingPid) {
13591                throw new IllegalArgumentException(
13592                        "Receiver requested to register for pid " + callingPid
13593                        + " was previously registered for pid " + rl.pid);
13594            } else if (rl.userId != userId) {
13595                throw new IllegalArgumentException(
13596                        "Receiver requested to register for user " + userId
13597                        + " was previously registered for user " + rl.userId);
13598            }
13599            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13600                    permission, callingUid, userId);
13601            rl.add(bf);
13602            if (!bf.debugCheck()) {
13603                Slog.w(TAG, "==> For Dynamic broadast");
13604            }
13605            mReceiverResolver.addFilter(bf);
13606
13607            // Enqueue broadcasts for all existing stickies that match
13608            // this filter.
13609            if (allSticky != null) {
13610                ArrayList receivers = new ArrayList();
13611                receivers.add(bf);
13612
13613                int N = allSticky.size();
13614                for (int i=0; i<N; i++) {
13615                    Intent intent = (Intent)allSticky.get(i);
13616                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13617                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13618                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13619                            null, null, false, true, true, -1);
13620                    queue.enqueueParallelBroadcastLocked(r);
13621                    queue.scheduleBroadcastsLocked();
13622                }
13623            }
13624
13625            return sticky;
13626        }
13627    }
13628
13629    public void unregisterReceiver(IIntentReceiver receiver) {
13630        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13631
13632        final long origId = Binder.clearCallingIdentity();
13633        try {
13634            boolean doTrim = false;
13635
13636            synchronized(this) {
13637                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13638                if (rl != null) {
13639                    if (rl.curBroadcast != null) {
13640                        BroadcastRecord r = rl.curBroadcast;
13641                        final boolean doNext = finishReceiverLocked(
13642                                receiver.asBinder(), r.resultCode, r.resultData,
13643                                r.resultExtras, r.resultAbort);
13644                        if (doNext) {
13645                            doTrim = true;
13646                            r.queue.processNextBroadcast(false);
13647                        }
13648                    }
13649
13650                    if (rl.app != null) {
13651                        rl.app.receivers.remove(rl);
13652                    }
13653                    removeReceiverLocked(rl);
13654                    if (rl.linkedToDeath) {
13655                        rl.linkedToDeath = false;
13656                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13657                    }
13658                }
13659            }
13660
13661            // If we actually concluded any broadcasts, we might now be able
13662            // to trim the recipients' apps from our working set
13663            if (doTrim) {
13664                trimApplications();
13665                return;
13666            }
13667
13668        } finally {
13669            Binder.restoreCallingIdentity(origId);
13670        }
13671    }
13672
13673    void removeReceiverLocked(ReceiverList rl) {
13674        mRegisteredReceivers.remove(rl.receiver.asBinder());
13675        int N = rl.size();
13676        for (int i=0; i<N; i++) {
13677            mReceiverResolver.removeFilter(rl.get(i));
13678        }
13679    }
13680
13681    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13682        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13683            ProcessRecord r = mLruProcesses.get(i);
13684            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13685                try {
13686                    r.thread.dispatchPackageBroadcast(cmd, packages);
13687                } catch (RemoteException ex) {
13688                }
13689            }
13690        }
13691    }
13692
13693    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13694            int[] users) {
13695        List<ResolveInfo> receivers = null;
13696        try {
13697            HashSet<ComponentName> singleUserReceivers = null;
13698            boolean scannedFirstReceivers = false;
13699            for (int user : users) {
13700                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13701                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13702                if (user != 0 && newReceivers != null) {
13703                    // If this is not the primary user, we need to check for
13704                    // any receivers that should be filtered out.
13705                    for (int i=0; i<newReceivers.size(); i++) {
13706                        ResolveInfo ri = newReceivers.get(i);
13707                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13708                            newReceivers.remove(i);
13709                            i--;
13710                        }
13711                    }
13712                }
13713                if (newReceivers != null && newReceivers.size() == 0) {
13714                    newReceivers = null;
13715                }
13716                if (receivers == null) {
13717                    receivers = newReceivers;
13718                } else if (newReceivers != null) {
13719                    // We need to concatenate the additional receivers
13720                    // found with what we have do far.  This would be easy,
13721                    // but we also need to de-dup any receivers that are
13722                    // singleUser.
13723                    if (!scannedFirstReceivers) {
13724                        // Collect any single user receivers we had already retrieved.
13725                        scannedFirstReceivers = true;
13726                        for (int i=0; i<receivers.size(); i++) {
13727                            ResolveInfo ri = receivers.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                                singleUserReceivers.add(cn);
13735                            }
13736                        }
13737                    }
13738                    // Add the new results to the existing results, tracking
13739                    // and de-dupping single user receivers.
13740                    for (int i=0; i<newReceivers.size(); i++) {
13741                        ResolveInfo ri = newReceivers.get(i);
13742                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13743                            ComponentName cn = new ComponentName(
13744                                    ri.activityInfo.packageName, ri.activityInfo.name);
13745                            if (singleUserReceivers == null) {
13746                                singleUserReceivers = new HashSet<ComponentName>();
13747                            }
13748                            if (!singleUserReceivers.contains(cn)) {
13749                                singleUserReceivers.add(cn);
13750                                receivers.add(ri);
13751                            }
13752                        } else {
13753                            receivers.add(ri);
13754                        }
13755                    }
13756                }
13757            }
13758        } catch (RemoteException ex) {
13759            // pm is in same process, this will never happen.
13760        }
13761        return receivers;
13762    }
13763
13764    private final int broadcastIntentLocked(ProcessRecord callerApp,
13765            String callerPackage, Intent intent, String resolvedType,
13766            IIntentReceiver resultTo, int resultCode, String resultData,
13767            Bundle map, String requiredPermission, int appOp,
13768            boolean ordered, boolean sticky, int callingPid, int callingUid,
13769            int userId) {
13770        intent = new Intent(intent);
13771
13772        // By default broadcasts do not go to stopped apps.
13773        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13774
13775        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13776            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13777            + " ordered=" + ordered + " userid=" + userId);
13778        if ((resultTo != null) && !ordered) {
13779            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13780        }
13781
13782        userId = handleIncomingUser(callingPid, callingUid, userId,
13783                true, false, "broadcast", callerPackage);
13784
13785        // Make sure that the user who is receiving this broadcast is started.
13786        // If not, we will just skip it.
13787
13788
13789        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13790            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13791                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13792                Slog.w(TAG, "Skipping broadcast of " + intent
13793                        + ": user " + userId + " is stopped");
13794                return ActivityManager.BROADCAST_SUCCESS;
13795            }
13796        }
13797
13798        /*
13799         * Prevent non-system code (defined here to be non-persistent
13800         * processes) from sending protected broadcasts.
13801         */
13802        int callingAppId = UserHandle.getAppId(callingUid);
13803        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13804            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13805            || callingAppId == Process.NFC_UID || callingUid == 0) {
13806            // Always okay.
13807        } else if (callerApp == null || !callerApp.persistent) {
13808            try {
13809                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13810                        intent.getAction())) {
13811                    String msg = "Permission Denial: not allowed to send broadcast "
13812                            + intent.getAction() + " from pid="
13813                            + callingPid + ", uid=" + callingUid;
13814                    Slog.w(TAG, msg);
13815                    throw new SecurityException(msg);
13816                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13817                    // Special case for compatibility: we don't want apps to send this,
13818                    // but historically it has not been protected and apps may be using it
13819                    // to poke their own app widget.  So, instead of making it protected,
13820                    // just limit it to the caller.
13821                    if (callerApp == null) {
13822                        String msg = "Permission Denial: not allowed to send broadcast "
13823                                + intent.getAction() + " from unknown caller.";
13824                        Slog.w(TAG, msg);
13825                        throw new SecurityException(msg);
13826                    } else if (intent.getComponent() != null) {
13827                        // They are good enough to send to an explicit component...  verify
13828                        // it is being sent to the calling app.
13829                        if (!intent.getComponent().getPackageName().equals(
13830                                callerApp.info.packageName)) {
13831                            String msg = "Permission Denial: not allowed to send broadcast "
13832                                    + intent.getAction() + " to "
13833                                    + intent.getComponent().getPackageName() + " from "
13834                                    + callerApp.info.packageName;
13835                            Slog.w(TAG, msg);
13836                            throw new SecurityException(msg);
13837                        }
13838                    } else {
13839                        // Limit broadcast to their own package.
13840                        intent.setPackage(callerApp.info.packageName);
13841                    }
13842                }
13843            } catch (RemoteException e) {
13844                Slog.w(TAG, "Remote exception", e);
13845                return ActivityManager.BROADCAST_SUCCESS;
13846            }
13847        }
13848
13849        // Handle special intents: if this broadcast is from the package
13850        // manager about a package being removed, we need to remove all of
13851        // its activities from the history stack.
13852        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13853                intent.getAction());
13854        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13855                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13856                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13857                || uidRemoved) {
13858            if (checkComponentPermission(
13859                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13860                    callingPid, callingUid, -1, true)
13861                    == PackageManager.PERMISSION_GRANTED) {
13862                if (uidRemoved) {
13863                    final Bundle intentExtras = intent.getExtras();
13864                    final int uid = intentExtras != null
13865                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13866                    if (uid >= 0) {
13867                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13868                        synchronized (bs) {
13869                            bs.removeUidStatsLocked(uid);
13870                        }
13871                        mAppOpsService.uidRemoved(uid);
13872                    }
13873                } else {
13874                    // If resources are unavailable just force stop all
13875                    // those packages and flush the attribute cache as well.
13876                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13877                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13878                        if (list != null && (list.length > 0)) {
13879                            for (String pkg : list) {
13880                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13881                                        "storage unmount");
13882                            }
13883                            sendPackageBroadcastLocked(
13884                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13885                        }
13886                    } else {
13887                        Uri data = intent.getData();
13888                        String ssp;
13889                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13890                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13891                                    intent.getAction());
13892                            boolean fullUninstall = removed &&
13893                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13894                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13895                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13896                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13897                                        false, fullUninstall, userId,
13898                                        removed ? "pkg removed" : "pkg changed");
13899                            }
13900                            if (removed) {
13901                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13902                                        new String[] {ssp}, userId);
13903                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13904                                    mAppOpsService.packageRemoved(
13905                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13906
13907                                    // Remove all permissions granted from/to this package
13908                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13909                                }
13910                            }
13911                        }
13912                    }
13913                }
13914            } else {
13915                String msg = "Permission Denial: " + intent.getAction()
13916                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13917                        + ", uid=" + callingUid + ")"
13918                        + " requires "
13919                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13920                Slog.w(TAG, msg);
13921                throw new SecurityException(msg);
13922            }
13923
13924        // Special case for adding a package: by default turn on compatibility
13925        // mode.
13926        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13927            Uri data = intent.getData();
13928            String ssp;
13929            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13930                mCompatModePackages.handlePackageAddedLocked(ssp,
13931                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13932            }
13933        }
13934
13935        /*
13936         * If this is the time zone changed action, queue up a message that will reset the timezone
13937         * of all currently running processes. This message will get queued up before the broadcast
13938         * happens.
13939         */
13940        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13941            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13942        }
13943
13944        /*
13945         * If the user set the time, let all running processes know.
13946         */
13947        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13948            final int is24Hour = intent.getBooleanExtra(
13949                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13950            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13951        }
13952
13953        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13954            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13955        }
13956
13957        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13958            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13959            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13960        }
13961
13962        // Add to the sticky list if requested.
13963        if (sticky) {
13964            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13965                    callingPid, callingUid)
13966                    != PackageManager.PERMISSION_GRANTED) {
13967                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13968                        + callingPid + ", uid=" + callingUid
13969                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13970                Slog.w(TAG, msg);
13971                throw new SecurityException(msg);
13972            }
13973            if (requiredPermission != null) {
13974                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13975                        + " and enforce permission " + requiredPermission);
13976                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13977            }
13978            if (intent.getComponent() != null) {
13979                throw new SecurityException(
13980                        "Sticky broadcasts can't target a specific component");
13981            }
13982            // We use userId directly here, since the "all" target is maintained
13983            // as a separate set of sticky broadcasts.
13984            if (userId != UserHandle.USER_ALL) {
13985                // But first, if this is not a broadcast to all users, then
13986                // make sure it doesn't conflict with an existing broadcast to
13987                // all users.
13988                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13989                        UserHandle.USER_ALL);
13990                if (stickies != null) {
13991                    ArrayList<Intent> list = stickies.get(intent.getAction());
13992                    if (list != null) {
13993                        int N = list.size();
13994                        int i;
13995                        for (i=0; i<N; i++) {
13996                            if (intent.filterEquals(list.get(i))) {
13997                                throw new IllegalArgumentException(
13998                                        "Sticky broadcast " + intent + " for user "
13999                                        + userId + " conflicts with existing global broadcast");
14000                            }
14001                        }
14002                    }
14003                }
14004            }
14005            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14006            if (stickies == null) {
14007                stickies = new ArrayMap<String, ArrayList<Intent>>();
14008                mStickyBroadcasts.put(userId, stickies);
14009            }
14010            ArrayList<Intent> list = stickies.get(intent.getAction());
14011            if (list == null) {
14012                list = new ArrayList<Intent>();
14013                stickies.put(intent.getAction(), list);
14014            }
14015            int N = list.size();
14016            int i;
14017            for (i=0; i<N; i++) {
14018                if (intent.filterEquals(list.get(i))) {
14019                    // This sticky already exists, replace it.
14020                    list.set(i, new Intent(intent));
14021                    break;
14022                }
14023            }
14024            if (i >= N) {
14025                list.add(new Intent(intent));
14026            }
14027        }
14028
14029        int[] users;
14030        if (userId == UserHandle.USER_ALL) {
14031            // Caller wants broadcast to go to all started users.
14032            users = mStartedUserArray;
14033        } else {
14034            // Caller wants broadcast to go to one specific user.
14035            users = new int[] {userId};
14036        }
14037
14038        // Figure out who all will receive this broadcast.
14039        List receivers = null;
14040        List<BroadcastFilter> registeredReceivers = null;
14041        // Need to resolve the intent to interested receivers...
14042        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14043                 == 0) {
14044            receivers = collectReceiverComponents(intent, resolvedType, users);
14045        }
14046        if (intent.getComponent() == null) {
14047            registeredReceivers = mReceiverResolver.queryIntent(intent,
14048                    resolvedType, false, userId);
14049        }
14050
14051        final boolean replacePending =
14052                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14053
14054        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14055                + " replacePending=" + replacePending);
14056
14057        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14058        if (!ordered && NR > 0) {
14059            // If we are not serializing this broadcast, then send the
14060            // registered receivers separately so they don't wait for the
14061            // components to be launched.
14062            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14063            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14064                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14065                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14066                    ordered, sticky, false, userId);
14067            if (DEBUG_BROADCAST) Slog.v(
14068                    TAG, "Enqueueing parallel broadcast " + r);
14069            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14070            if (!replaced) {
14071                queue.enqueueParallelBroadcastLocked(r);
14072                queue.scheduleBroadcastsLocked();
14073            }
14074            registeredReceivers = null;
14075            NR = 0;
14076        }
14077
14078        // Merge into one list.
14079        int ir = 0;
14080        if (receivers != null) {
14081            // A special case for PACKAGE_ADDED: do not allow the package
14082            // being added to see this broadcast.  This prevents them from
14083            // using this as a back door to get run as soon as they are
14084            // installed.  Maybe in the future we want to have a special install
14085            // broadcast or such for apps, but we'd like to deliberately make
14086            // this decision.
14087            String skipPackages[] = null;
14088            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14089                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14090                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14091                Uri data = intent.getData();
14092                if (data != null) {
14093                    String pkgName = data.getSchemeSpecificPart();
14094                    if (pkgName != null) {
14095                        skipPackages = new String[] { pkgName };
14096                    }
14097                }
14098            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14099                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14100            }
14101            if (skipPackages != null && (skipPackages.length > 0)) {
14102                for (String skipPackage : skipPackages) {
14103                    if (skipPackage != null) {
14104                        int NT = receivers.size();
14105                        for (int it=0; it<NT; it++) {
14106                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14107                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14108                                receivers.remove(it);
14109                                it--;
14110                                NT--;
14111                            }
14112                        }
14113                    }
14114                }
14115            }
14116
14117            int NT = receivers != null ? receivers.size() : 0;
14118            int it = 0;
14119            ResolveInfo curt = null;
14120            BroadcastFilter curr = null;
14121            while (it < NT && ir < NR) {
14122                if (curt == null) {
14123                    curt = (ResolveInfo)receivers.get(it);
14124                }
14125                if (curr == null) {
14126                    curr = registeredReceivers.get(ir);
14127                }
14128                if (curr.getPriority() >= curt.priority) {
14129                    // Insert this broadcast record into the final list.
14130                    receivers.add(it, curr);
14131                    ir++;
14132                    curr = null;
14133                    it++;
14134                    NT++;
14135                } else {
14136                    // Skip to the next ResolveInfo in the final list.
14137                    it++;
14138                    curt = null;
14139                }
14140            }
14141        }
14142        while (ir < NR) {
14143            if (receivers == null) {
14144                receivers = new ArrayList();
14145            }
14146            receivers.add(registeredReceivers.get(ir));
14147            ir++;
14148        }
14149
14150        if ((receivers != null && receivers.size() > 0)
14151                || resultTo != null) {
14152            BroadcastQueue queue = broadcastQueueForIntent(intent);
14153            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14154                    callerPackage, callingPid, callingUid, resolvedType,
14155                    requiredPermission, appOp, receivers, resultTo, resultCode,
14156                    resultData, map, ordered, sticky, false, userId);
14157            if (DEBUG_BROADCAST) Slog.v(
14158                    TAG, "Enqueueing ordered broadcast " + r
14159                    + ": prev had " + queue.mOrderedBroadcasts.size());
14160            if (DEBUG_BROADCAST) {
14161                int seq = r.intent.getIntExtra("seq", -1);
14162                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14163            }
14164            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14165            if (!replaced) {
14166                queue.enqueueOrderedBroadcastLocked(r);
14167                queue.scheduleBroadcastsLocked();
14168            }
14169        }
14170
14171        return ActivityManager.BROADCAST_SUCCESS;
14172    }
14173
14174    final Intent verifyBroadcastLocked(Intent intent) {
14175        // Refuse possible leaked file descriptors
14176        if (intent != null && intent.hasFileDescriptors() == true) {
14177            throw new IllegalArgumentException("File descriptors passed in Intent");
14178        }
14179
14180        int flags = intent.getFlags();
14181
14182        if (!mProcessesReady) {
14183            // if the caller really truly claims to know what they're doing, go
14184            // ahead and allow the broadcast without launching any receivers
14185            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14186                intent = new Intent(intent);
14187                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14188            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14189                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14190                        + " before boot completion");
14191                throw new IllegalStateException("Cannot broadcast before boot completed");
14192            }
14193        }
14194
14195        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14196            throw new IllegalArgumentException(
14197                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14198        }
14199
14200        return intent;
14201    }
14202
14203    public final int broadcastIntent(IApplicationThread caller,
14204            Intent intent, String resolvedType, IIntentReceiver resultTo,
14205            int resultCode, String resultData, Bundle map,
14206            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14207        enforceNotIsolatedCaller("broadcastIntent");
14208        synchronized(this) {
14209            intent = verifyBroadcastLocked(intent);
14210
14211            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14212            final int callingPid = Binder.getCallingPid();
14213            final int callingUid = Binder.getCallingUid();
14214            final long origId = Binder.clearCallingIdentity();
14215            int res = broadcastIntentLocked(callerApp,
14216                    callerApp != null ? callerApp.info.packageName : null,
14217                    intent, resolvedType, resultTo,
14218                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14219                    callingPid, callingUid, userId);
14220            Binder.restoreCallingIdentity(origId);
14221            return res;
14222        }
14223    }
14224
14225    int broadcastIntentInPackage(String packageName, int uid,
14226            Intent intent, String resolvedType, IIntentReceiver resultTo,
14227            int resultCode, String resultData, Bundle map,
14228            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14229        synchronized(this) {
14230            intent = verifyBroadcastLocked(intent);
14231
14232            final long origId = Binder.clearCallingIdentity();
14233            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14234                    resultTo, resultCode, resultData, map, requiredPermission,
14235                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14236            Binder.restoreCallingIdentity(origId);
14237            return res;
14238        }
14239    }
14240
14241    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14242        // Refuse possible leaked file descriptors
14243        if (intent != null && intent.hasFileDescriptors() == true) {
14244            throw new IllegalArgumentException("File descriptors passed in Intent");
14245        }
14246
14247        userId = handleIncomingUser(Binder.getCallingPid(),
14248                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14249
14250        synchronized(this) {
14251            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14252                    != PackageManager.PERMISSION_GRANTED) {
14253                String msg = "Permission Denial: unbroadcastIntent() from pid="
14254                        + Binder.getCallingPid()
14255                        + ", uid=" + Binder.getCallingUid()
14256                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14257                Slog.w(TAG, msg);
14258                throw new SecurityException(msg);
14259            }
14260            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14261            if (stickies != null) {
14262                ArrayList<Intent> list = stickies.get(intent.getAction());
14263                if (list != null) {
14264                    int N = list.size();
14265                    int i;
14266                    for (i=0; i<N; i++) {
14267                        if (intent.filterEquals(list.get(i))) {
14268                            list.remove(i);
14269                            break;
14270                        }
14271                    }
14272                    if (list.size() <= 0) {
14273                        stickies.remove(intent.getAction());
14274                    }
14275                }
14276                if (stickies.size() <= 0) {
14277                    mStickyBroadcasts.remove(userId);
14278                }
14279            }
14280        }
14281    }
14282
14283    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14284            String resultData, Bundle resultExtras, boolean resultAbort) {
14285        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14286        if (r == null) {
14287            Slog.w(TAG, "finishReceiver called but not found on queue");
14288            return false;
14289        }
14290
14291        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14292    }
14293
14294    void backgroundServicesFinishedLocked(int userId) {
14295        for (BroadcastQueue queue : mBroadcastQueues) {
14296            queue.backgroundServicesFinishedLocked(userId);
14297        }
14298    }
14299
14300    public void finishReceiver(IBinder who, int resultCode, String resultData,
14301            Bundle resultExtras, boolean resultAbort) {
14302        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14303
14304        // Refuse possible leaked file descriptors
14305        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14306            throw new IllegalArgumentException("File descriptors passed in Bundle");
14307        }
14308
14309        final long origId = Binder.clearCallingIdentity();
14310        try {
14311            boolean doNext = false;
14312            BroadcastRecord r;
14313
14314            synchronized(this) {
14315                r = broadcastRecordForReceiverLocked(who);
14316                if (r != null) {
14317                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14318                        resultData, resultExtras, resultAbort, true);
14319                }
14320            }
14321
14322            if (doNext) {
14323                r.queue.processNextBroadcast(false);
14324            }
14325            trimApplications();
14326        } finally {
14327            Binder.restoreCallingIdentity(origId);
14328        }
14329    }
14330
14331    // =========================================================
14332    // INSTRUMENTATION
14333    // =========================================================
14334
14335    public boolean startInstrumentation(ComponentName className,
14336            String profileFile, int flags, Bundle arguments,
14337            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14338            int userId, String abiOverride) {
14339        enforceNotIsolatedCaller("startInstrumentation");
14340        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14341                userId, false, true, "startInstrumentation", null);
14342        // Refuse possible leaked file descriptors
14343        if (arguments != null && arguments.hasFileDescriptors()) {
14344            throw new IllegalArgumentException("File descriptors passed in Bundle");
14345        }
14346
14347        synchronized(this) {
14348            InstrumentationInfo ii = null;
14349            ApplicationInfo ai = null;
14350            try {
14351                ii = mContext.getPackageManager().getInstrumentationInfo(
14352                    className, STOCK_PM_FLAGS);
14353                ai = AppGlobals.getPackageManager().getApplicationInfo(
14354                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14355            } catch (PackageManager.NameNotFoundException e) {
14356            } catch (RemoteException e) {
14357            }
14358            if (ii == null) {
14359                reportStartInstrumentationFailure(watcher, className,
14360                        "Unable to find instrumentation info for: " + className);
14361                return false;
14362            }
14363            if (ai == null) {
14364                reportStartInstrumentationFailure(watcher, className,
14365                        "Unable to find instrumentation target package: " + ii.targetPackage);
14366                return false;
14367            }
14368
14369            int match = mContext.getPackageManager().checkSignatures(
14370                    ii.targetPackage, ii.packageName);
14371            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14372                String msg = "Permission Denial: starting instrumentation "
14373                        + className + " from pid="
14374                        + Binder.getCallingPid()
14375                        + ", uid=" + Binder.getCallingPid()
14376                        + " not allowed because package " + ii.packageName
14377                        + " does not have a signature matching the target "
14378                        + ii.targetPackage;
14379                reportStartInstrumentationFailure(watcher, className, msg);
14380                throw new SecurityException(msg);
14381            }
14382
14383            final long origId = Binder.clearCallingIdentity();
14384            // Instrumentation can kill and relaunch even persistent processes
14385            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14386                    "start instr");
14387            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14388            app.instrumentationClass = className;
14389            app.instrumentationInfo = ai;
14390            app.instrumentationProfileFile = profileFile;
14391            app.instrumentationArguments = arguments;
14392            app.instrumentationWatcher = watcher;
14393            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14394            app.instrumentationResultClass = className;
14395            Binder.restoreCallingIdentity(origId);
14396        }
14397
14398        return true;
14399    }
14400
14401    /**
14402     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14403     * error to the logs, but if somebody is watching, send the report there too.  This enables
14404     * the "am" command to report errors with more information.
14405     *
14406     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14407     * @param cn The component name of the instrumentation.
14408     * @param report The error report.
14409     */
14410    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14411            ComponentName cn, String report) {
14412        Slog.w(TAG, report);
14413        try {
14414            if (watcher != null) {
14415                Bundle results = new Bundle();
14416                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14417                results.putString("Error", report);
14418                watcher.instrumentationStatus(cn, -1, results);
14419            }
14420        } catch (RemoteException e) {
14421            Slog.w(TAG, e);
14422        }
14423    }
14424
14425    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14426        if (app.instrumentationWatcher != null) {
14427            try {
14428                // NOTE:  IInstrumentationWatcher *must* be oneway here
14429                app.instrumentationWatcher.instrumentationFinished(
14430                    app.instrumentationClass,
14431                    resultCode,
14432                    results);
14433            } catch (RemoteException e) {
14434            }
14435        }
14436        if (app.instrumentationUiAutomationConnection != null) {
14437            try {
14438                app.instrumentationUiAutomationConnection.shutdown();
14439            } catch (RemoteException re) {
14440                /* ignore */
14441            }
14442            // Only a UiAutomation can set this flag and now that
14443            // it is finished we make sure it is reset to its default.
14444            mUserIsMonkey = false;
14445        }
14446        app.instrumentationWatcher = null;
14447        app.instrumentationUiAutomationConnection = null;
14448        app.instrumentationClass = null;
14449        app.instrumentationInfo = null;
14450        app.instrumentationProfileFile = null;
14451        app.instrumentationArguments = null;
14452
14453        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14454                "finished inst");
14455    }
14456
14457    public void finishInstrumentation(IApplicationThread target,
14458            int resultCode, Bundle results) {
14459        int userId = UserHandle.getCallingUserId();
14460        // Refuse possible leaked file descriptors
14461        if (results != null && results.hasFileDescriptors()) {
14462            throw new IllegalArgumentException("File descriptors passed in Intent");
14463        }
14464
14465        synchronized(this) {
14466            ProcessRecord app = getRecordForAppLocked(target);
14467            if (app == null) {
14468                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14469                return;
14470            }
14471            final long origId = Binder.clearCallingIdentity();
14472            finishInstrumentationLocked(app, resultCode, results);
14473            Binder.restoreCallingIdentity(origId);
14474        }
14475    }
14476
14477    // =========================================================
14478    // CONFIGURATION
14479    // =========================================================
14480
14481    public ConfigurationInfo getDeviceConfigurationInfo() {
14482        ConfigurationInfo config = new ConfigurationInfo();
14483        synchronized (this) {
14484            config.reqTouchScreen = mConfiguration.touchscreen;
14485            config.reqKeyboardType = mConfiguration.keyboard;
14486            config.reqNavigation = mConfiguration.navigation;
14487            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14488                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14489                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14490            }
14491            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14492                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14493                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14494            }
14495            config.reqGlEsVersion = GL_ES_VERSION;
14496        }
14497        return config;
14498    }
14499
14500    ActivityStack getFocusedStack() {
14501        return mStackSupervisor.getFocusedStack();
14502    }
14503
14504    public Configuration getConfiguration() {
14505        Configuration ci;
14506        synchronized(this) {
14507            ci = new Configuration(mConfiguration);
14508        }
14509        return ci;
14510    }
14511
14512    public void updatePersistentConfiguration(Configuration values) {
14513        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14514                "updateConfiguration()");
14515        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14516                "updateConfiguration()");
14517        if (values == null) {
14518            throw new NullPointerException("Configuration must not be null");
14519        }
14520
14521        synchronized(this) {
14522            final long origId = Binder.clearCallingIdentity();
14523            updateConfigurationLocked(values, null, true, false);
14524            Binder.restoreCallingIdentity(origId);
14525        }
14526    }
14527
14528    public void updateConfiguration(Configuration values) {
14529        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14530                "updateConfiguration()");
14531
14532        synchronized(this) {
14533            if (values == null && mWindowManager != null) {
14534                // sentinel: fetch the current configuration from the window manager
14535                values = mWindowManager.computeNewConfiguration();
14536            }
14537
14538            if (mWindowManager != null) {
14539                mProcessList.applyDisplaySize(mWindowManager);
14540            }
14541
14542            final long origId = Binder.clearCallingIdentity();
14543            if (values != null) {
14544                Settings.System.clearConfiguration(values);
14545            }
14546            updateConfigurationLocked(values, null, false, false);
14547            Binder.restoreCallingIdentity(origId);
14548        }
14549    }
14550
14551    /**
14552     * Do either or both things: (1) change the current configuration, and (2)
14553     * make sure the given activity is running with the (now) current
14554     * configuration.  Returns true if the activity has been left running, or
14555     * false if <var>starting</var> is being destroyed to match the new
14556     * configuration.
14557     * @param persistent TODO
14558     */
14559    boolean updateConfigurationLocked(Configuration values,
14560            ActivityRecord starting, boolean persistent, boolean initLocale) {
14561        int changes = 0;
14562
14563        if (values != null) {
14564            Configuration newConfig = new Configuration(mConfiguration);
14565            changes = newConfig.updateFrom(values);
14566            if (changes != 0) {
14567                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14568                    Slog.i(TAG, "Updating configuration to: " + values);
14569                }
14570
14571                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14572
14573                if (values.locale != null && !initLocale) {
14574                    saveLocaleLocked(values.locale,
14575                                     !values.locale.equals(mConfiguration.locale),
14576                                     values.userSetLocale);
14577                }
14578
14579                mConfigurationSeq++;
14580                if (mConfigurationSeq <= 0) {
14581                    mConfigurationSeq = 1;
14582                }
14583                newConfig.seq = mConfigurationSeq;
14584                mConfiguration = newConfig;
14585                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14586                mUsageStatsService.noteStartConfig(newConfig);
14587
14588                final Configuration configCopy = new Configuration(mConfiguration);
14589
14590                // TODO: If our config changes, should we auto dismiss any currently
14591                // showing dialogs?
14592                mShowDialogs = shouldShowDialogs(newConfig);
14593
14594                AttributeCache ac = AttributeCache.instance();
14595                if (ac != null) {
14596                    ac.updateConfiguration(configCopy);
14597                }
14598
14599                // Make sure all resources in our process are updated
14600                // right now, so that anyone who is going to retrieve
14601                // resource values after we return will be sure to get
14602                // the new ones.  This is especially important during
14603                // boot, where the first config change needs to guarantee
14604                // all resources have that config before following boot
14605                // code is executed.
14606                mSystemThread.applyConfigurationToResources(configCopy);
14607
14608                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14609                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14610                    msg.obj = new Configuration(configCopy);
14611                    mHandler.sendMessage(msg);
14612                }
14613
14614                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14615                    ProcessRecord app = mLruProcesses.get(i);
14616                    try {
14617                        if (app.thread != null) {
14618                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14619                                    + app.processName + " new config " + mConfiguration);
14620                            app.thread.scheduleConfigurationChanged(configCopy);
14621                        }
14622                    } catch (Exception e) {
14623                    }
14624                }
14625                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14626                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14627                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14628                        | Intent.FLAG_RECEIVER_FOREGROUND);
14629                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14630                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14631                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14632                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14633                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14634                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14635                    broadcastIntentLocked(null, null, intent,
14636                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14637                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14638                }
14639            }
14640        }
14641
14642        boolean kept = true;
14643        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14644        // mainStack is null during startup.
14645        if (mainStack != null) {
14646            if (changes != 0 && starting == null) {
14647                // If the configuration changed, and the caller is not already
14648                // in the process of starting an activity, then find the top
14649                // activity to check if its configuration needs to change.
14650                starting = mainStack.topRunningActivityLocked(null);
14651            }
14652
14653            if (starting != null) {
14654                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14655                // And we need to make sure at this point that all other activities
14656                // are made visible with the correct configuration.
14657                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14658            }
14659        }
14660
14661        if (values != null && mWindowManager != null) {
14662            mWindowManager.setNewConfiguration(mConfiguration);
14663        }
14664
14665        return kept;
14666    }
14667
14668    /**
14669     * Decide based on the configuration whether we should shouw the ANR,
14670     * crash, etc dialogs.  The idea is that if there is no affordnace to
14671     * press the on-screen buttons, we shouldn't show the dialog.
14672     *
14673     * A thought: SystemUI might also want to get told about this, the Power
14674     * dialog / global actions also might want different behaviors.
14675     */
14676    private static final boolean shouldShowDialogs(Configuration config) {
14677        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14678                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14679    }
14680
14681    /**
14682     * Save the locale.  You must be inside a synchronized (this) block.
14683     */
14684    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14685        if(isDiff) {
14686            SystemProperties.set("user.language", l.getLanguage());
14687            SystemProperties.set("user.region", l.getCountry());
14688        }
14689
14690        if(isPersist) {
14691            SystemProperties.set("persist.sys.language", l.getLanguage());
14692            SystemProperties.set("persist.sys.country", l.getCountry());
14693            SystemProperties.set("persist.sys.localevar", l.getVariant());
14694        }
14695    }
14696
14697    @Override
14698    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14699        ActivityRecord srec = ActivityRecord.forToken(token);
14700        return srec != null && srec.task.affinity != null &&
14701                srec.task.affinity.equals(destAffinity);
14702    }
14703
14704    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14705            Intent resultData) {
14706
14707        synchronized (this) {
14708            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14709            if (stack != null) {
14710                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14711            }
14712            return false;
14713        }
14714    }
14715
14716    public int getLaunchedFromUid(IBinder activityToken) {
14717        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14718        if (srec == null) {
14719            return -1;
14720        }
14721        return srec.launchedFromUid;
14722    }
14723
14724    public String getLaunchedFromPackage(IBinder activityToken) {
14725        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14726        if (srec == null) {
14727            return null;
14728        }
14729        return srec.launchedFromPackage;
14730    }
14731
14732    // =========================================================
14733    // LIFETIME MANAGEMENT
14734    // =========================================================
14735
14736    // Returns which broadcast queue the app is the current [or imminent] receiver
14737    // on, or 'null' if the app is not an active broadcast recipient.
14738    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14739        BroadcastRecord r = app.curReceiver;
14740        if (r != null) {
14741            return r.queue;
14742        }
14743
14744        // It's not the current receiver, but it might be starting up to become one
14745        synchronized (this) {
14746            for (BroadcastQueue queue : mBroadcastQueues) {
14747                r = queue.mPendingBroadcast;
14748                if (r != null && r.curApp == app) {
14749                    // found it; report which queue it's in
14750                    return queue;
14751                }
14752            }
14753        }
14754
14755        return null;
14756    }
14757
14758    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14759            boolean doingAll, long now) {
14760        if (mAdjSeq == app.adjSeq) {
14761            // This adjustment has already been computed.
14762            return app.curRawAdj;
14763        }
14764
14765        if (app.thread == null) {
14766            app.adjSeq = mAdjSeq;
14767            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14768            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14769            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14770        }
14771
14772        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14773        app.adjSource = null;
14774        app.adjTarget = null;
14775        app.empty = false;
14776        app.cached = false;
14777
14778        final int activitiesSize = app.activities.size();
14779
14780        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14781            // The max adjustment doesn't allow this app to be anything
14782            // below foreground, so it is not worth doing work for it.
14783            app.adjType = "fixed";
14784            app.adjSeq = mAdjSeq;
14785            app.curRawAdj = app.maxAdj;
14786            app.foregroundActivities = false;
14787            app.keeping = true;
14788            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14789            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14790            // System processes can do UI, and when they do we want to have
14791            // them trim their memory after the user leaves the UI.  To
14792            // facilitate this, here we need to determine whether or not it
14793            // is currently showing UI.
14794            app.systemNoUi = true;
14795            if (app == TOP_APP) {
14796                app.systemNoUi = false;
14797            } else if (activitiesSize > 0) {
14798                for (int j = 0; j < activitiesSize; j++) {
14799                    final ActivityRecord r = app.activities.get(j);
14800                    if (r.visible) {
14801                        app.systemNoUi = false;
14802                    }
14803                }
14804            }
14805            if (!app.systemNoUi) {
14806                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14807            }
14808            return (app.curAdj=app.maxAdj);
14809        }
14810
14811        app.keeping = false;
14812        app.systemNoUi = false;
14813
14814        // Determine the importance of the process, starting with most
14815        // important to least, and assign an appropriate OOM adjustment.
14816        int adj;
14817        int schedGroup;
14818        int procState;
14819        boolean foregroundActivities = false;
14820        boolean interesting = false;
14821        BroadcastQueue queue;
14822        if (app == TOP_APP) {
14823            // The last app on the list is the foreground app.
14824            adj = ProcessList.FOREGROUND_APP_ADJ;
14825            schedGroup = Process.THREAD_GROUP_DEFAULT;
14826            app.adjType = "top-activity";
14827            foregroundActivities = true;
14828            interesting = true;
14829            procState = ActivityManager.PROCESS_STATE_TOP;
14830        } else if (app.instrumentationClass != null) {
14831            // Don't want to kill running instrumentation.
14832            adj = ProcessList.FOREGROUND_APP_ADJ;
14833            schedGroup = Process.THREAD_GROUP_DEFAULT;
14834            app.adjType = "instrumentation";
14835            interesting = true;
14836            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14837        } else if ((queue = isReceivingBroadcast(app)) != null) {
14838            // An app that is currently receiving a broadcast also
14839            // counts as being in the foreground for OOM killer purposes.
14840            // It's placed in a sched group based on the nature of the
14841            // broadcast as reflected by which queue it's active in.
14842            adj = ProcessList.FOREGROUND_APP_ADJ;
14843            schedGroup = (queue == mFgBroadcastQueue)
14844                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14845            app.adjType = "broadcast";
14846            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14847        } else if (app.executingServices.size() > 0) {
14848            // An app that is currently executing a service callback also
14849            // counts as being in the foreground.
14850            adj = ProcessList.FOREGROUND_APP_ADJ;
14851            schedGroup = app.execServicesFg ?
14852                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14853            app.adjType = "exec-service";
14854            procState = ActivityManager.PROCESS_STATE_SERVICE;
14855            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14856        } else {
14857            // As far as we know the process is empty.  We may change our mind later.
14858            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14859            // At this point we don't actually know the adjustment.  Use the cached adj
14860            // value that the caller wants us to.
14861            adj = cachedAdj;
14862            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14863            app.cached = true;
14864            app.empty = true;
14865            app.adjType = "cch-empty";
14866        }
14867
14868        // Examine all activities if not already foreground.
14869        if (!foregroundActivities && activitiesSize > 0) {
14870            for (int j = 0; j < activitiesSize; j++) {
14871                final ActivityRecord r = app.activities.get(j);
14872                if (r.app != app) {
14873                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14874                            + app + "?!?");
14875                    continue;
14876                }
14877                if (r.visible) {
14878                    // App has a visible activity; only upgrade adjustment.
14879                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14880                        adj = ProcessList.VISIBLE_APP_ADJ;
14881                        app.adjType = "visible";
14882                    }
14883                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14884                        procState = ActivityManager.PROCESS_STATE_TOP;
14885                    }
14886                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14887                    app.cached = false;
14888                    app.empty = false;
14889                    foregroundActivities = true;
14890                    break;
14891                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14892                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14893                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14894                        app.adjType = "pausing";
14895                    }
14896                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14897                        procState = ActivityManager.PROCESS_STATE_TOP;
14898                    }
14899                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14900                    app.cached = false;
14901                    app.empty = false;
14902                    foregroundActivities = true;
14903                } else if (r.state == ActivityState.STOPPING) {
14904                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14905                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14906                        app.adjType = "stopping";
14907                    }
14908                    // For the process state, we will at this point consider the
14909                    // process to be cached.  It will be cached either as an activity
14910                    // or empty depending on whether the activity is finishing.  We do
14911                    // this so that we can treat the process as cached for purposes of
14912                    // memory trimming (determing current memory level, trim command to
14913                    // send to process) since there can be an arbitrary number of stopping
14914                    // processes and they should soon all go into the cached state.
14915                    if (!r.finishing) {
14916                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14917                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14918                        }
14919                    }
14920                    app.cached = false;
14921                    app.empty = false;
14922                    foregroundActivities = true;
14923                } else {
14924                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14925                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14926                        app.adjType = "cch-act";
14927                    }
14928                }
14929            }
14930        }
14931
14932        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14933            if (app.foregroundServices) {
14934                // The user is aware of this app, so make it visible.
14935                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14936                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14937                app.cached = false;
14938                app.adjType = "fg-service";
14939                schedGroup = Process.THREAD_GROUP_DEFAULT;
14940            } else if (app.forcingToForeground != null) {
14941                // The user is aware of this app, so make it visible.
14942                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14943                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14944                app.cached = false;
14945                app.adjType = "force-fg";
14946                app.adjSource = app.forcingToForeground;
14947                schedGroup = Process.THREAD_GROUP_DEFAULT;
14948            }
14949        }
14950
14951        if (app.foregroundServices) {
14952            interesting = true;
14953        }
14954
14955        if (app == mHeavyWeightProcess) {
14956            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14957                // We don't want to kill the current heavy-weight process.
14958                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14959                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14960                app.cached = false;
14961                app.adjType = "heavy";
14962            }
14963            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14964                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14965            }
14966        }
14967
14968        if (app == mHomeProcess) {
14969            if (adj > ProcessList.HOME_APP_ADJ) {
14970                // This process is hosting what we currently consider to be the
14971                // home app, so we don't want to let it go into the background.
14972                adj = ProcessList.HOME_APP_ADJ;
14973                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14974                app.cached = false;
14975                app.adjType = "home";
14976            }
14977            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14978                procState = ActivityManager.PROCESS_STATE_HOME;
14979            }
14980        }
14981
14982        if (app == mPreviousProcess && app.activities.size() > 0) {
14983            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14984                // This was the previous process that showed UI to the user.
14985                // We want to try to keep it around more aggressively, to give
14986                // a good experience around switching between two apps.
14987                adj = ProcessList.PREVIOUS_APP_ADJ;
14988                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14989                app.cached = false;
14990                app.adjType = "previous";
14991            }
14992            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14993                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14994            }
14995        }
14996
14997        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14998                + " reason=" + app.adjType);
14999
15000        // By default, we use the computed adjustment.  It may be changed if
15001        // there are applications dependent on our services or providers, but
15002        // this gives us a baseline and makes sure we don't get into an
15003        // infinite recursion.
15004        app.adjSeq = mAdjSeq;
15005        app.curRawAdj = adj;
15006        app.hasStartedServices = false;
15007
15008        if (mBackupTarget != null && app == mBackupTarget.app) {
15009            // If possible we want to avoid killing apps while they're being backed up
15010            if (adj > ProcessList.BACKUP_APP_ADJ) {
15011                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15012                adj = ProcessList.BACKUP_APP_ADJ;
15013                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15014                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15015                }
15016                app.adjType = "backup";
15017                app.cached = false;
15018            }
15019            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15020                procState = ActivityManager.PROCESS_STATE_BACKUP;
15021            }
15022        }
15023
15024        boolean mayBeTop = false;
15025
15026        for (int is = app.services.size()-1;
15027                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15028                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15029                        || procState > ActivityManager.PROCESS_STATE_TOP);
15030                is--) {
15031            ServiceRecord s = app.services.valueAt(is);
15032            if (s.startRequested) {
15033                app.hasStartedServices = true;
15034                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15035                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15036                }
15037                if (app.hasShownUi && app != mHomeProcess) {
15038                    // If this process has shown some UI, let it immediately
15039                    // go to the LRU list because it may be pretty heavy with
15040                    // UI stuff.  We'll tag it with a label just to help
15041                    // debug and understand what is going on.
15042                    if (adj > ProcessList.SERVICE_ADJ) {
15043                        app.adjType = "cch-started-ui-services";
15044                    }
15045                } else {
15046                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15047                        // This service has seen some activity within
15048                        // recent memory, so we will keep its process ahead
15049                        // of the background processes.
15050                        if (adj > ProcessList.SERVICE_ADJ) {
15051                            adj = ProcessList.SERVICE_ADJ;
15052                            app.adjType = "started-services";
15053                            app.cached = false;
15054                        }
15055                    }
15056                    // If we have let the service slide into the background
15057                    // state, still have some text describing what it is doing
15058                    // even though the service no longer has an impact.
15059                    if (adj > ProcessList.SERVICE_ADJ) {
15060                        app.adjType = "cch-started-services";
15061                    }
15062                }
15063                // Don't kill this process because it is doing work; it
15064                // has said it is doing work.
15065                app.keeping = true;
15066            }
15067            for (int conni = s.connections.size()-1;
15068                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15069                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15070                            || procState > ActivityManager.PROCESS_STATE_TOP);
15071                    conni--) {
15072                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15073                for (int i = 0;
15074                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15075                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15076                                || procState > ActivityManager.PROCESS_STATE_TOP);
15077                        i++) {
15078                    // XXX should compute this based on the max of
15079                    // all connected clients.
15080                    ConnectionRecord cr = clist.get(i);
15081                    if (cr.binding.client == app) {
15082                        // Binding to ourself is not interesting.
15083                        continue;
15084                    }
15085                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15086                        ProcessRecord client = cr.binding.client;
15087                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15088                                TOP_APP, doingAll, now);
15089                        int clientProcState = client.curProcState;
15090                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15091                            // If the other app is cached for any reason, for purposes here
15092                            // we are going to consider it empty.  The specific cached state
15093                            // doesn't propagate except under certain conditions.
15094                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15095                        }
15096                        String adjType = null;
15097                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15098                            // Not doing bind OOM management, so treat
15099                            // this guy more like a started service.
15100                            if (app.hasShownUi && app != mHomeProcess) {
15101                                // If this process has shown some UI, let it immediately
15102                                // go to the LRU list because it may be pretty heavy with
15103                                // UI stuff.  We'll tag it with a label just to help
15104                                // debug and understand what is going on.
15105                                if (adj > clientAdj) {
15106                                    adjType = "cch-bound-ui-services";
15107                                }
15108                                app.cached = false;
15109                                clientAdj = adj;
15110                                clientProcState = procState;
15111                            } else {
15112                                if (now >= (s.lastActivity
15113                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15114                                    // This service has not seen activity within
15115                                    // recent memory, so allow it to drop to the
15116                                    // LRU list if there is no other reason to keep
15117                                    // it around.  We'll also tag it with a label just
15118                                    // to help debug and undertand what is going on.
15119                                    if (adj > clientAdj) {
15120                                        adjType = "cch-bound-services";
15121                                    }
15122                                    clientAdj = adj;
15123                                }
15124                            }
15125                        }
15126                        if (adj > clientAdj) {
15127                            // If this process has recently shown UI, and
15128                            // the process that is binding to it is less
15129                            // important than being visible, then we don't
15130                            // care about the binding as much as we care
15131                            // about letting this process get into the LRU
15132                            // list to be killed and restarted if needed for
15133                            // memory.
15134                            if (app.hasShownUi && app != mHomeProcess
15135                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15136                                adjType = "cch-bound-ui-services";
15137                            } else {
15138                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15139                                        |Context.BIND_IMPORTANT)) != 0) {
15140                                    adj = clientAdj;
15141                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15142                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15143                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15144                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15145                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15146                                    adj = clientAdj;
15147                                } else {
15148                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15149                                        adj = ProcessList.VISIBLE_APP_ADJ;
15150                                    }
15151                                }
15152                                if (!client.cached) {
15153                                    app.cached = false;
15154                                }
15155                                if (client.keeping) {
15156                                    app.keeping = true;
15157                                }
15158                                adjType = "service";
15159                            }
15160                        }
15161                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15162                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15163                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15164                            }
15165                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15166                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15167                                    // Special handling of clients who are in the top state.
15168                                    // We *may* want to consider this process to be in the
15169                                    // top state as well, but only if there is not another
15170                                    // reason for it to be running.  Being on the top is a
15171                                    // special state, meaning you are specifically running
15172                                    // for the current top app.  If the process is already
15173                                    // running in the background for some other reason, it
15174                                    // is more important to continue considering it to be
15175                                    // in the background state.
15176                                    mayBeTop = true;
15177                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15178                                } else {
15179                                    // Special handling for above-top states (persistent
15180                                    // processes).  These should not bring the current process
15181                                    // into the top state, since they are not on top.  Instead
15182                                    // give them the best state after that.
15183                                    clientProcState =
15184                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15185                                }
15186                            }
15187                        } else {
15188                            if (clientProcState <
15189                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15190                                clientProcState =
15191                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15192                            }
15193                        }
15194                        if (procState > clientProcState) {
15195                            procState = clientProcState;
15196                        }
15197                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15198                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15199                            app.pendingUiClean = true;
15200                        }
15201                        if (adjType != null) {
15202                            app.adjType = adjType;
15203                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15204                                    .REASON_SERVICE_IN_USE;
15205                            app.adjSource = cr.binding.client;
15206                            app.adjSourceOom = clientAdj;
15207                            app.adjTarget = s.name;
15208                        }
15209                    }
15210                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15211                        app.treatLikeActivity = true;
15212                    }
15213                    final ActivityRecord a = cr.activity;
15214                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15215                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15216                                (a.visible || a.state == ActivityState.RESUMED
15217                                 || a.state == ActivityState.PAUSING)) {
15218                            adj = ProcessList.FOREGROUND_APP_ADJ;
15219                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15220                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15221                            }
15222                            app.cached = false;
15223                            app.adjType = "service";
15224                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15225                                    .REASON_SERVICE_IN_USE;
15226                            app.adjSource = a;
15227                            app.adjSourceOom = adj;
15228                            app.adjTarget = s.name;
15229                        }
15230                    }
15231                }
15232            }
15233        }
15234
15235        for (int provi = app.pubProviders.size()-1;
15236                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15237                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15238                        || procState > ActivityManager.PROCESS_STATE_TOP);
15239                provi--) {
15240            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15241            for (int i = cpr.connections.size()-1;
15242                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15243                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15244                            || procState > ActivityManager.PROCESS_STATE_TOP);
15245                    i--) {
15246                ContentProviderConnection conn = cpr.connections.get(i);
15247                ProcessRecord client = conn.client;
15248                if (client == app) {
15249                    // Being our own client is not interesting.
15250                    continue;
15251                }
15252                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15253                int clientProcState = client.curProcState;
15254                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15255                    // If the other app is cached for any reason, for purposes here
15256                    // we are going to consider it empty.
15257                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15258                }
15259                if (adj > clientAdj) {
15260                    if (app.hasShownUi && app != mHomeProcess
15261                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15262                        app.adjType = "cch-ui-provider";
15263                    } else {
15264                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15265                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15266                        app.adjType = "provider";
15267                    }
15268                    app.cached &= client.cached;
15269                    app.keeping |= client.keeping;
15270                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15271                            .REASON_PROVIDER_IN_USE;
15272                    app.adjSource = client;
15273                    app.adjSourceOom = clientAdj;
15274                    app.adjTarget = cpr.name;
15275                }
15276                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15277                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15278                        // Special handling of clients who are in the top state.
15279                        // We *may* want to consider this process to be in the
15280                        // top state as well, but only if there is not another
15281                        // reason for it to be running.  Being on the top is a
15282                        // special state, meaning you are specifically running
15283                        // for the current top app.  If the process is already
15284                        // running in the background for some other reason, it
15285                        // is more important to continue considering it to be
15286                        // in the background state.
15287                        mayBeTop = true;
15288                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15289                    } else {
15290                        // Special handling for above-top states (persistent
15291                        // processes).  These should not bring the current process
15292                        // into the top state, since they are not on top.  Instead
15293                        // give them the best state after that.
15294                        clientProcState =
15295                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15296                    }
15297                }
15298                if (procState > clientProcState) {
15299                    procState = clientProcState;
15300                }
15301                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15302                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15303                }
15304            }
15305            // If the provider has external (non-framework) process
15306            // dependencies, ensure that its adjustment is at least
15307            // FOREGROUND_APP_ADJ.
15308            if (cpr.hasExternalProcessHandles()) {
15309                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15310                    adj = ProcessList.FOREGROUND_APP_ADJ;
15311                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15312                    app.cached = false;
15313                    app.keeping = true;
15314                    app.adjType = "provider";
15315                    app.adjTarget = cpr.name;
15316                }
15317                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15318                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15319                }
15320            }
15321        }
15322
15323        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15324            // A client of one of our services or providers is in the top state.  We
15325            // *may* want to be in the top state, but not if we are already running in
15326            // the background for some other reason.  For the decision here, we are going
15327            // to pick out a few specific states that we want to remain in when a client
15328            // is top (states that tend to be longer-term) and otherwise allow it to go
15329            // to the top state.
15330            switch (procState) {
15331                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15332                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15333                case ActivityManager.PROCESS_STATE_SERVICE:
15334                    // These all are longer-term states, so pull them up to the top
15335                    // of the background states, but not all the way to the top state.
15336                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15337                    break;
15338                default:
15339                    // Otherwise, top is a better choice, so take it.
15340                    procState = ActivityManager.PROCESS_STATE_TOP;
15341                    break;
15342            }
15343        }
15344
15345        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15346            if (app.hasClientActivities) {
15347                // This is a cached process, but with client activities.  Mark it so.
15348                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15349                app.adjType = "cch-client-act";
15350            } else if (app.treatLikeActivity) {
15351                // This is a cached process, but somebody wants us to treat it like it has
15352                // an activity, okay!
15353                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15354                app.adjType = "cch-as-act";
15355            }
15356        }
15357
15358        if (adj == ProcessList.SERVICE_ADJ) {
15359            if (doingAll) {
15360                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15361                mNewNumServiceProcs++;
15362                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15363                if (!app.serviceb) {
15364                    // This service isn't far enough down on the LRU list to
15365                    // normally be a B service, but if we are low on RAM and it
15366                    // is large we want to force it down since we would prefer to
15367                    // keep launcher over it.
15368                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15369                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15370                        app.serviceHighRam = true;
15371                        app.serviceb = true;
15372                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15373                    } else {
15374                        mNewNumAServiceProcs++;
15375                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15376                    }
15377                } else {
15378                    app.serviceHighRam = false;
15379                }
15380            }
15381            if (app.serviceb) {
15382                adj = ProcessList.SERVICE_B_ADJ;
15383            }
15384        }
15385
15386        app.curRawAdj = adj;
15387
15388        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15389        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15390        if (adj > app.maxAdj) {
15391            adj = app.maxAdj;
15392            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15393                schedGroup = Process.THREAD_GROUP_DEFAULT;
15394            }
15395        }
15396        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15397            app.keeping = true;
15398        }
15399
15400        // Do final modification to adj.  Everything we do between here and applying
15401        // the final setAdj must be done in this function, because we will also use
15402        // it when computing the final cached adj later.  Note that we don't need to
15403        // worry about this for max adj above, since max adj will always be used to
15404        // keep it out of the cached vaues.
15405        app.curAdj = app.modifyRawOomAdj(adj);
15406        app.curSchedGroup = schedGroup;
15407        app.curProcState = procState;
15408        app.foregroundActivities = foregroundActivities;
15409
15410        return app.curRawAdj;
15411    }
15412
15413    /**
15414     * Schedule PSS collection of a process.
15415     */
15416    void requestPssLocked(ProcessRecord proc, int procState) {
15417        if (mPendingPssProcesses.contains(proc)) {
15418            return;
15419        }
15420        if (mPendingPssProcesses.size() == 0) {
15421            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15422        }
15423        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15424        proc.pssProcState = procState;
15425        mPendingPssProcesses.add(proc);
15426    }
15427
15428    /**
15429     * Schedule PSS collection of all processes.
15430     */
15431    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15432        if (!always) {
15433            if (now < (mLastFullPssTime +
15434                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15435                return;
15436            }
15437        }
15438        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15439        mLastFullPssTime = now;
15440        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15441        mPendingPssProcesses.clear();
15442        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15443            ProcessRecord app = mLruProcesses.get(i);
15444            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15445                app.pssProcState = app.setProcState;
15446                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15447                        isSleeping(), now);
15448                mPendingPssProcesses.add(app);
15449            }
15450        }
15451        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15452    }
15453
15454    /**
15455     * Ask a given process to GC right now.
15456     */
15457    final void performAppGcLocked(ProcessRecord app) {
15458        try {
15459            app.lastRequestedGc = SystemClock.uptimeMillis();
15460            if (app.thread != null) {
15461                if (app.reportLowMemory) {
15462                    app.reportLowMemory = false;
15463                    app.thread.scheduleLowMemory();
15464                } else {
15465                    app.thread.processInBackground();
15466                }
15467            }
15468        } catch (Exception e) {
15469            // whatever.
15470        }
15471    }
15472
15473    /**
15474     * Returns true if things are idle enough to perform GCs.
15475     */
15476    private final boolean canGcNowLocked() {
15477        boolean processingBroadcasts = false;
15478        for (BroadcastQueue q : mBroadcastQueues) {
15479            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15480                processingBroadcasts = true;
15481            }
15482        }
15483        return !processingBroadcasts
15484                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15485    }
15486
15487    /**
15488     * Perform GCs on all processes that are waiting for it, but only
15489     * if things are idle.
15490     */
15491    final void performAppGcsLocked() {
15492        final int N = mProcessesToGc.size();
15493        if (N <= 0) {
15494            return;
15495        }
15496        if (canGcNowLocked()) {
15497            while (mProcessesToGc.size() > 0) {
15498                ProcessRecord proc = mProcessesToGc.remove(0);
15499                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15500                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15501                            <= SystemClock.uptimeMillis()) {
15502                        // To avoid spamming the system, we will GC processes one
15503                        // at a time, waiting a few seconds between each.
15504                        performAppGcLocked(proc);
15505                        scheduleAppGcsLocked();
15506                        return;
15507                    } else {
15508                        // It hasn't been long enough since we last GCed this
15509                        // process...  put it in the list to wait for its time.
15510                        addProcessToGcListLocked(proc);
15511                        break;
15512                    }
15513                }
15514            }
15515
15516            scheduleAppGcsLocked();
15517        }
15518    }
15519
15520    /**
15521     * If all looks good, perform GCs on all processes waiting for them.
15522     */
15523    final void performAppGcsIfAppropriateLocked() {
15524        if (canGcNowLocked()) {
15525            performAppGcsLocked();
15526            return;
15527        }
15528        // Still not idle, wait some more.
15529        scheduleAppGcsLocked();
15530    }
15531
15532    /**
15533     * Schedule the execution of all pending app GCs.
15534     */
15535    final void scheduleAppGcsLocked() {
15536        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15537
15538        if (mProcessesToGc.size() > 0) {
15539            // Schedule a GC for the time to the next process.
15540            ProcessRecord proc = mProcessesToGc.get(0);
15541            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15542
15543            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15544            long now = SystemClock.uptimeMillis();
15545            if (when < (now+GC_TIMEOUT)) {
15546                when = now + GC_TIMEOUT;
15547            }
15548            mHandler.sendMessageAtTime(msg, when);
15549        }
15550    }
15551
15552    /**
15553     * Add a process to the array of processes waiting to be GCed.  Keeps the
15554     * list in sorted order by the last GC time.  The process can't already be
15555     * on the list.
15556     */
15557    final void addProcessToGcListLocked(ProcessRecord proc) {
15558        boolean added = false;
15559        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15560            if (mProcessesToGc.get(i).lastRequestedGc <
15561                    proc.lastRequestedGc) {
15562                added = true;
15563                mProcessesToGc.add(i+1, proc);
15564                break;
15565            }
15566        }
15567        if (!added) {
15568            mProcessesToGc.add(0, proc);
15569        }
15570    }
15571
15572    /**
15573     * Set up to ask a process to GC itself.  This will either do it
15574     * immediately, or put it on the list of processes to gc the next
15575     * time things are idle.
15576     */
15577    final void scheduleAppGcLocked(ProcessRecord app) {
15578        long now = SystemClock.uptimeMillis();
15579        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15580            return;
15581        }
15582        if (!mProcessesToGc.contains(app)) {
15583            addProcessToGcListLocked(app);
15584            scheduleAppGcsLocked();
15585        }
15586    }
15587
15588    final void checkExcessivePowerUsageLocked(boolean doKills) {
15589        updateCpuStatsNow();
15590
15591        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15592        boolean doWakeKills = doKills;
15593        boolean doCpuKills = doKills;
15594        if (mLastPowerCheckRealtime == 0) {
15595            doWakeKills = false;
15596        }
15597        if (mLastPowerCheckUptime == 0) {
15598            doCpuKills = false;
15599        }
15600        if (stats.isScreenOn()) {
15601            doWakeKills = false;
15602        }
15603        final long curRealtime = SystemClock.elapsedRealtime();
15604        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15605        final long curUptime = SystemClock.uptimeMillis();
15606        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15607        mLastPowerCheckRealtime = curRealtime;
15608        mLastPowerCheckUptime = curUptime;
15609        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15610            doWakeKills = false;
15611        }
15612        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15613            doCpuKills = false;
15614        }
15615        int i = mLruProcesses.size();
15616        while (i > 0) {
15617            i--;
15618            ProcessRecord app = mLruProcesses.get(i);
15619            if (!app.keeping) {
15620                long wtime;
15621                synchronized (stats) {
15622                    wtime = stats.getProcessWakeTime(app.info.uid,
15623                            app.pid, curRealtime);
15624                }
15625                long wtimeUsed = wtime - app.lastWakeTime;
15626                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15627                if (DEBUG_POWER) {
15628                    StringBuilder sb = new StringBuilder(128);
15629                    sb.append("Wake for ");
15630                    app.toShortString(sb);
15631                    sb.append(": over ");
15632                    TimeUtils.formatDuration(realtimeSince, sb);
15633                    sb.append(" used ");
15634                    TimeUtils.formatDuration(wtimeUsed, sb);
15635                    sb.append(" (");
15636                    sb.append((wtimeUsed*100)/realtimeSince);
15637                    sb.append("%)");
15638                    Slog.i(TAG, sb.toString());
15639                    sb.setLength(0);
15640                    sb.append("CPU for ");
15641                    app.toShortString(sb);
15642                    sb.append(": over ");
15643                    TimeUtils.formatDuration(uptimeSince, sb);
15644                    sb.append(" used ");
15645                    TimeUtils.formatDuration(cputimeUsed, sb);
15646                    sb.append(" (");
15647                    sb.append((cputimeUsed*100)/uptimeSince);
15648                    sb.append("%)");
15649                    Slog.i(TAG, sb.toString());
15650                }
15651                // If a process has held a wake lock for more
15652                // than 50% of the time during this period,
15653                // that sounds bad.  Kill!
15654                if (doWakeKills && realtimeSince > 0
15655                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15656                    synchronized (stats) {
15657                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15658                                realtimeSince, wtimeUsed);
15659                    }
15660                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15661                            + " during " + realtimeSince);
15662                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15663                } else if (doCpuKills && uptimeSince > 0
15664                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15665                    synchronized (stats) {
15666                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15667                                uptimeSince, cputimeUsed);
15668                    }
15669                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15670                            + " during " + uptimeSince);
15671                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15672                } else {
15673                    app.lastWakeTime = wtime;
15674                    app.lastCpuTime = app.curCpuTime;
15675                }
15676            }
15677        }
15678    }
15679
15680    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15681            ProcessRecord TOP_APP, boolean doingAll, long now) {
15682        boolean success = true;
15683
15684        if (app.curRawAdj != app.setRawAdj) {
15685            if (wasKeeping && !app.keeping) {
15686                // This app is no longer something we want to keep.  Note
15687                // its current wake lock time to later know to kill it if
15688                // it is not behaving well.
15689                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15690                synchronized (stats) {
15691                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15692                            app.pid, SystemClock.elapsedRealtime());
15693                }
15694                app.lastCpuTime = app.curCpuTime;
15695            }
15696
15697            app.setRawAdj = app.curRawAdj;
15698        }
15699
15700        int changes = 0;
15701
15702        if (app.curAdj != app.setAdj) {
15703            ProcessList.setOomAdj(app.pid, app.curAdj);
15704            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15705                TAG, "Set " + app.pid + " " + app.processName +
15706                " adj " + app.curAdj + ": " + app.adjType);
15707            app.setAdj = app.curAdj;
15708        }
15709
15710        if (app.setSchedGroup != app.curSchedGroup) {
15711            app.setSchedGroup = app.curSchedGroup;
15712            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15713                    "Setting process group of " + app.processName
15714                    + " to " + app.curSchedGroup);
15715            if (app.waitingToKill != null &&
15716                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15717                killUnneededProcessLocked(app, app.waitingToKill);
15718                success = false;
15719            } else {
15720                if (true) {
15721                    long oldId = Binder.clearCallingIdentity();
15722                    try {
15723                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15724                    } catch (Exception e) {
15725                        Slog.w(TAG, "Failed setting process group of " + app.pid
15726                                + " to " + app.curSchedGroup);
15727                        e.printStackTrace();
15728                    } finally {
15729                        Binder.restoreCallingIdentity(oldId);
15730                    }
15731                } else {
15732                    if (app.thread != null) {
15733                        try {
15734                            app.thread.setSchedulingGroup(app.curSchedGroup);
15735                        } catch (RemoteException e) {
15736                        }
15737                    }
15738                }
15739                Process.setSwappiness(app.pid,
15740                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15741            }
15742        }
15743        if (app.repForegroundActivities != app.foregroundActivities) {
15744            app.repForegroundActivities = app.foregroundActivities;
15745            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15746        }
15747        if (app.repProcState != app.curProcState) {
15748            app.repProcState = app.curProcState;
15749            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15750            if (app.thread != null) {
15751                try {
15752                    if (false) {
15753                        //RuntimeException h = new RuntimeException("here");
15754                        Slog.i(TAG, "Sending new process state " + app.repProcState
15755                                + " to " + app /*, h*/);
15756                    }
15757                    app.thread.setProcessState(app.repProcState);
15758                } catch (RemoteException e) {
15759                }
15760            }
15761        }
15762        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15763                app.setProcState)) {
15764            app.lastStateTime = now;
15765            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15766                    isSleeping(), now);
15767            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15768                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15769                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15770                    + (app.nextPssTime-now) + ": " + app);
15771        } else {
15772            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15773                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15774                requestPssLocked(app, app.setProcState);
15775                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15776                        isSleeping(), now);
15777            } else if (false && DEBUG_PSS) {
15778                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15779            }
15780        }
15781        if (app.setProcState != app.curProcState) {
15782            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15783                    "Proc state change of " + app.processName
15784                    + " to " + app.curProcState);
15785            app.setProcState = app.curProcState;
15786            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15787                app.notCachedSinceIdle = false;
15788            }
15789            if (!doingAll) {
15790                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15791            } else {
15792                app.procStateChanged = true;
15793            }
15794        }
15795
15796        if (changes != 0) {
15797            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15798            int i = mPendingProcessChanges.size()-1;
15799            ProcessChangeItem item = null;
15800            while (i >= 0) {
15801                item = mPendingProcessChanges.get(i);
15802                if (item.pid == app.pid) {
15803                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15804                    break;
15805                }
15806                i--;
15807            }
15808            if (i < 0) {
15809                // No existing item in pending changes; need a new one.
15810                final int NA = mAvailProcessChanges.size();
15811                if (NA > 0) {
15812                    item = mAvailProcessChanges.remove(NA-1);
15813                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15814                } else {
15815                    item = new ProcessChangeItem();
15816                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15817                }
15818                item.changes = 0;
15819                item.pid = app.pid;
15820                item.uid = app.info.uid;
15821                if (mPendingProcessChanges.size() == 0) {
15822                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15823                            "*** Enqueueing dispatch processes changed!");
15824                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15825                }
15826                mPendingProcessChanges.add(item);
15827            }
15828            item.changes |= changes;
15829            item.processState = app.repProcState;
15830            item.foregroundActivities = app.repForegroundActivities;
15831            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15832                    + Integer.toHexString(System.identityHashCode(item))
15833                    + " " + app.toShortString() + ": changes=" + item.changes
15834                    + " procState=" + item.processState
15835                    + " foreground=" + item.foregroundActivities
15836                    + " type=" + app.adjType + " source=" + app.adjSource
15837                    + " target=" + app.adjTarget);
15838        }
15839
15840        return success;
15841    }
15842
15843    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15844        if (proc.thread != null && proc.baseProcessTracker != null) {
15845            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15846        }
15847    }
15848
15849    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15850            ProcessRecord TOP_APP, boolean doingAll, long now) {
15851        if (app.thread == null) {
15852            return false;
15853        }
15854
15855        final boolean wasKeeping = app.keeping;
15856
15857        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15858
15859        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15860    }
15861
15862    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15863            boolean oomAdj) {
15864        if (isForeground != proc.foregroundServices) {
15865            proc.foregroundServices = isForeground;
15866            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15867                    proc.info.uid);
15868            if (isForeground) {
15869                if (curProcs == null) {
15870                    curProcs = new ArrayList<ProcessRecord>();
15871                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15872                }
15873                if (!curProcs.contains(proc)) {
15874                    curProcs.add(proc);
15875                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15876                            proc.info.packageName, proc.info.uid);
15877                }
15878            } else {
15879                if (curProcs != null) {
15880                    if (curProcs.remove(proc)) {
15881                        mBatteryStatsService.noteEvent(
15882                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15883                                proc.info.packageName, proc.info.uid);
15884                        if (curProcs.size() <= 0) {
15885                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15886                        }
15887                    }
15888                }
15889            }
15890            if (oomAdj) {
15891                updateOomAdjLocked();
15892            }
15893        }
15894    }
15895
15896    private final ActivityRecord resumedAppLocked() {
15897        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15898        String pkg;
15899        int uid;
15900        if (act != null && !act.sleeping) {
15901            pkg = act.packageName;
15902            uid = act.info.applicationInfo.uid;
15903        } else {
15904            pkg = null;
15905            uid = -1;
15906        }
15907        // Has the UID or resumed package name changed?
15908        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15909                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15910            if (mCurResumedPackage != null) {
15911                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15912                        mCurResumedPackage, mCurResumedUid);
15913            }
15914            mCurResumedPackage = pkg;
15915            mCurResumedUid = uid;
15916            if (mCurResumedPackage != null) {
15917                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15918                        mCurResumedPackage, mCurResumedUid);
15919            }
15920        }
15921        return act;
15922    }
15923
15924    final boolean updateOomAdjLocked(ProcessRecord app) {
15925        final ActivityRecord TOP_ACT = resumedAppLocked();
15926        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15927        final boolean wasCached = app.cached;
15928
15929        mAdjSeq++;
15930
15931        // This is the desired cached adjusment we want to tell it to use.
15932        // If our app is currently cached, we know it, and that is it.  Otherwise,
15933        // we don't know it yet, and it needs to now be cached we will then
15934        // need to do a complete oom adj.
15935        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15936                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15937        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15938                SystemClock.uptimeMillis());
15939        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15940            // Changed to/from cached state, so apps after it in the LRU
15941            // list may also be changed.
15942            updateOomAdjLocked();
15943        }
15944        return success;
15945    }
15946
15947    final void updateOomAdjLocked() {
15948        final ActivityRecord TOP_ACT = resumedAppLocked();
15949        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15950        final long now = SystemClock.uptimeMillis();
15951        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15952        final int N = mLruProcesses.size();
15953
15954        if (false) {
15955            RuntimeException e = new RuntimeException();
15956            e.fillInStackTrace();
15957            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15958        }
15959
15960        mAdjSeq++;
15961        mNewNumServiceProcs = 0;
15962        mNewNumAServiceProcs = 0;
15963
15964        final int emptyProcessLimit;
15965        final int cachedProcessLimit;
15966        if (mProcessLimit <= 0) {
15967            emptyProcessLimit = cachedProcessLimit = 0;
15968        } else if (mProcessLimit == 1) {
15969            emptyProcessLimit = 1;
15970            cachedProcessLimit = 0;
15971        } else {
15972            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15973            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15974        }
15975
15976        // Let's determine how many processes we have running vs.
15977        // how many slots we have for background processes; we may want
15978        // to put multiple processes in a slot of there are enough of
15979        // them.
15980        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15981                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15982        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15983        if (numEmptyProcs > cachedProcessLimit) {
15984            // If there are more empty processes than our limit on cached
15985            // processes, then use the cached process limit for the factor.
15986            // This ensures that the really old empty processes get pushed
15987            // down to the bottom, so if we are running low on memory we will
15988            // have a better chance at keeping around more cached processes
15989            // instead of a gazillion empty processes.
15990            numEmptyProcs = cachedProcessLimit;
15991        }
15992        int emptyFactor = numEmptyProcs/numSlots;
15993        if (emptyFactor < 1) emptyFactor = 1;
15994        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15995        if (cachedFactor < 1) cachedFactor = 1;
15996        int stepCached = 0;
15997        int stepEmpty = 0;
15998        int numCached = 0;
15999        int numEmpty = 0;
16000        int numTrimming = 0;
16001
16002        mNumNonCachedProcs = 0;
16003        mNumCachedHiddenProcs = 0;
16004
16005        // First update the OOM adjustment for each of the
16006        // application processes based on their current state.
16007        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16008        int nextCachedAdj = curCachedAdj+1;
16009        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16010        int nextEmptyAdj = curEmptyAdj+2;
16011        for (int i=N-1; i>=0; i--) {
16012            ProcessRecord app = mLruProcesses.get(i);
16013            if (!app.killedByAm && app.thread != null) {
16014                app.procStateChanged = false;
16015                final boolean wasKeeping = app.keeping;
16016                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16017
16018                // If we haven't yet assigned the final cached adj
16019                // to the process, do that now.
16020                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16021                    switch (app.curProcState) {
16022                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16023                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16024                            // This process is a cached process holding activities...
16025                            // assign it the next cached value for that type, and then
16026                            // step that cached level.
16027                            app.curRawAdj = curCachedAdj;
16028                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16029                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16030                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16031                                    + ")");
16032                            if (curCachedAdj != nextCachedAdj) {
16033                                stepCached++;
16034                                if (stepCached >= cachedFactor) {
16035                                    stepCached = 0;
16036                                    curCachedAdj = nextCachedAdj;
16037                                    nextCachedAdj += 2;
16038                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16039                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16040                                    }
16041                                }
16042                            }
16043                            break;
16044                        default:
16045                            // For everything else, assign next empty cached process
16046                            // level and bump that up.  Note that this means that
16047                            // long-running services that have dropped down to the
16048                            // cached level will be treated as empty (since their process
16049                            // state is still as a service), which is what we want.
16050                            app.curRawAdj = curEmptyAdj;
16051                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16052                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16053                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16054                                    + ")");
16055                            if (curEmptyAdj != nextEmptyAdj) {
16056                                stepEmpty++;
16057                                if (stepEmpty >= emptyFactor) {
16058                                    stepEmpty = 0;
16059                                    curEmptyAdj = nextEmptyAdj;
16060                                    nextEmptyAdj += 2;
16061                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16062                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16063                                    }
16064                                }
16065                            }
16066                            break;
16067                    }
16068                }
16069
16070                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16071
16072                // Count the number of process types.
16073                switch (app.curProcState) {
16074                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16075                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16076                        mNumCachedHiddenProcs++;
16077                        numCached++;
16078                        if (numCached > cachedProcessLimit) {
16079                            killUnneededProcessLocked(app, "cached #" + numCached);
16080                        }
16081                        break;
16082                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16083                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16084                                && app.lastActivityTime < oldTime) {
16085                            killUnneededProcessLocked(app, "empty for "
16086                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16087                                    / 1000) + "s");
16088                        } else {
16089                            numEmpty++;
16090                            if (numEmpty > emptyProcessLimit) {
16091                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16092                            }
16093                        }
16094                        break;
16095                    default:
16096                        mNumNonCachedProcs++;
16097                        break;
16098                }
16099
16100                if (app.isolated && app.services.size() <= 0) {
16101                    // If this is an isolated process, and there are no
16102                    // services running in it, then the process is no longer
16103                    // needed.  We agressively kill these because we can by
16104                    // definition not re-use the same process again, and it is
16105                    // good to avoid having whatever code was running in them
16106                    // left sitting around after no longer needed.
16107                    killUnneededProcessLocked(app, "isolated not needed");
16108                }
16109
16110                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16111                        && !app.killedByAm) {
16112                    numTrimming++;
16113                }
16114            }
16115        }
16116
16117        mNumServiceProcs = mNewNumServiceProcs;
16118
16119        // Now determine the memory trimming level of background processes.
16120        // Unfortunately we need to start at the back of the list to do this
16121        // properly.  We only do this if the number of background apps we
16122        // are managing to keep around is less than half the maximum we desire;
16123        // if we are keeping a good number around, we'll let them use whatever
16124        // memory they want.
16125        final int numCachedAndEmpty = numCached + numEmpty;
16126        int memFactor;
16127        if (numCached <= ProcessList.TRIM_CACHED_APPS
16128                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16129            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16130                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16131            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16132                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16133            } else {
16134                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16135            }
16136        } else {
16137            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16138        }
16139        // We always allow the memory level to go up (better).  We only allow it to go
16140        // down if we are in a state where that is allowed, *and* the total number of processes
16141        // has gone down since last time.
16142        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16143                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16144                + " last=" + mLastNumProcesses);
16145        if (memFactor > mLastMemoryLevel) {
16146            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16147                memFactor = mLastMemoryLevel;
16148                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16149            }
16150        }
16151        mLastMemoryLevel = memFactor;
16152        mLastNumProcesses = mLruProcesses.size();
16153        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16154        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16155        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16156            if (mLowRamStartTime == 0) {
16157                mLowRamStartTime = now;
16158            }
16159            int step = 0;
16160            int fgTrimLevel;
16161            switch (memFactor) {
16162                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16163                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16164                    break;
16165                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16166                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16167                    break;
16168                default:
16169                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16170                    break;
16171            }
16172            int factor = numTrimming/3;
16173            int minFactor = 2;
16174            if (mHomeProcess != null) minFactor++;
16175            if (mPreviousProcess != null) minFactor++;
16176            if (factor < minFactor) factor = minFactor;
16177            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16178            for (int i=N-1; i>=0; i--) {
16179                ProcessRecord app = mLruProcesses.get(i);
16180                if (allChanged || app.procStateChanged) {
16181                    setProcessTrackerState(app, trackerMemFactor, now);
16182                    app.procStateChanged = false;
16183                }
16184                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16185                        && !app.killedByAm) {
16186                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16187                        try {
16188                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16189                                    "Trimming memory of " + app.processName
16190                                    + " to " + curLevel);
16191                            app.thread.scheduleTrimMemory(curLevel);
16192                        } catch (RemoteException e) {
16193                        }
16194                        if (false) {
16195                            // For now we won't do this; our memory trimming seems
16196                            // to be good enough at this point that destroying
16197                            // activities causes more harm than good.
16198                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16199                                    && app != mHomeProcess && app != mPreviousProcess) {
16200                                // Need to do this on its own message because the stack may not
16201                                // be in a consistent state at this point.
16202                                // For these apps we will also finish their activities
16203                                // to help them free memory.
16204                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16205                            }
16206                        }
16207                    }
16208                    app.trimMemoryLevel = curLevel;
16209                    step++;
16210                    if (step >= factor) {
16211                        step = 0;
16212                        switch (curLevel) {
16213                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16214                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16215                                break;
16216                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16217                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16218                                break;
16219                        }
16220                    }
16221                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16222                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16223                            && app.thread != null) {
16224                        try {
16225                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16226                                    "Trimming memory of heavy-weight " + app.processName
16227                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16228                            app.thread.scheduleTrimMemory(
16229                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16230                        } catch (RemoteException e) {
16231                        }
16232                    }
16233                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16234                } else {
16235                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16236                            || app.systemNoUi) && app.pendingUiClean) {
16237                        // If this application is now in the background and it
16238                        // had done UI, then give it the special trim level to
16239                        // have it free UI resources.
16240                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16241                        if (app.trimMemoryLevel < level && app.thread != null) {
16242                            try {
16243                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16244                                        "Trimming memory of bg-ui " + app.processName
16245                                        + " to " + level);
16246                                app.thread.scheduleTrimMemory(level);
16247                            } catch (RemoteException e) {
16248                            }
16249                        }
16250                        app.pendingUiClean = false;
16251                    }
16252                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16253                        try {
16254                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16255                                    "Trimming memory of fg " + app.processName
16256                                    + " to " + fgTrimLevel);
16257                            app.thread.scheduleTrimMemory(fgTrimLevel);
16258                        } catch (RemoteException e) {
16259                        }
16260                    }
16261                    app.trimMemoryLevel = fgTrimLevel;
16262                }
16263            }
16264        } else {
16265            if (mLowRamStartTime != 0) {
16266                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16267                mLowRamStartTime = 0;
16268            }
16269            for (int i=N-1; i>=0; i--) {
16270                ProcessRecord app = mLruProcesses.get(i);
16271                if (allChanged || app.procStateChanged) {
16272                    setProcessTrackerState(app, trackerMemFactor, now);
16273                    app.procStateChanged = false;
16274                }
16275                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16276                        || app.systemNoUi) && app.pendingUiClean) {
16277                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16278                            && app.thread != null) {
16279                        try {
16280                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16281                                    "Trimming memory of ui hidden " + app.processName
16282                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16283                            app.thread.scheduleTrimMemory(
16284                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16285                        } catch (RemoteException e) {
16286                        }
16287                    }
16288                    app.pendingUiClean = false;
16289                }
16290                app.trimMemoryLevel = 0;
16291            }
16292        }
16293
16294        if (mAlwaysFinishActivities) {
16295            // Need to do this on its own message because the stack may not
16296            // be in a consistent state at this point.
16297            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16298        }
16299
16300        if (allChanged) {
16301            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16302        }
16303
16304        if (mProcessStats.shouldWriteNowLocked(now)) {
16305            mHandler.post(new Runnable() {
16306                @Override public void run() {
16307                    synchronized (ActivityManagerService.this) {
16308                        mProcessStats.writeStateAsyncLocked();
16309                    }
16310                }
16311            });
16312        }
16313
16314        if (DEBUG_OOM_ADJ) {
16315            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16316        }
16317    }
16318
16319    final void trimApplications() {
16320        synchronized (this) {
16321            int i;
16322
16323            // First remove any unused application processes whose package
16324            // has been removed.
16325            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16326                final ProcessRecord app = mRemovedProcesses.get(i);
16327                if (app.activities.size() == 0
16328                        && app.curReceiver == null && app.services.size() == 0) {
16329                    Slog.i(
16330                        TAG, "Exiting empty application process "
16331                        + app.processName + " ("
16332                        + (app.thread != null ? app.thread.asBinder() : null)
16333                        + ")\n");
16334                    if (app.pid > 0 && app.pid != MY_PID) {
16335                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16336                                app.processName, app.setAdj, "empty");
16337                        app.killedByAm = true;
16338                        Process.killProcessQuiet(app.pid);
16339                    } else {
16340                        try {
16341                            app.thread.scheduleExit();
16342                        } catch (Exception e) {
16343                            // Ignore exceptions.
16344                        }
16345                    }
16346                    cleanUpApplicationRecordLocked(app, false, true, -1);
16347                    mRemovedProcesses.remove(i);
16348
16349                    if (app.persistent) {
16350                        if (app.persistent) {
16351                            addAppLocked(app.info, false, null /* ABI override */);
16352                        }
16353                    }
16354                }
16355            }
16356
16357            // Now update the oom adj for all processes.
16358            updateOomAdjLocked();
16359        }
16360    }
16361
16362    /** This method sends the specified signal to each of the persistent apps */
16363    public void signalPersistentProcesses(int sig) throws RemoteException {
16364        if (sig != Process.SIGNAL_USR1) {
16365            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16366        }
16367
16368        synchronized (this) {
16369            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16370                    != PackageManager.PERMISSION_GRANTED) {
16371                throw new SecurityException("Requires permission "
16372                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16373            }
16374
16375            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16376                ProcessRecord r = mLruProcesses.get(i);
16377                if (r.thread != null && r.persistent) {
16378                    Process.sendSignal(r.pid, sig);
16379                }
16380            }
16381        }
16382    }
16383
16384    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16385        if (proc == null || proc == mProfileProc) {
16386            proc = mProfileProc;
16387            path = mProfileFile;
16388            profileType = mProfileType;
16389            clearProfilerLocked();
16390        }
16391        if (proc == null) {
16392            return;
16393        }
16394        try {
16395            proc.thread.profilerControl(false, path, null, profileType);
16396        } catch (RemoteException e) {
16397            throw new IllegalStateException("Process disappeared");
16398        }
16399    }
16400
16401    private void clearProfilerLocked() {
16402        if (mProfileFd != null) {
16403            try {
16404                mProfileFd.close();
16405            } catch (IOException e) {
16406            }
16407        }
16408        mProfileApp = null;
16409        mProfileProc = null;
16410        mProfileFile = null;
16411        mProfileType = 0;
16412        mAutoStopProfiler = false;
16413    }
16414
16415    public boolean profileControl(String process, int userId, boolean start,
16416            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16417
16418        try {
16419            synchronized (this) {
16420                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16421                // its own permission.
16422                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16423                        != PackageManager.PERMISSION_GRANTED) {
16424                    throw new SecurityException("Requires permission "
16425                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16426                }
16427
16428                if (start && fd == null) {
16429                    throw new IllegalArgumentException("null fd");
16430                }
16431
16432                ProcessRecord proc = null;
16433                if (process != null) {
16434                    proc = findProcessLocked(process, userId, "profileControl");
16435                }
16436
16437                if (start && (proc == null || proc.thread == null)) {
16438                    throw new IllegalArgumentException("Unknown process: " + process);
16439                }
16440
16441                if (start) {
16442                    stopProfilerLocked(null, null, 0);
16443                    setProfileApp(proc.info, proc.processName, path, fd, false);
16444                    mProfileProc = proc;
16445                    mProfileType = profileType;
16446                    try {
16447                        fd = fd.dup();
16448                    } catch (IOException e) {
16449                        fd = null;
16450                    }
16451                    proc.thread.profilerControl(start, path, fd, profileType);
16452                    fd = null;
16453                    mProfileFd = null;
16454                } else {
16455                    stopProfilerLocked(proc, path, profileType);
16456                    if (fd != null) {
16457                        try {
16458                            fd.close();
16459                        } catch (IOException e) {
16460                        }
16461                    }
16462                }
16463
16464                return true;
16465            }
16466        } catch (RemoteException e) {
16467            throw new IllegalStateException("Process disappeared");
16468        } finally {
16469            if (fd != null) {
16470                try {
16471                    fd.close();
16472                } catch (IOException e) {
16473                }
16474            }
16475        }
16476    }
16477
16478    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16479        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16480                userId, true, true, callName, null);
16481        ProcessRecord proc = null;
16482        try {
16483            int pid = Integer.parseInt(process);
16484            synchronized (mPidsSelfLocked) {
16485                proc = mPidsSelfLocked.get(pid);
16486            }
16487        } catch (NumberFormatException e) {
16488        }
16489
16490        if (proc == null) {
16491            ArrayMap<String, SparseArray<ProcessRecord>> all
16492                    = mProcessNames.getMap();
16493            SparseArray<ProcessRecord> procs = all.get(process);
16494            if (procs != null && procs.size() > 0) {
16495                proc = procs.valueAt(0);
16496                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16497                    for (int i=1; i<procs.size(); i++) {
16498                        ProcessRecord thisProc = procs.valueAt(i);
16499                        if (thisProc.userId == userId) {
16500                            proc = thisProc;
16501                            break;
16502                        }
16503                    }
16504                }
16505            }
16506        }
16507
16508        return proc;
16509    }
16510
16511    public boolean dumpHeap(String process, int userId, boolean managed,
16512            String path, ParcelFileDescriptor fd) throws RemoteException {
16513
16514        try {
16515            synchronized (this) {
16516                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16517                // its own permission (same as profileControl).
16518                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16519                        != PackageManager.PERMISSION_GRANTED) {
16520                    throw new SecurityException("Requires permission "
16521                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16522                }
16523
16524                if (fd == null) {
16525                    throw new IllegalArgumentException("null fd");
16526                }
16527
16528                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16529                if (proc == null || proc.thread == null) {
16530                    throw new IllegalArgumentException("Unknown process: " + process);
16531                }
16532
16533                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16534                if (!isDebuggable) {
16535                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16536                        throw new SecurityException("Process not debuggable: " + proc);
16537                    }
16538                }
16539
16540                proc.thread.dumpHeap(managed, path, fd);
16541                fd = null;
16542                return true;
16543            }
16544        } catch (RemoteException e) {
16545            throw new IllegalStateException("Process disappeared");
16546        } finally {
16547            if (fd != null) {
16548                try {
16549                    fd.close();
16550                } catch (IOException e) {
16551                }
16552            }
16553        }
16554    }
16555
16556    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16557    public void monitor() {
16558        synchronized (this) { }
16559    }
16560
16561    void onCoreSettingsChange(Bundle settings) {
16562        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16563            ProcessRecord processRecord = mLruProcesses.get(i);
16564            try {
16565                if (processRecord.thread != null) {
16566                    processRecord.thread.setCoreSettings(settings);
16567                }
16568            } catch (RemoteException re) {
16569                /* ignore */
16570            }
16571        }
16572    }
16573
16574    // Multi-user methods
16575
16576    /**
16577     * Start user, if its not already running, but don't bring it to foreground.
16578     */
16579    @Override
16580    public boolean startUserInBackground(final int userId) {
16581        return startUser(userId, /* foreground */ false);
16582    }
16583
16584    /**
16585     * Refreshes the list of users related to the current user when either a
16586     * user switch happens or when a new related user is started in the
16587     * background.
16588     */
16589    private void updateCurrentProfileIdsLocked() {
16590        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16591                mCurrentUserId, false /* enabledOnly */);
16592        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16593        for (int i = 0; i < currentProfileIds.length; i++) {
16594            currentProfileIds[i] = profiles.get(i).id;
16595        }
16596        mCurrentProfileIds = currentProfileIds;
16597    }
16598
16599    private Set getProfileIdsLocked(int userId) {
16600        Set userIds = new HashSet<Integer>();
16601        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16602                userId, false /* enabledOnly */);
16603        for (UserInfo user : profiles) {
16604            userIds.add(Integer.valueOf(user.id));
16605        }
16606        return userIds;
16607    }
16608
16609    @Override
16610    public boolean switchUser(final int userId) {
16611        return startUser(userId, /* foregound */ true);
16612    }
16613
16614    private boolean startUser(final int userId, boolean foreground) {
16615        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16616                != PackageManager.PERMISSION_GRANTED) {
16617            String msg = "Permission Denial: switchUser() from pid="
16618                    + Binder.getCallingPid()
16619                    + ", uid=" + Binder.getCallingUid()
16620                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16621            Slog.w(TAG, msg);
16622            throw new SecurityException(msg);
16623        }
16624
16625        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16626
16627        final long ident = Binder.clearCallingIdentity();
16628        try {
16629            synchronized (this) {
16630                final int oldUserId = mCurrentUserId;
16631                if (oldUserId == userId) {
16632                    return true;
16633                }
16634
16635                mStackSupervisor.setLockTaskModeLocked(null);
16636
16637                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16638                if (userInfo == null) {
16639                    Slog.w(TAG, "No user info for user #" + userId);
16640                    return false;
16641                }
16642
16643                if (foreground) {
16644                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16645                            R.anim.screen_user_enter);
16646                }
16647
16648                boolean needStart = false;
16649
16650                // If the user we are switching to is not currently started, then
16651                // we need to start it now.
16652                if (mStartedUsers.get(userId) == null) {
16653                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16654                    updateStartedUserArrayLocked();
16655                    needStart = true;
16656                }
16657
16658                final Integer userIdInt = Integer.valueOf(userId);
16659                mUserLru.remove(userIdInt);
16660                mUserLru.add(userIdInt);
16661
16662                if (foreground) {
16663                    mCurrentUserId = userId;
16664                    updateCurrentProfileIdsLocked();
16665                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16666                    // Once the internal notion of the active user has switched, we lock the device
16667                    // with the option to show the user switcher on the keyguard.
16668                    mWindowManager.lockNow(null);
16669                } else {
16670                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16671                    updateCurrentProfileIdsLocked();
16672                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16673                    mUserLru.remove(currentUserIdInt);
16674                    mUserLru.add(currentUserIdInt);
16675                }
16676
16677                final UserStartedState uss = mStartedUsers.get(userId);
16678
16679                // Make sure user is in the started state.  If it is currently
16680                // stopping, we need to knock that off.
16681                if (uss.mState == UserStartedState.STATE_STOPPING) {
16682                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16683                    // so we can just fairly silently bring the user back from
16684                    // the almost-dead.
16685                    uss.mState = UserStartedState.STATE_RUNNING;
16686                    updateStartedUserArrayLocked();
16687                    needStart = true;
16688                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16689                    // This means ACTION_SHUTDOWN has been sent, so we will
16690                    // need to treat this as a new boot of the user.
16691                    uss.mState = UserStartedState.STATE_BOOTING;
16692                    updateStartedUserArrayLocked();
16693                    needStart = true;
16694                }
16695
16696                if (uss.mState == UserStartedState.STATE_BOOTING) {
16697                    // Booting up a new user, need to tell system services about it.
16698                    // Note that this is on the same handler as scheduling of broadcasts,
16699                    // which is important because it needs to go first.
16700                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16701                }
16702
16703                if (foreground) {
16704                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16705                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16706                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16707                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16708                            oldUserId, userId, uss));
16709                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16710                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16711                }
16712
16713                if (needStart) {
16714                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16715                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16716                            | Intent.FLAG_RECEIVER_FOREGROUND);
16717                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16718                    broadcastIntentLocked(null, null, intent,
16719                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16720                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16721                }
16722
16723                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16724                    if (userId != UserHandle.USER_OWNER) {
16725                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16726                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16727                        broadcastIntentLocked(null, null, intent, null,
16728                                new IIntentReceiver.Stub() {
16729                                    public void performReceive(Intent intent, int resultCode,
16730                                            String data, Bundle extras, boolean ordered,
16731                                            boolean sticky, int sendingUser) {
16732                                        userInitialized(uss, userId);
16733                                    }
16734                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16735                                true, false, MY_PID, Process.SYSTEM_UID,
16736                                userId);
16737                        uss.initializing = true;
16738                    } else {
16739                        getUserManagerLocked().makeInitialized(userInfo.id);
16740                    }
16741                }
16742
16743                if (foreground) {
16744                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16745                    if (homeInFront) {
16746                        startHomeActivityLocked(userId);
16747                    } else {
16748                        mStackSupervisor.resumeTopActivitiesLocked();
16749                    }
16750                    EventLogTags.writeAmSwitchUser(userId);
16751                    getUserManagerLocked().userForeground(userId);
16752                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16753                } else {
16754                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16755                }
16756
16757                if (needStart) {
16758                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16759                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16760                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16761                    broadcastIntentLocked(null, null, intent,
16762                            null, new IIntentReceiver.Stub() {
16763                                @Override
16764                                public void performReceive(Intent intent, int resultCode, String data,
16765                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16766                                        throws RemoteException {
16767                                }
16768                            }, 0, null, null,
16769                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16770                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16771                }
16772            }
16773        } finally {
16774            Binder.restoreCallingIdentity(ident);
16775        }
16776
16777        return true;
16778    }
16779
16780    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16781        long ident = Binder.clearCallingIdentity();
16782        try {
16783            Intent intent;
16784            if (oldUserId >= 0) {
16785                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16786                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16787                        | Intent.FLAG_RECEIVER_FOREGROUND);
16788                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16789                broadcastIntentLocked(null, null, intent,
16790                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16791                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16792            }
16793            if (newUserId >= 0) {
16794                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16795                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16796                        | Intent.FLAG_RECEIVER_FOREGROUND);
16797                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16798                broadcastIntentLocked(null, null, intent,
16799                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16800                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16801                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16802                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16803                        | Intent.FLAG_RECEIVER_FOREGROUND);
16804                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16805                broadcastIntentLocked(null, null, intent,
16806                        null, null, 0, null, null,
16807                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16808                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16809            }
16810        } finally {
16811            Binder.restoreCallingIdentity(ident);
16812        }
16813    }
16814
16815    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16816            final int newUserId) {
16817        final int N = mUserSwitchObservers.beginBroadcast();
16818        if (N > 0) {
16819            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16820                int mCount = 0;
16821                @Override
16822                public void sendResult(Bundle data) throws RemoteException {
16823                    synchronized (ActivityManagerService.this) {
16824                        if (mCurUserSwitchCallback == this) {
16825                            mCount++;
16826                            if (mCount == N) {
16827                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16828                            }
16829                        }
16830                    }
16831                }
16832            };
16833            synchronized (this) {
16834                uss.switching = true;
16835                mCurUserSwitchCallback = callback;
16836            }
16837            for (int i=0; i<N; i++) {
16838                try {
16839                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16840                            newUserId, callback);
16841                } catch (RemoteException e) {
16842                }
16843            }
16844        } else {
16845            synchronized (this) {
16846                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16847            }
16848        }
16849        mUserSwitchObservers.finishBroadcast();
16850    }
16851
16852    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16853        synchronized (this) {
16854            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16855            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16856        }
16857    }
16858
16859    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16860        mCurUserSwitchCallback = null;
16861        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16862        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16863                oldUserId, newUserId, uss));
16864    }
16865
16866    void userInitialized(UserStartedState uss, int newUserId) {
16867        completeSwitchAndInitalize(uss, newUserId, true, false);
16868    }
16869
16870    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16871        completeSwitchAndInitalize(uss, newUserId, false, true);
16872    }
16873
16874    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16875            boolean clearInitializing, boolean clearSwitching) {
16876        boolean unfrozen = false;
16877        synchronized (this) {
16878            if (clearInitializing) {
16879                uss.initializing = false;
16880                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16881            }
16882            if (clearSwitching) {
16883                uss.switching = false;
16884            }
16885            if (!uss.switching && !uss.initializing) {
16886                mWindowManager.stopFreezingScreen();
16887                unfrozen = true;
16888            }
16889        }
16890        if (unfrozen) {
16891            final int N = mUserSwitchObservers.beginBroadcast();
16892            for (int i=0; i<N; i++) {
16893                try {
16894                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16895                } catch (RemoteException e) {
16896                }
16897            }
16898            mUserSwitchObservers.finishBroadcast();
16899        }
16900    }
16901
16902    void scheduleStartProfilesLocked() {
16903        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16904            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16905                    DateUtils.SECOND_IN_MILLIS);
16906        }
16907    }
16908
16909    void startProfilesLocked() {
16910        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16911        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16912                mCurrentUserId, false /* enabledOnly */);
16913        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16914        for (UserInfo user : profiles) {
16915            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16916                    && user.id != mCurrentUserId) {
16917                toStart.add(user);
16918            }
16919        }
16920        final int n = toStart.size();
16921        int i = 0;
16922        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16923            startUserInBackground(toStart.get(i).id);
16924        }
16925        if (i < n) {
16926            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16927        }
16928    }
16929
16930    void finishUserBoot(UserStartedState uss) {
16931        synchronized (this) {
16932            if (uss.mState == UserStartedState.STATE_BOOTING
16933                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16934                uss.mState = UserStartedState.STATE_RUNNING;
16935                final int userId = uss.mHandle.getIdentifier();
16936                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16937                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16938                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16939                broadcastIntentLocked(null, null, intent,
16940                        null, null, 0, null, null,
16941                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16942                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16943            }
16944        }
16945    }
16946
16947    void finishUserSwitch(UserStartedState uss) {
16948        synchronized (this) {
16949            finishUserBoot(uss);
16950
16951            startProfilesLocked();
16952
16953            int num = mUserLru.size();
16954            int i = 0;
16955            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16956                Integer oldUserId = mUserLru.get(i);
16957                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16958                if (oldUss == null) {
16959                    // Shouldn't happen, but be sane if it does.
16960                    mUserLru.remove(i);
16961                    num--;
16962                    continue;
16963                }
16964                if (oldUss.mState == UserStartedState.STATE_STOPPING
16965                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16966                    // This user is already stopping, doesn't count.
16967                    num--;
16968                    i++;
16969                    continue;
16970                }
16971                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16972                    // Owner and current can't be stopped, but count as running.
16973                    i++;
16974                    continue;
16975                }
16976                // This is a user to be stopped.
16977                stopUserLocked(oldUserId, null);
16978                num--;
16979                i++;
16980            }
16981        }
16982    }
16983
16984    @Override
16985    public int stopUser(final int userId, final IStopUserCallback callback) {
16986        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16987                != PackageManager.PERMISSION_GRANTED) {
16988            String msg = "Permission Denial: switchUser() from pid="
16989                    + Binder.getCallingPid()
16990                    + ", uid=" + Binder.getCallingUid()
16991                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16992            Slog.w(TAG, msg);
16993            throw new SecurityException(msg);
16994        }
16995        if (userId <= 0) {
16996            throw new IllegalArgumentException("Can't stop primary user " + userId);
16997        }
16998        synchronized (this) {
16999            return stopUserLocked(userId, callback);
17000        }
17001    }
17002
17003    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17004        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17005        if (mCurrentUserId == userId) {
17006            return ActivityManager.USER_OP_IS_CURRENT;
17007        }
17008
17009        final UserStartedState uss = mStartedUsers.get(userId);
17010        if (uss == null) {
17011            // User is not started, nothing to do...  but we do need to
17012            // callback if requested.
17013            if (callback != null) {
17014                mHandler.post(new Runnable() {
17015                    @Override
17016                    public void run() {
17017                        try {
17018                            callback.userStopped(userId);
17019                        } catch (RemoteException e) {
17020                        }
17021                    }
17022                });
17023            }
17024            return ActivityManager.USER_OP_SUCCESS;
17025        }
17026
17027        if (callback != null) {
17028            uss.mStopCallbacks.add(callback);
17029        }
17030
17031        if (uss.mState != UserStartedState.STATE_STOPPING
17032                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17033            uss.mState = UserStartedState.STATE_STOPPING;
17034            updateStartedUserArrayLocked();
17035
17036            long ident = Binder.clearCallingIdentity();
17037            try {
17038                // We are going to broadcast ACTION_USER_STOPPING and then
17039                // once that is done send a final ACTION_SHUTDOWN and then
17040                // stop the user.
17041                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17042                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17043                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17044                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17045                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17046                // This is the result receiver for the final shutdown broadcast.
17047                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17048                    @Override
17049                    public void performReceive(Intent intent, int resultCode, String data,
17050                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17051                        finishUserStop(uss);
17052                    }
17053                };
17054                // This is the result receiver for the initial stopping broadcast.
17055                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17056                    @Override
17057                    public void performReceive(Intent intent, int resultCode, String data,
17058                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17059                        // On to the next.
17060                        synchronized (ActivityManagerService.this) {
17061                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17062                                // Whoops, we are being started back up.  Abort, abort!
17063                                return;
17064                            }
17065                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17066                        }
17067                        mSystemServiceManager.stopUser(userId);
17068                        broadcastIntentLocked(null, null, shutdownIntent,
17069                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17070                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17071                    }
17072                };
17073                // Kick things off.
17074                broadcastIntentLocked(null, null, stoppingIntent,
17075                        null, stoppingReceiver, 0, null, null,
17076                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17077                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17078            } finally {
17079                Binder.restoreCallingIdentity(ident);
17080            }
17081        }
17082
17083        return ActivityManager.USER_OP_SUCCESS;
17084    }
17085
17086    void finishUserStop(UserStartedState uss) {
17087        final int userId = uss.mHandle.getIdentifier();
17088        boolean stopped;
17089        ArrayList<IStopUserCallback> callbacks;
17090        synchronized (this) {
17091            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17092            if (mStartedUsers.get(userId) != uss) {
17093                stopped = false;
17094            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17095                stopped = false;
17096            } else {
17097                stopped = true;
17098                // User can no longer run.
17099                mStartedUsers.remove(userId);
17100                mUserLru.remove(Integer.valueOf(userId));
17101                updateStartedUserArrayLocked();
17102
17103                // Clean up all state and processes associated with the user.
17104                // Kill all the processes for the user.
17105                forceStopUserLocked(userId, "finish user");
17106            }
17107        }
17108
17109        for (int i=0; i<callbacks.size(); i++) {
17110            try {
17111                if (stopped) callbacks.get(i).userStopped(userId);
17112                else callbacks.get(i).userStopAborted(userId);
17113            } catch (RemoteException e) {
17114            }
17115        }
17116
17117        if (stopped) {
17118            mSystemServiceManager.cleanupUser(userId);
17119            synchronized (this) {
17120                mStackSupervisor.removeUserLocked(userId);
17121            }
17122        }
17123    }
17124
17125    @Override
17126    public UserInfo getCurrentUser() {
17127        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17128                != PackageManager.PERMISSION_GRANTED) && (
17129                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17130                != PackageManager.PERMISSION_GRANTED)) {
17131            String msg = "Permission Denial: getCurrentUser() from pid="
17132                    + Binder.getCallingPid()
17133                    + ", uid=" + Binder.getCallingUid()
17134                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17135            Slog.w(TAG, msg);
17136            throw new SecurityException(msg);
17137        }
17138        synchronized (this) {
17139            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17140        }
17141    }
17142
17143    int getCurrentUserIdLocked() {
17144        return mCurrentUserId;
17145    }
17146
17147    @Override
17148    public boolean isUserRunning(int userId, boolean orStopped) {
17149        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17150                != PackageManager.PERMISSION_GRANTED) {
17151            String msg = "Permission Denial: isUserRunning() from pid="
17152                    + Binder.getCallingPid()
17153                    + ", uid=" + Binder.getCallingUid()
17154                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17155            Slog.w(TAG, msg);
17156            throw new SecurityException(msg);
17157        }
17158        synchronized (this) {
17159            return isUserRunningLocked(userId, orStopped);
17160        }
17161    }
17162
17163    boolean isUserRunningLocked(int userId, boolean orStopped) {
17164        UserStartedState state = mStartedUsers.get(userId);
17165        if (state == null) {
17166            return false;
17167        }
17168        if (orStopped) {
17169            return true;
17170        }
17171        return state.mState != UserStartedState.STATE_STOPPING
17172                && state.mState != UserStartedState.STATE_SHUTDOWN;
17173    }
17174
17175    @Override
17176    public int[] getRunningUserIds() {
17177        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17178                != PackageManager.PERMISSION_GRANTED) {
17179            String msg = "Permission Denial: isUserRunning() from pid="
17180                    + Binder.getCallingPid()
17181                    + ", uid=" + Binder.getCallingUid()
17182                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17183            Slog.w(TAG, msg);
17184            throw new SecurityException(msg);
17185        }
17186        synchronized (this) {
17187            return mStartedUserArray;
17188        }
17189    }
17190
17191    private void updateStartedUserArrayLocked() {
17192        int num = 0;
17193        for (int i=0; i<mStartedUsers.size();  i++) {
17194            UserStartedState uss = mStartedUsers.valueAt(i);
17195            // This list does not include stopping users.
17196            if (uss.mState != UserStartedState.STATE_STOPPING
17197                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17198                num++;
17199            }
17200        }
17201        mStartedUserArray = new int[num];
17202        num = 0;
17203        for (int i=0; i<mStartedUsers.size();  i++) {
17204            UserStartedState uss = mStartedUsers.valueAt(i);
17205            if (uss.mState != UserStartedState.STATE_STOPPING
17206                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17207                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17208                num++;
17209            }
17210        }
17211    }
17212
17213    @Override
17214    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17215        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17216                != PackageManager.PERMISSION_GRANTED) {
17217            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17218                    + Binder.getCallingPid()
17219                    + ", uid=" + Binder.getCallingUid()
17220                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17221            Slog.w(TAG, msg);
17222            throw new SecurityException(msg);
17223        }
17224
17225        mUserSwitchObservers.register(observer);
17226    }
17227
17228    @Override
17229    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17230        mUserSwitchObservers.unregister(observer);
17231    }
17232
17233    private boolean userExists(int userId) {
17234        if (userId == 0) {
17235            return true;
17236        }
17237        UserManagerService ums = getUserManagerLocked();
17238        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17239    }
17240
17241    int[] getUsersLocked() {
17242        UserManagerService ums = getUserManagerLocked();
17243        return ums != null ? ums.getUserIds() : new int[] { 0 };
17244    }
17245
17246    UserManagerService getUserManagerLocked() {
17247        if (mUserManager == null) {
17248            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17249            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17250        }
17251        return mUserManager;
17252    }
17253
17254    private int applyUserId(int uid, int userId) {
17255        return UserHandle.getUid(userId, uid);
17256    }
17257
17258    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17259        if (info == null) return null;
17260        ApplicationInfo newInfo = new ApplicationInfo(info);
17261        newInfo.uid = applyUserId(info.uid, userId);
17262        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17263                + info.packageName;
17264        return newInfo;
17265    }
17266
17267    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17268        if (aInfo == null
17269                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17270            return aInfo;
17271        }
17272
17273        ActivityInfo info = new ActivityInfo(aInfo);
17274        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17275        return info;
17276    }
17277
17278    private final class LocalService extends ActivityManagerInternal {
17279        @Override
17280        public void goingToSleep() {
17281            ActivityManagerService.this.goingToSleep();
17282        }
17283
17284        @Override
17285        public void wakingUp() {
17286            ActivityManagerService.this.wakingUp();
17287        }
17288    }
17289
17290    /**
17291     * An implementation of IAppTask, that allows an app to manage its own tasks via
17292     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17293     * only the process that calls getAppTasks() can call the AppTask methods.
17294     */
17295    class AppTaskImpl extends IAppTask.Stub {
17296        private int mTaskId;
17297        private int mCallingUid;
17298
17299        public AppTaskImpl(int taskId, int callingUid) {
17300            mTaskId = taskId;
17301            mCallingUid = callingUid;
17302        }
17303
17304        @Override
17305        public void finishAndRemoveTask() {
17306            // Ensure that we are called from the same process that created this AppTask
17307            if (mCallingUid != Binder.getCallingUid()) {
17308                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17309                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17310                return;
17311            }
17312
17313            synchronized (ActivityManagerService.this) {
17314                long origId = Binder.clearCallingIdentity();
17315                try {
17316                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17317                    if (tr != null) {
17318                        // Only kill the process if we are not a new document
17319                        int flags = tr.getBaseIntent().getFlags();
17320                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17321                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17322                        removeTaskByIdLocked(mTaskId,
17323                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17324                    }
17325                } finally {
17326                    Binder.restoreCallingIdentity(origId);
17327                }
17328            }
17329        }
17330
17331        @Override
17332        public ActivityManager.RecentTaskInfo getTaskInfo() {
17333            // Ensure that we are called from the same process that created this AppTask
17334            if (mCallingUid != Binder.getCallingUid()) {
17335                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17336                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17337                return null;
17338            }
17339
17340            synchronized (ActivityManagerService.this) {
17341                long origId = Binder.clearCallingIdentity();
17342                try {
17343                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17344                    if (tr != null) {
17345                        return createRecentTaskInfoFromTaskRecord(tr);
17346                    }
17347                } finally {
17348                    Binder.restoreCallingIdentity(origId);
17349                }
17350                return null;
17351            }
17352        }
17353    }
17354}
17355