ActivityManagerService.java revision 2c43c339de5aaf4fef58aa9b5ac3af48609263a8
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    public void initPowerManagement() {
2198        mStackSupervisor.initPowerManagement();
2199        mBatteryStatsService.initPowerManagement();
2200    }
2201
2202    @Override
2203    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2204            throws RemoteException {
2205        if (code == SYSPROPS_TRANSACTION) {
2206            // We need to tell all apps about the system property change.
2207            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2208            synchronized(this) {
2209                final int NP = mProcessNames.getMap().size();
2210                for (int ip=0; ip<NP; ip++) {
2211                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2212                    final int NA = apps.size();
2213                    for (int ia=0; ia<NA; ia++) {
2214                        ProcessRecord app = apps.valueAt(ia);
2215                        if (app.thread != null) {
2216                            procs.add(app.thread.asBinder());
2217                        }
2218                    }
2219                }
2220            }
2221
2222            int N = procs.size();
2223            for (int i=0; i<N; i++) {
2224                Parcel data2 = Parcel.obtain();
2225                try {
2226                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2227                } catch (RemoteException e) {
2228                }
2229                data2.recycle();
2230            }
2231        }
2232        try {
2233            return super.onTransact(code, data, reply, flags);
2234        } catch (RuntimeException e) {
2235            // The activity manager only throws security exceptions, so let's
2236            // log all others.
2237            if (!(e instanceof SecurityException)) {
2238                Slog.wtf(TAG, "Activity Manager Crash", e);
2239            }
2240            throw e;
2241        }
2242    }
2243
2244    void updateCpuStats() {
2245        final long now = SystemClock.uptimeMillis();
2246        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2247            return;
2248        }
2249        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2250            synchronized (mProcessCpuThread) {
2251                mProcessCpuThread.notify();
2252            }
2253        }
2254    }
2255
2256    void updateCpuStatsNow() {
2257        synchronized (mProcessCpuThread) {
2258            mProcessCpuMutexFree.set(false);
2259            final long now = SystemClock.uptimeMillis();
2260            boolean haveNewCpuStats = false;
2261
2262            if (MONITOR_CPU_USAGE &&
2263                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2264                mLastCpuTime.set(now);
2265                haveNewCpuStats = true;
2266                mProcessCpuTracker.update();
2267                //Slog.i(TAG, mProcessCpu.printCurrentState());
2268                //Slog.i(TAG, "Total CPU usage: "
2269                //        + mProcessCpu.getTotalCpuPercent() + "%");
2270
2271                // Slog the cpu usage if the property is set.
2272                if ("true".equals(SystemProperties.get("events.cpu"))) {
2273                    int user = mProcessCpuTracker.getLastUserTime();
2274                    int system = mProcessCpuTracker.getLastSystemTime();
2275                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2276                    int irq = mProcessCpuTracker.getLastIrqTime();
2277                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2278                    int idle = mProcessCpuTracker.getLastIdleTime();
2279
2280                    int total = user + system + iowait + irq + softIrq + idle;
2281                    if (total == 0) total = 1;
2282
2283                    EventLog.writeEvent(EventLogTags.CPU,
2284                            ((user+system+iowait+irq+softIrq) * 100) / total,
2285                            (user * 100) / total,
2286                            (system * 100) / total,
2287                            (iowait * 100) / total,
2288                            (irq * 100) / total,
2289                            (softIrq * 100) / total);
2290                }
2291            }
2292
2293            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2294            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2295            synchronized(bstats) {
2296                synchronized(mPidsSelfLocked) {
2297                    if (haveNewCpuStats) {
2298                        if (mOnBattery) {
2299                            int perc = bstats.startAddingCpuLocked();
2300                            int totalUTime = 0;
2301                            int totalSTime = 0;
2302                            final int N = mProcessCpuTracker.countStats();
2303                            for (int i=0; i<N; i++) {
2304                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2305                                if (!st.working) {
2306                                    continue;
2307                                }
2308                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2309                                int otherUTime = (st.rel_utime*perc)/100;
2310                                int otherSTime = (st.rel_stime*perc)/100;
2311                                totalUTime += otherUTime;
2312                                totalSTime += otherSTime;
2313                                if (pr != null) {
2314                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2315                                    if (ps == null || !ps.isActive()) {
2316                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2317                                                pr.info.uid, pr.processName);
2318                                    }
2319                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2320                                            st.rel_stime-otherSTime);
2321                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2322                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2323                                } else {
2324                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2325                                    if (ps == null || !ps.isActive()) {
2326                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2327                                                bstats.mapUid(st.uid), st.name);
2328                                    }
2329                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2330                                            st.rel_stime-otherSTime);
2331                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2332                                }
2333                            }
2334                            bstats.finishAddingCpuLocked(perc, totalUTime,
2335                                    totalSTime, cpuSpeedTimes);
2336                        }
2337                    }
2338                }
2339
2340                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2341                    mLastWriteTime = now;
2342                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2343                }
2344            }
2345        }
2346    }
2347
2348    @Override
2349    public void batteryNeedsCpuUpdate() {
2350        updateCpuStatsNow();
2351    }
2352
2353    @Override
2354    public void batteryPowerChanged(boolean onBattery) {
2355        // When plugging in, update the CPU stats first before changing
2356        // the plug state.
2357        updateCpuStatsNow();
2358        synchronized (this) {
2359            synchronized(mPidsSelfLocked) {
2360                mOnBattery = DEBUG_POWER ? true : onBattery;
2361            }
2362        }
2363    }
2364
2365    /**
2366     * Initialize the application bind args. These are passed to each
2367     * process when the bindApplication() IPC is sent to the process. They're
2368     * lazily setup to make sure the services are running when they're asked for.
2369     */
2370    private HashMap<String, IBinder> getCommonServicesLocked() {
2371        if (mAppBindArgs == null) {
2372            mAppBindArgs = new HashMap<String, IBinder>();
2373
2374            // Setup the application init args
2375            mAppBindArgs.put("package", ServiceManager.getService("package"));
2376            mAppBindArgs.put("window", ServiceManager.getService("window"));
2377            mAppBindArgs.put(Context.ALARM_SERVICE,
2378                    ServiceManager.getService(Context.ALARM_SERVICE));
2379        }
2380        return mAppBindArgs;
2381    }
2382
2383    final void setFocusedActivityLocked(ActivityRecord r) {
2384        if (mFocusedActivity != r) {
2385            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2386            mFocusedActivity = r;
2387            if (r.task != null && r.task.voiceInteractor != null) {
2388                startRunningVoiceLocked();
2389            } else {
2390                finishRunningVoiceLocked();
2391            }
2392            mStackSupervisor.setFocusedStack(r);
2393            if (r != null) {
2394                mWindowManager.setFocusedApp(r.appToken, true);
2395            }
2396            applyUpdateLockStateLocked(r);
2397        }
2398    }
2399
2400    final void clearFocusedActivity(ActivityRecord r) {
2401        if (mFocusedActivity == r) {
2402            mFocusedActivity = null;
2403        }
2404    }
2405
2406    @Override
2407    public void setFocusedStack(int stackId) {
2408        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2409        synchronized (ActivityManagerService.this) {
2410            ActivityStack stack = mStackSupervisor.getStack(stackId);
2411            if (stack != null) {
2412                ActivityRecord r = stack.topRunningActivityLocked(null);
2413                if (r != null) {
2414                    setFocusedActivityLocked(r);
2415                }
2416            }
2417        }
2418    }
2419
2420    @Override
2421    public void notifyActivityDrawn(IBinder token) {
2422        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2423        synchronized (this) {
2424            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2425            if (r != null) {
2426                r.task.stack.notifyActivityDrawnLocked(r);
2427            }
2428        }
2429    }
2430
2431    final void applyUpdateLockStateLocked(ActivityRecord r) {
2432        // Modifications to the UpdateLock state are done on our handler, outside
2433        // the activity manager's locks.  The new state is determined based on the
2434        // state *now* of the relevant activity record.  The object is passed to
2435        // the handler solely for logging detail, not to be consulted/modified.
2436        final boolean nextState = r != null && r.immersive;
2437        mHandler.sendMessage(
2438                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2439    }
2440
2441    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2442        Message msg = Message.obtain();
2443        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2444        msg.obj = r.task.askedCompatMode ? null : r;
2445        mHandler.sendMessage(msg);
2446    }
2447
2448    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2449            String what, Object obj, ProcessRecord srcApp) {
2450        app.lastActivityTime = now;
2451
2452        if (app.activities.size() > 0) {
2453            // Don't want to touch dependent processes that are hosting activities.
2454            return index;
2455        }
2456
2457        int lrui = mLruProcesses.lastIndexOf(app);
2458        if (lrui < 0) {
2459            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2460                    + what + " " + obj + " from " + srcApp);
2461            return index;
2462        }
2463
2464        if (lrui >= index) {
2465            // Don't want to cause this to move dependent processes *back* in the
2466            // list as if they were less frequently used.
2467            return index;
2468        }
2469
2470        if (lrui >= mLruProcessActivityStart) {
2471            // Don't want to touch dependent processes that are hosting activities.
2472            return index;
2473        }
2474
2475        mLruProcesses.remove(lrui);
2476        if (index > 0) {
2477            index--;
2478        }
2479        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2480                + " in LRU list: " + app);
2481        mLruProcesses.add(index, app);
2482        return index;
2483    }
2484
2485    final void removeLruProcessLocked(ProcessRecord app) {
2486        int lrui = mLruProcesses.lastIndexOf(app);
2487        if (lrui >= 0) {
2488            if (lrui <= mLruProcessActivityStart) {
2489                mLruProcessActivityStart--;
2490            }
2491            if (lrui <= mLruProcessServiceStart) {
2492                mLruProcessServiceStart--;
2493            }
2494            mLruProcesses.remove(lrui);
2495        }
2496    }
2497
2498    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2499            ProcessRecord client) {
2500        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2501                || app.treatLikeActivity;
2502        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2503        if (!activityChange && hasActivity) {
2504            // The process has activities, so we are only allowing activity-based adjustments
2505            // to move it.  It should be kept in the front of the list with other
2506            // processes that have activities, and we don't want those to change their
2507            // order except due to activity operations.
2508            return;
2509        }
2510
2511        mLruSeq++;
2512        final long now = SystemClock.uptimeMillis();
2513        app.lastActivityTime = now;
2514
2515        // First a quick reject: if the app is already at the position we will
2516        // put it, then there is nothing to do.
2517        if (hasActivity) {
2518            final int N = mLruProcesses.size();
2519            if (N > 0 && mLruProcesses.get(N-1) == app) {
2520                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2521                return;
2522            }
2523        } else {
2524            if (mLruProcessServiceStart > 0
2525                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2526                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2527                return;
2528            }
2529        }
2530
2531        int lrui = mLruProcesses.lastIndexOf(app);
2532
2533        if (app.persistent && lrui >= 0) {
2534            // We don't care about the position of persistent processes, as long as
2535            // they are in the list.
2536            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2537            return;
2538        }
2539
2540        /* In progress: compute new position first, so we can avoid doing work
2541           if the process is not actually going to move.  Not yet working.
2542        int addIndex;
2543        int nextIndex;
2544        boolean inActivity = false, inService = false;
2545        if (hasActivity) {
2546            // Process has activities, put it at the very tipsy-top.
2547            addIndex = mLruProcesses.size();
2548            nextIndex = mLruProcessServiceStart;
2549            inActivity = true;
2550        } else if (hasService) {
2551            // Process has services, put it at the top of the service list.
2552            addIndex = mLruProcessActivityStart;
2553            nextIndex = mLruProcessServiceStart;
2554            inActivity = true;
2555            inService = true;
2556        } else  {
2557            // Process not otherwise of interest, it goes to the top of the non-service area.
2558            addIndex = mLruProcessServiceStart;
2559            if (client != null) {
2560                int clientIndex = mLruProcesses.lastIndexOf(client);
2561                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2562                        + app);
2563                if (clientIndex >= 0 && addIndex > clientIndex) {
2564                    addIndex = clientIndex;
2565                }
2566            }
2567            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2568        }
2569
2570        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2571                + mLruProcessActivityStart + "): " + app);
2572        */
2573
2574        if (lrui >= 0) {
2575            if (lrui < mLruProcessActivityStart) {
2576                mLruProcessActivityStart--;
2577            }
2578            if (lrui < mLruProcessServiceStart) {
2579                mLruProcessServiceStart--;
2580            }
2581            /*
2582            if (addIndex > lrui) {
2583                addIndex--;
2584            }
2585            if (nextIndex > lrui) {
2586                nextIndex--;
2587            }
2588            */
2589            mLruProcesses.remove(lrui);
2590        }
2591
2592        /*
2593        mLruProcesses.add(addIndex, app);
2594        if (inActivity) {
2595            mLruProcessActivityStart++;
2596        }
2597        if (inService) {
2598            mLruProcessActivityStart++;
2599        }
2600        */
2601
2602        int nextIndex;
2603        if (hasActivity) {
2604            final int N = mLruProcesses.size();
2605            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2606                // Process doesn't have activities, but has clients with
2607                // activities...  move it up, but one below the top (the top
2608                // should always have a real activity).
2609                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2610                mLruProcesses.add(N-1, app);
2611                // To keep it from spamming the LRU list (by making a bunch of clients),
2612                // we will push down any other entries owned by the app.
2613                final int uid = app.info.uid;
2614                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2615                    ProcessRecord subProc = mLruProcesses.get(i);
2616                    if (subProc.info.uid == uid) {
2617                        // We want to push this one down the list.  If the process after
2618                        // it is for the same uid, however, don't do so, because we don't
2619                        // want them internally to be re-ordered.
2620                        if (mLruProcesses.get(i-1).info.uid != uid) {
2621                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2622                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2623                            ProcessRecord tmp = mLruProcesses.get(i);
2624                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2625                            mLruProcesses.set(i-1, tmp);
2626                            i--;
2627                        }
2628                    } else {
2629                        // A gap, we can stop here.
2630                        break;
2631                    }
2632                }
2633            } else {
2634                // Process has activities, put it at the very tipsy-top.
2635                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2636                mLruProcesses.add(app);
2637            }
2638            nextIndex = mLruProcessServiceStart;
2639        } else if (hasService) {
2640            // Process has services, put it at the top of the service list.
2641            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2642            mLruProcesses.add(mLruProcessActivityStart, app);
2643            nextIndex = mLruProcessServiceStart;
2644            mLruProcessActivityStart++;
2645        } else  {
2646            // Process not otherwise of interest, it goes to the top of the non-service area.
2647            int index = mLruProcessServiceStart;
2648            if (client != null) {
2649                // If there is a client, don't allow the process to be moved up higher
2650                // in the list than that client.
2651                int clientIndex = mLruProcesses.lastIndexOf(client);
2652                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2653                        + " when updating " + app);
2654                if (clientIndex <= lrui) {
2655                    // Don't allow the client index restriction to push it down farther in the
2656                    // list than it already is.
2657                    clientIndex = lrui;
2658                }
2659                if (clientIndex >= 0 && index > clientIndex) {
2660                    index = clientIndex;
2661                }
2662            }
2663            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2664            mLruProcesses.add(index, app);
2665            nextIndex = index-1;
2666            mLruProcessActivityStart++;
2667            mLruProcessServiceStart++;
2668        }
2669
2670        // If the app is currently using a content provider or service,
2671        // bump those processes as well.
2672        for (int j=app.connections.size()-1; j>=0; j--) {
2673            ConnectionRecord cr = app.connections.valueAt(j);
2674            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2675                    && cr.binding.service.app != null
2676                    && cr.binding.service.app.lruSeq != mLruSeq
2677                    && !cr.binding.service.app.persistent) {
2678                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2679                        "service connection", cr, app);
2680            }
2681        }
2682        for (int j=app.conProviders.size()-1; j>=0; j--) {
2683            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2684            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2685                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2686                        "provider reference", cpr, app);
2687            }
2688        }
2689    }
2690
2691    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2692        if (uid == Process.SYSTEM_UID) {
2693            // The system gets to run in any process.  If there are multiple
2694            // processes with the same uid, just pick the first (this
2695            // should never happen).
2696            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2697            if (procs == null) return null;
2698            final int N = procs.size();
2699            for (int i = 0; i < N; i++) {
2700                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2701            }
2702        }
2703        ProcessRecord proc = mProcessNames.get(processName, uid);
2704        if (false && proc != null && !keepIfLarge
2705                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2706                && proc.lastCachedPss >= 4000) {
2707            // Turn this condition on to cause killing to happen regularly, for testing.
2708            if (proc.baseProcessTracker != null) {
2709                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2710            }
2711            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2712                    + "k from cached");
2713        } else if (proc != null && !keepIfLarge
2714                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2715                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2716            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2717            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2718                if (proc.baseProcessTracker != null) {
2719                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2720                }
2721                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2722                        + "k from cached");
2723            }
2724        }
2725        return proc;
2726    }
2727
2728    void ensurePackageDexOpt(String packageName) {
2729        IPackageManager pm = AppGlobals.getPackageManager();
2730        try {
2731            if (pm.performDexOpt(packageName)) {
2732                mDidDexOpt = true;
2733            }
2734        } catch (RemoteException e) {
2735        }
2736    }
2737
2738    boolean isNextTransitionForward() {
2739        int transit = mWindowManager.getPendingAppTransition();
2740        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2741                || transit == AppTransition.TRANSIT_TASK_OPEN
2742                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2743    }
2744
2745    final ProcessRecord startProcessLocked(String processName,
2746            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2747            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2748            boolean isolated, boolean keepIfLarge) {
2749        ProcessRecord app;
2750        if (!isolated) {
2751            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2752        } else {
2753            // If this is an isolated process, it can't re-use an existing process.
2754            app = null;
2755        }
2756        // We don't have to do anything more if:
2757        // (1) There is an existing application record; and
2758        // (2) The caller doesn't think it is dead, OR there is no thread
2759        //     object attached to it so we know it couldn't have crashed; and
2760        // (3) There is a pid assigned to it, so it is either starting or
2761        //     already running.
2762        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2763                + " app=" + app + " knownToBeDead=" + knownToBeDead
2764                + " thread=" + (app != null ? app.thread : null)
2765                + " pid=" + (app != null ? app.pid : -1));
2766        if (app != null && app.pid > 0) {
2767            if (!knownToBeDead || app.thread == null) {
2768                // We already have the app running, or are waiting for it to
2769                // come up (we have a pid but not yet its thread), so keep it.
2770                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2771                // If this is a new package in the process, add the package to the list
2772                app.addPackage(info.packageName, mProcessStats);
2773                return app;
2774            }
2775
2776            // An application record is attached to a previous process,
2777            // clean it up now.
2778            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2779            handleAppDiedLocked(app, true, true);
2780        }
2781
2782        String hostingNameStr = hostingName != null
2783                ? hostingName.flattenToShortString() : null;
2784
2785        if (!isolated) {
2786            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2787                // If we are in the background, then check to see if this process
2788                // is bad.  If so, we will just silently fail.
2789                if (mBadProcesses.get(info.processName, info.uid) != null) {
2790                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2791                            + "/" + info.processName);
2792                    return null;
2793                }
2794            } else {
2795                // When the user is explicitly starting a process, then clear its
2796                // crash count so that we won't make it bad until they see at
2797                // least one crash dialog again, and make the process good again
2798                // if it had been bad.
2799                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2800                        + "/" + info.processName);
2801                mProcessCrashTimes.remove(info.processName, info.uid);
2802                if (mBadProcesses.get(info.processName, info.uid) != null) {
2803                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2804                            UserHandle.getUserId(info.uid), info.uid,
2805                            info.processName);
2806                    mBadProcesses.remove(info.processName, info.uid);
2807                    if (app != null) {
2808                        app.bad = false;
2809                    }
2810                }
2811            }
2812        }
2813
2814        if (app == null) {
2815            app = newProcessRecordLocked(info, processName, isolated);
2816            if (app == null) {
2817                Slog.w(TAG, "Failed making new process record for "
2818                        + processName + "/" + info.uid + " isolated=" + isolated);
2819                return null;
2820            }
2821            mProcessNames.put(processName, app.uid, app);
2822            if (isolated) {
2823                mIsolatedProcesses.put(app.uid, app);
2824            }
2825        } else {
2826            // If this is a new package in the process, add the package to the list
2827            app.addPackage(info.packageName, mProcessStats);
2828        }
2829
2830        // If the system is not ready yet, then hold off on starting this
2831        // process until it is.
2832        if (!mProcessesReady
2833                && !isAllowedWhileBooting(info)
2834                && !allowWhileBooting) {
2835            if (!mProcessesOnHold.contains(app)) {
2836                mProcessesOnHold.add(app);
2837            }
2838            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2839            return app;
2840        }
2841
2842        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2843        return (app.pid != 0) ? app : null;
2844    }
2845
2846    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2847        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2848    }
2849
2850    private final void startProcessLocked(ProcessRecord app,
2851            String hostingType, String hostingNameStr, String abiOverride) {
2852        if (app.pid > 0 && app.pid != MY_PID) {
2853            synchronized (mPidsSelfLocked) {
2854                mPidsSelfLocked.remove(app.pid);
2855                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2856            }
2857            app.setPid(0);
2858        }
2859
2860        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2861                "startProcessLocked removing on hold: " + app);
2862        mProcessesOnHold.remove(app);
2863
2864        updateCpuStats();
2865
2866        try {
2867            int uid = app.uid;
2868
2869            int[] gids = null;
2870            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2871            if (!app.isolated) {
2872                int[] permGids = null;
2873                try {
2874                    final PackageManager pm = mContext.getPackageManager();
2875                    permGids = pm.getPackageGids(app.info.packageName);
2876
2877                    if (Environment.isExternalStorageEmulated()) {
2878                        if (pm.checkPermission(
2879                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2880                                app.info.packageName) == PERMISSION_GRANTED) {
2881                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2882                        } else {
2883                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2884                        }
2885                    }
2886                } catch (PackageManager.NameNotFoundException e) {
2887                    Slog.w(TAG, "Unable to retrieve gids", e);
2888                }
2889
2890                /*
2891                 * Add shared application and profile GIDs so applications can share some
2892                 * resources like shared libraries and access user-wide resources
2893                 */
2894                if (permGids == null) {
2895                    gids = new int[2];
2896                } else {
2897                    gids = new int[permGids.length + 2];
2898                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2899                }
2900                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2901                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2902            }
2903            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2904                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2905                        && mTopComponent != null
2906                        && app.processName.equals(mTopComponent.getPackageName())) {
2907                    uid = 0;
2908                }
2909                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2910                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2911                    uid = 0;
2912                }
2913            }
2914            int debugFlags = 0;
2915            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2916                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2917                // Also turn on CheckJNI for debuggable apps. It's quite
2918                // awkward to turn on otherwise.
2919                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2920            }
2921            // Run the app in safe mode if its manifest requests so or the
2922            // system is booted in safe mode.
2923            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2924                mSafeMode == true) {
2925                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2926            }
2927            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2928                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2929            }
2930            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2931                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2932            }
2933            if ("1".equals(SystemProperties.get("debug.assert"))) {
2934                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2935            }
2936
2937            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2938            if (requiredAbi == null) {
2939                requiredAbi = Build.SUPPORTED_ABIS[0];
2940            }
2941
2942            // Start the process.  It will either succeed and return a result containing
2943            // the PID of the new process, or else throw a RuntimeException.
2944            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2945                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2946                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2947
2948            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2949            synchronized (bs) {
2950                if (bs.isOnBattery()) {
2951                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2952                }
2953            }
2954
2955            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2956                    UserHandle.getUserId(uid), startResult.pid, uid,
2957                    app.processName, hostingType,
2958                    hostingNameStr != null ? hostingNameStr : "");
2959
2960            if (app.persistent) {
2961                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2962            }
2963
2964            StringBuilder buf = mStringBuilder;
2965            buf.setLength(0);
2966            buf.append("Start proc ");
2967            buf.append(app.processName);
2968            buf.append(" for ");
2969            buf.append(hostingType);
2970            if (hostingNameStr != null) {
2971                buf.append(" ");
2972                buf.append(hostingNameStr);
2973            }
2974            buf.append(": pid=");
2975            buf.append(startResult.pid);
2976            buf.append(" uid=");
2977            buf.append(uid);
2978            buf.append(" gids={");
2979            if (gids != null) {
2980                for (int gi=0; gi<gids.length; gi++) {
2981                    if (gi != 0) buf.append(", ");
2982                    buf.append(gids[gi]);
2983
2984                }
2985            }
2986            buf.append("}");
2987            if (requiredAbi != null) {
2988                buf.append(" abi=");
2989                buf.append(requiredAbi);
2990            }
2991            Slog.i(TAG, buf.toString());
2992            app.setPid(startResult.pid);
2993            app.usingWrapper = startResult.usingWrapper;
2994            app.removed = false;
2995            synchronized (mPidsSelfLocked) {
2996                this.mPidsSelfLocked.put(startResult.pid, app);
2997                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2998                msg.obj = app;
2999                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3000                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3001            }
3002            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3003                    app.processName, app.info.uid);
3004            if (app.isolated) {
3005                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3006            }
3007        } catch (RuntimeException e) {
3008            // XXX do better error recovery.
3009            app.setPid(0);
3010            Slog.e(TAG, "Failure starting process " + app.processName, e);
3011        }
3012    }
3013
3014    void updateUsageStats(ActivityRecord component, boolean resumed) {
3015        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3016        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3017        if (resumed) {
3018            mUsageStatsService.noteResumeComponent(component.realActivity);
3019            synchronized (stats) {
3020                stats.noteActivityResumedLocked(component.app.uid);
3021            }
3022        } else {
3023            mUsageStatsService.notePauseComponent(component.realActivity);
3024            synchronized (stats) {
3025                stats.noteActivityPausedLocked(component.app.uid);
3026            }
3027        }
3028    }
3029
3030    Intent getHomeIntent() {
3031        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3032        intent.setComponent(mTopComponent);
3033        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3034            intent.addCategory(Intent.CATEGORY_HOME);
3035        }
3036        return intent;
3037    }
3038
3039    boolean startHomeActivityLocked(int userId) {
3040        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3041                && mTopAction == null) {
3042            // We are running in factory test mode, but unable to find
3043            // the factory test app, so just sit around displaying the
3044            // error message and don't try to start anything.
3045            return false;
3046        }
3047        Intent intent = getHomeIntent();
3048        ActivityInfo aInfo =
3049            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3050        if (aInfo != null) {
3051            intent.setComponent(new ComponentName(
3052                    aInfo.applicationInfo.packageName, aInfo.name));
3053            // Don't do this if the home app is currently being
3054            // instrumented.
3055            aInfo = new ActivityInfo(aInfo);
3056            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3057            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3058                    aInfo.applicationInfo.uid, true);
3059            if (app == null || app.instrumentationClass == null) {
3060                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3061                mStackSupervisor.startHomeActivity(intent, aInfo);
3062            }
3063        }
3064
3065        return true;
3066    }
3067
3068    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3069        ActivityInfo ai = null;
3070        ComponentName comp = intent.getComponent();
3071        try {
3072            if (comp != null) {
3073                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3074            } else {
3075                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3076                        intent,
3077                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3078                            flags, userId);
3079
3080                if (info != null) {
3081                    ai = info.activityInfo;
3082                }
3083            }
3084        } catch (RemoteException e) {
3085            // ignore
3086        }
3087
3088        return ai;
3089    }
3090
3091    /**
3092     * Starts the "new version setup screen" if appropriate.
3093     */
3094    void startSetupActivityLocked() {
3095        // Only do this once per boot.
3096        if (mCheckedForSetup) {
3097            return;
3098        }
3099
3100        // We will show this screen if the current one is a different
3101        // version than the last one shown, and we are not running in
3102        // low-level factory test mode.
3103        final ContentResolver resolver = mContext.getContentResolver();
3104        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3105                Settings.Global.getInt(resolver,
3106                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3107            mCheckedForSetup = true;
3108
3109            // See if we should be showing the platform update setup UI.
3110            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3111            List<ResolveInfo> ris = mContext.getPackageManager()
3112                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3113
3114            // We don't allow third party apps to replace this.
3115            ResolveInfo ri = null;
3116            for (int i=0; ris != null && i<ris.size(); i++) {
3117                if ((ris.get(i).activityInfo.applicationInfo.flags
3118                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3119                    ri = ris.get(i);
3120                    break;
3121                }
3122            }
3123
3124            if (ri != null) {
3125                String vers = ri.activityInfo.metaData != null
3126                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3127                        : null;
3128                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3129                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3130                            Intent.METADATA_SETUP_VERSION);
3131                }
3132                String lastVers = Settings.Secure.getString(
3133                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3134                if (vers != null && !vers.equals(lastVers)) {
3135                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3136                    intent.setComponent(new ComponentName(
3137                            ri.activityInfo.packageName, ri.activityInfo.name));
3138                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3139                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3140                }
3141            }
3142        }
3143    }
3144
3145    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3146        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3147    }
3148
3149    void enforceNotIsolatedCaller(String caller) {
3150        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3151            throw new SecurityException("Isolated process not allowed to call " + caller);
3152        }
3153    }
3154
3155    @Override
3156    public int getFrontActivityScreenCompatMode() {
3157        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3158        synchronized (this) {
3159            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3160        }
3161    }
3162
3163    @Override
3164    public void setFrontActivityScreenCompatMode(int mode) {
3165        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3166                "setFrontActivityScreenCompatMode");
3167        synchronized (this) {
3168            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3169        }
3170    }
3171
3172    @Override
3173    public int getPackageScreenCompatMode(String packageName) {
3174        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3175        synchronized (this) {
3176            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3177        }
3178    }
3179
3180    @Override
3181    public void setPackageScreenCompatMode(String packageName, int mode) {
3182        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3183                "setPackageScreenCompatMode");
3184        synchronized (this) {
3185            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3186        }
3187    }
3188
3189    @Override
3190    public boolean getPackageAskScreenCompat(String packageName) {
3191        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3192        synchronized (this) {
3193            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3194        }
3195    }
3196
3197    @Override
3198    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3199        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3200                "setPackageAskScreenCompat");
3201        synchronized (this) {
3202            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3203        }
3204    }
3205
3206    private void dispatchProcessesChanged() {
3207        int N;
3208        synchronized (this) {
3209            N = mPendingProcessChanges.size();
3210            if (mActiveProcessChanges.length < N) {
3211                mActiveProcessChanges = new ProcessChangeItem[N];
3212            }
3213            mPendingProcessChanges.toArray(mActiveProcessChanges);
3214            mAvailProcessChanges.addAll(mPendingProcessChanges);
3215            mPendingProcessChanges.clear();
3216            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3217        }
3218
3219        int i = mProcessObservers.beginBroadcast();
3220        while (i > 0) {
3221            i--;
3222            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3223            if (observer != null) {
3224                try {
3225                    for (int j=0; j<N; j++) {
3226                        ProcessChangeItem item = mActiveProcessChanges[j];
3227                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3228                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3229                                    + item.pid + " uid=" + item.uid + ": "
3230                                    + item.foregroundActivities);
3231                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3232                                    item.foregroundActivities);
3233                        }
3234                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3235                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3236                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3237                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3238                        }
3239                    }
3240                } catch (RemoteException e) {
3241                }
3242            }
3243        }
3244        mProcessObservers.finishBroadcast();
3245    }
3246
3247    private void dispatchProcessDied(int pid, int uid) {
3248        int i = mProcessObservers.beginBroadcast();
3249        while (i > 0) {
3250            i--;
3251            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3252            if (observer != null) {
3253                try {
3254                    observer.onProcessDied(pid, uid);
3255                } catch (RemoteException e) {
3256                }
3257            }
3258        }
3259        mProcessObservers.finishBroadcast();
3260    }
3261
3262    final void doPendingActivityLaunchesLocked(boolean doResume) {
3263        final int N = mPendingActivityLaunches.size();
3264        if (N <= 0) {
3265            return;
3266        }
3267        for (int i=0; i<N; i++) {
3268            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3269            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3270                    doResume && i == (N-1), null);
3271        }
3272        mPendingActivityLaunches.clear();
3273    }
3274
3275    @Override
3276    public final int startActivity(IApplicationThread caller, String callingPackage,
3277            Intent intent, String resolvedType, IBinder resultTo,
3278            String resultWho, int requestCode, int startFlags,
3279            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3280        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3281                resultWho, requestCode,
3282                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3283    }
3284
3285    @Override
3286    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3287            Intent intent, String resolvedType, IBinder resultTo,
3288            String resultWho, int requestCode, int startFlags,
3289            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3290        enforceNotIsolatedCaller("startActivity");
3291        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3292                false, true, "startActivity", null);
3293        // TODO: Switch to user app stacks here.
3294        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3295                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3296                null, null, options, userId, null);
3297    }
3298
3299    @Override
3300    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3301            Intent intent, String resolvedType, IBinder resultTo,
3302            String resultWho, int requestCode, int startFlags, String profileFile,
3303            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3304        enforceNotIsolatedCaller("startActivityAndWait");
3305        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3306                false, true, "startActivityAndWait", null);
3307        WaitResult res = new WaitResult();
3308        // TODO: Switch to user app stacks here.
3309        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3310                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3311                res, null, options, UserHandle.getCallingUserId(), null);
3312        return res;
3313    }
3314
3315    @Override
3316    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3317            Intent intent, String resolvedType, IBinder resultTo,
3318            String resultWho, int requestCode, int startFlags, Configuration config,
3319            Bundle options, int userId) {
3320        enforceNotIsolatedCaller("startActivityWithConfig");
3321        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3322                false, true, "startActivityWithConfig", null);
3323        // TODO: Switch to user app stacks here.
3324        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3325                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3326                null, null, null, config, options, userId, null);
3327        return ret;
3328    }
3329
3330    @Override
3331    public int startActivityIntentSender(IApplicationThread caller,
3332            IntentSender intent, Intent fillInIntent, String resolvedType,
3333            IBinder resultTo, String resultWho, int requestCode,
3334            int flagsMask, int flagsValues, Bundle options) {
3335        enforceNotIsolatedCaller("startActivityIntentSender");
3336        // Refuse possible leaked file descriptors
3337        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3338            throw new IllegalArgumentException("File descriptors passed in Intent");
3339        }
3340
3341        IIntentSender sender = intent.getTarget();
3342        if (!(sender instanceof PendingIntentRecord)) {
3343            throw new IllegalArgumentException("Bad PendingIntent object");
3344        }
3345
3346        PendingIntentRecord pir = (PendingIntentRecord)sender;
3347
3348        synchronized (this) {
3349            // If this is coming from the currently resumed activity, it is
3350            // effectively saying that app switches are allowed at this point.
3351            final ActivityStack stack = getFocusedStack();
3352            if (stack.mResumedActivity != null &&
3353                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3354                mAppSwitchesAllowedTime = 0;
3355            }
3356        }
3357        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3358                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3359        return ret;
3360    }
3361
3362    @Override
3363    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3364            Intent intent, String resolvedType, IVoiceInteractionSession session,
3365            IVoiceInteractor interactor, int startFlags, String profileFile,
3366            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3367        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3368                != PackageManager.PERMISSION_GRANTED) {
3369            String msg = "Permission Denial: startVoiceActivity() from pid="
3370                    + Binder.getCallingPid()
3371                    + ", uid=" + Binder.getCallingUid()
3372                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3373            Slog.w(TAG, msg);
3374            throw new SecurityException(msg);
3375        }
3376        if (session == null || interactor == null) {
3377            throw new NullPointerException("null session or interactor");
3378        }
3379        userId = handleIncomingUser(callingPid, callingUid, userId,
3380                false, true, "startVoiceActivity", null);
3381        // TODO: Switch to user app stacks here.
3382        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3383                resolvedType, session, interactor, null, null, 0, startFlags,
3384                profileFile, profileFd, null, null, options, userId, null);
3385    }
3386
3387    @Override
3388    public boolean startNextMatchingActivity(IBinder callingActivity,
3389            Intent intent, Bundle options) {
3390        // Refuse possible leaked file descriptors
3391        if (intent != null && intent.hasFileDescriptors() == true) {
3392            throw new IllegalArgumentException("File descriptors passed in Intent");
3393        }
3394
3395        synchronized (this) {
3396            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3397            if (r == null) {
3398                ActivityOptions.abort(options);
3399                return false;
3400            }
3401            if (r.app == null || r.app.thread == null) {
3402                // The caller is not running...  d'oh!
3403                ActivityOptions.abort(options);
3404                return false;
3405            }
3406            intent = new Intent(intent);
3407            // The caller is not allowed to change the data.
3408            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3409            // And we are resetting to find the next component...
3410            intent.setComponent(null);
3411
3412            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3413
3414            ActivityInfo aInfo = null;
3415            try {
3416                List<ResolveInfo> resolves =
3417                    AppGlobals.getPackageManager().queryIntentActivities(
3418                            intent, r.resolvedType,
3419                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3420                            UserHandle.getCallingUserId());
3421
3422                // Look for the original activity in the list...
3423                final int N = resolves != null ? resolves.size() : 0;
3424                for (int i=0; i<N; i++) {
3425                    ResolveInfo rInfo = resolves.get(i);
3426                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3427                            && rInfo.activityInfo.name.equals(r.info.name)) {
3428                        // We found the current one...  the next matching is
3429                        // after it.
3430                        i++;
3431                        if (i<N) {
3432                            aInfo = resolves.get(i).activityInfo;
3433                        }
3434                        if (debug) {
3435                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3436                                    + "/" + r.info.name);
3437                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3438                                    + "/" + aInfo.name);
3439                        }
3440                        break;
3441                    }
3442                }
3443            } catch (RemoteException e) {
3444            }
3445
3446            if (aInfo == null) {
3447                // Nobody who is next!
3448                ActivityOptions.abort(options);
3449                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3450                return false;
3451            }
3452
3453            intent.setComponent(new ComponentName(
3454                    aInfo.applicationInfo.packageName, aInfo.name));
3455            intent.setFlags(intent.getFlags()&~(
3456                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3457                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3458                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3459                    Intent.FLAG_ACTIVITY_NEW_TASK));
3460
3461            // Okay now we need to start the new activity, replacing the
3462            // currently running activity.  This is a little tricky because
3463            // we want to start the new one as if the current one is finished,
3464            // but not finish the current one first so that there is no flicker.
3465            // And thus...
3466            final boolean wasFinishing = r.finishing;
3467            r.finishing = true;
3468
3469            // Propagate reply information over to the new activity.
3470            final ActivityRecord resultTo = r.resultTo;
3471            final String resultWho = r.resultWho;
3472            final int requestCode = r.requestCode;
3473            r.resultTo = null;
3474            if (resultTo != null) {
3475                resultTo.removeResultsLocked(r, resultWho, requestCode);
3476            }
3477
3478            final long origId = Binder.clearCallingIdentity();
3479            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3480                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3481                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3482                    options, false, null, null);
3483            Binder.restoreCallingIdentity(origId);
3484
3485            r.finishing = wasFinishing;
3486            if (res != ActivityManager.START_SUCCESS) {
3487                return false;
3488            }
3489            return true;
3490        }
3491    }
3492
3493    final int startActivityInPackage(int uid, String callingPackage,
3494            Intent intent, String resolvedType, IBinder resultTo,
3495            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3496                    IActivityContainer container) {
3497
3498        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3499                false, true, "startActivityInPackage", null);
3500
3501        // TODO: Switch to user app stacks here.
3502        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3503                null, null, resultTo, resultWho, requestCode, startFlags,
3504                null, null, null, null, options, userId, container);
3505        return ret;
3506    }
3507
3508    @Override
3509    public final int startActivities(IApplicationThread caller, String callingPackage,
3510            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3511            int userId) {
3512        enforceNotIsolatedCaller("startActivities");
3513        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3514                false, true, "startActivity", null);
3515        // TODO: Switch to user app stacks here.
3516        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3517                resolvedTypes, resultTo, options, userId);
3518        return ret;
3519    }
3520
3521    final int startActivitiesInPackage(int uid, String callingPackage,
3522            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3523            Bundle options, int userId) {
3524
3525        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3526                false, true, "startActivityInPackage", null);
3527        // TODO: Switch to user app stacks here.
3528        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3529                resultTo, options, userId);
3530        return ret;
3531    }
3532
3533    final void addRecentTaskLocked(TaskRecord task) {
3534        int N = mRecentTasks.size();
3535        // Quick case: check if the top-most recent task is the same.
3536        if (N > 0 && mRecentTasks.get(0) == task) {
3537            return;
3538        }
3539        // Another quick case: never add voice sessions.
3540        if (task.voiceSession != null) {
3541            return;
3542        }
3543        // Remove any existing entries that are the same kind of task.
3544        final Intent intent = task.intent;
3545        final boolean document = intent != null && intent.isDocument();
3546        final ComponentName comp = intent.getComponent();
3547
3548        int maxRecents = task.maxRecents - 1;
3549        for (int i=0; i<N; i++) {
3550            TaskRecord tr = mRecentTasks.get(i);
3551            if (task != tr) {
3552                if (task.userId != tr.userId) {
3553                    continue;
3554                }
3555                final Intent trIntent = tr.intent;
3556                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3557                    (intent == null || !intent.filterEquals(trIntent))) {
3558                    continue;
3559                }
3560                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3561                if (document && trIsDocument) {
3562                    // These are the same document activity (not necessarily the same doc).
3563                    if (maxRecents > 0) {
3564                        --maxRecents;
3565                        continue;
3566                    }
3567                    // Hit the maximum number of documents for this task. Fall through
3568                    // and remove this document from recents.
3569                } else if (document || trIsDocument) {
3570                    // Only one of these is a document. Not the droid we're looking for.
3571                    continue;
3572                }
3573            }
3574
3575            // Either task and tr are the same or, their affinities match or their intents match
3576            // and neither of them is a document, or they are documents using the same activity
3577            // and their maxRecents has been reached.
3578            tr.disposeThumbnail();
3579            mRecentTasks.remove(i);
3580            i--;
3581            N--;
3582            if (task.intent == null) {
3583                // If the new recent task we are adding is not fully
3584                // specified, then replace it with the existing recent task.
3585                task = tr;
3586            }
3587            mTaskPersister.notify(tr, false);
3588        }
3589        if (N >= MAX_RECENT_TASKS) {
3590            mRecentTasks.remove(N-1).disposeThumbnail();
3591        }
3592        mRecentTasks.add(0, task);
3593    }
3594
3595    @Override
3596    public void reportActivityFullyDrawn(IBinder token) {
3597        synchronized (this) {
3598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3599            if (r == null) {
3600                return;
3601            }
3602            r.reportFullyDrawnLocked();
3603        }
3604    }
3605
3606    @Override
3607    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3608        synchronized (this) {
3609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3610            if (r == null) {
3611                return;
3612            }
3613            final long origId = Binder.clearCallingIdentity();
3614            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3615            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3616                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3617            if (config != null) {
3618                r.frozenBeforeDestroy = true;
3619                if (!updateConfigurationLocked(config, r, false, false)) {
3620                    mStackSupervisor.resumeTopActivitiesLocked();
3621                }
3622            }
3623            Binder.restoreCallingIdentity(origId);
3624        }
3625    }
3626
3627    @Override
3628    public int getRequestedOrientation(IBinder token) {
3629        synchronized (this) {
3630            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3631            if (r == null) {
3632                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3633            }
3634            return mWindowManager.getAppOrientation(r.appToken);
3635        }
3636    }
3637
3638    /**
3639     * This is the internal entry point for handling Activity.finish().
3640     *
3641     * @param token The Binder token referencing the Activity we want to finish.
3642     * @param resultCode Result code, if any, from this Activity.
3643     * @param resultData Result data (Intent), if any, from this Activity.
3644     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3645     *            the root Activity in the task.
3646     *
3647     * @return Returns true if the activity successfully finished, or false if it is still running.
3648     */
3649    @Override
3650    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3651            boolean finishTask) {
3652        // Refuse possible leaked file descriptors
3653        if (resultData != null && resultData.hasFileDescriptors() == true) {
3654            throw new IllegalArgumentException("File descriptors passed in Intent");
3655        }
3656
3657        synchronized(this) {
3658            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3659            if (r == null) {
3660                return true;
3661            }
3662            // Keep track of the root activity of the task before we finish it
3663            TaskRecord tr = r.task;
3664            ActivityRecord rootR = tr.getRootActivity();
3665            if (mController != null) {
3666                // Find the first activity that is not finishing.
3667                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3668                if (next != null) {
3669                    // ask watcher if this is allowed
3670                    boolean resumeOK = true;
3671                    try {
3672                        resumeOK = mController.activityResuming(next.packageName);
3673                    } catch (RemoteException e) {
3674                        mController = null;
3675                        Watchdog.getInstance().setActivityController(null);
3676                    }
3677
3678                    if (!resumeOK) {
3679                        return false;
3680                    }
3681                }
3682            }
3683            final long origId = Binder.clearCallingIdentity();
3684            try {
3685                boolean res;
3686                if (finishTask && r == rootR) {
3687                    // If requested, remove the task that is associated to this activity only if it
3688                    // was the root activity in the task.  The result code and data is ignored because
3689                    // we don't support returning them across task boundaries.
3690                    res = removeTaskByIdLocked(tr.taskId, 0);
3691                } else {
3692                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3693                            resultData, "app-request", true);
3694                }
3695                return res;
3696            } finally {
3697                Binder.restoreCallingIdentity(origId);
3698            }
3699        }
3700    }
3701
3702    @Override
3703    public final void finishHeavyWeightApp() {
3704        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3705                != PackageManager.PERMISSION_GRANTED) {
3706            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3707                    + Binder.getCallingPid()
3708                    + ", uid=" + Binder.getCallingUid()
3709                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3710            Slog.w(TAG, msg);
3711            throw new SecurityException(msg);
3712        }
3713
3714        synchronized(this) {
3715            if (mHeavyWeightProcess == null) {
3716                return;
3717            }
3718
3719            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3720                    mHeavyWeightProcess.activities);
3721            for (int i=0; i<activities.size(); i++) {
3722                ActivityRecord r = activities.get(i);
3723                if (!r.finishing) {
3724                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3725                            null, "finish-heavy", true);
3726                }
3727            }
3728
3729            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3730                    mHeavyWeightProcess.userId, 0));
3731            mHeavyWeightProcess = null;
3732        }
3733    }
3734
3735    @Override
3736    public void crashApplication(int uid, int initialPid, String packageName,
3737            String message) {
3738        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3739                != PackageManager.PERMISSION_GRANTED) {
3740            String msg = "Permission Denial: crashApplication() from pid="
3741                    + Binder.getCallingPid()
3742                    + ", uid=" + Binder.getCallingUid()
3743                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3744            Slog.w(TAG, msg);
3745            throw new SecurityException(msg);
3746        }
3747
3748        synchronized(this) {
3749            ProcessRecord proc = null;
3750
3751            // Figure out which process to kill.  We don't trust that initialPid
3752            // still has any relation to current pids, so must scan through the
3753            // list.
3754            synchronized (mPidsSelfLocked) {
3755                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3756                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3757                    if (p.uid != uid) {
3758                        continue;
3759                    }
3760                    if (p.pid == initialPid) {
3761                        proc = p;
3762                        break;
3763                    }
3764                    if (p.pkgList.containsKey(packageName)) {
3765                        proc = p;
3766                    }
3767                }
3768            }
3769
3770            if (proc == null) {
3771                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3772                        + " initialPid=" + initialPid
3773                        + " packageName=" + packageName);
3774                return;
3775            }
3776
3777            if (proc.thread != null) {
3778                if (proc.pid == Process.myPid()) {
3779                    Log.w(TAG, "crashApplication: trying to crash self!");
3780                    return;
3781                }
3782                long ident = Binder.clearCallingIdentity();
3783                try {
3784                    proc.thread.scheduleCrash(message);
3785                } catch (RemoteException e) {
3786                }
3787                Binder.restoreCallingIdentity(ident);
3788            }
3789        }
3790    }
3791
3792    @Override
3793    public final void finishSubActivity(IBinder token, String resultWho,
3794            int requestCode) {
3795        synchronized(this) {
3796            final long origId = Binder.clearCallingIdentity();
3797            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3798            if (r != null) {
3799                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3800            }
3801            Binder.restoreCallingIdentity(origId);
3802        }
3803    }
3804
3805    @Override
3806    public boolean finishActivityAffinity(IBinder token) {
3807        synchronized(this) {
3808            final long origId = Binder.clearCallingIdentity();
3809            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3810            boolean res = false;
3811            if (r != null) {
3812                res = r.task.stack.finishActivityAffinityLocked(r);
3813            }
3814            Binder.restoreCallingIdentity(origId);
3815            return res;
3816        }
3817    }
3818
3819    @Override
3820    public boolean willActivityBeVisible(IBinder token) {
3821        synchronized(this) {
3822            ActivityStack stack = ActivityRecord.getStackLocked(token);
3823            if (stack != null) {
3824                return stack.willActivityBeVisibleLocked(token);
3825            }
3826            return false;
3827        }
3828    }
3829
3830    @Override
3831    public void overridePendingTransition(IBinder token, String packageName,
3832            int enterAnim, int exitAnim) {
3833        synchronized(this) {
3834            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3835            if (self == null) {
3836                return;
3837            }
3838
3839            final long origId = Binder.clearCallingIdentity();
3840
3841            if (self.state == ActivityState.RESUMED
3842                    || self.state == ActivityState.PAUSING) {
3843                mWindowManager.overridePendingAppTransition(packageName,
3844                        enterAnim, exitAnim, null);
3845            }
3846
3847            Binder.restoreCallingIdentity(origId);
3848        }
3849    }
3850
3851    /**
3852     * Main function for removing an existing process from the activity manager
3853     * as a result of that process going away.  Clears out all connections
3854     * to the process.
3855     */
3856    private final void handleAppDiedLocked(ProcessRecord app,
3857            boolean restarting, boolean allowRestart) {
3858        int pid = app.pid;
3859        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3860        if (!restarting) {
3861            removeLruProcessLocked(app);
3862            if (pid > 0) {
3863                ProcessList.remove(pid);
3864            }
3865        }
3866
3867        if (mProfileProc == app) {
3868            clearProfilerLocked();
3869        }
3870
3871        // Remove this application's activities from active lists.
3872        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3873
3874        app.activities.clear();
3875
3876        if (app.instrumentationClass != null) {
3877            Slog.w(TAG, "Crash of app " + app.processName
3878                  + " running instrumentation " + app.instrumentationClass);
3879            Bundle info = new Bundle();
3880            info.putString("shortMsg", "Process crashed.");
3881            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3882        }
3883
3884        if (!restarting) {
3885            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3886                // If there was nothing to resume, and we are not already
3887                // restarting this process, but there is a visible activity that
3888                // is hosted by the process...  then make sure all visible
3889                // activities are running, taking care of restarting this
3890                // process.
3891                if (hasVisibleActivities) {
3892                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3893                }
3894            }
3895        }
3896    }
3897
3898    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3899        IBinder threadBinder = thread.asBinder();
3900        // Find the application record.
3901        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3902            ProcessRecord rec = mLruProcesses.get(i);
3903            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3904                return i;
3905            }
3906        }
3907        return -1;
3908    }
3909
3910    final ProcessRecord getRecordForAppLocked(
3911            IApplicationThread thread) {
3912        if (thread == null) {
3913            return null;
3914        }
3915
3916        int appIndex = getLRURecordIndexForAppLocked(thread);
3917        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3918    }
3919
3920    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3921        // If there are no longer any background processes running,
3922        // and the app that died was not running instrumentation,
3923        // then tell everyone we are now low on memory.
3924        boolean haveBg = false;
3925        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3926            ProcessRecord rec = mLruProcesses.get(i);
3927            if (rec.thread != null
3928                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3929                haveBg = true;
3930                break;
3931            }
3932        }
3933
3934        if (!haveBg) {
3935            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3936            if (doReport) {
3937                long now = SystemClock.uptimeMillis();
3938                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3939                    doReport = false;
3940                } else {
3941                    mLastMemUsageReportTime = now;
3942                }
3943            }
3944            final ArrayList<ProcessMemInfo> memInfos
3945                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3946            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3947            long now = SystemClock.uptimeMillis();
3948            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3949                ProcessRecord rec = mLruProcesses.get(i);
3950                if (rec == dyingProc || rec.thread == null) {
3951                    continue;
3952                }
3953                if (doReport) {
3954                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3955                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3956                }
3957                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3958                    // The low memory report is overriding any current
3959                    // state for a GC request.  Make sure to do
3960                    // heavy/important/visible/foreground processes first.
3961                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3962                        rec.lastRequestedGc = 0;
3963                    } else {
3964                        rec.lastRequestedGc = rec.lastLowMemory;
3965                    }
3966                    rec.reportLowMemory = true;
3967                    rec.lastLowMemory = now;
3968                    mProcessesToGc.remove(rec);
3969                    addProcessToGcListLocked(rec);
3970                }
3971            }
3972            if (doReport) {
3973                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3974                mHandler.sendMessage(msg);
3975            }
3976            scheduleAppGcsLocked();
3977        }
3978    }
3979
3980    final void appDiedLocked(ProcessRecord app, int pid,
3981            IApplicationThread thread) {
3982
3983        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3984        synchronized (stats) {
3985            stats.noteProcessDiedLocked(app.info.uid, pid);
3986        }
3987
3988        // Clean up already done if the process has been re-started.
3989        if (app.pid == pid && app.thread != null &&
3990                app.thread.asBinder() == thread.asBinder()) {
3991            boolean doLowMem = app.instrumentationClass == null;
3992            boolean doOomAdj = doLowMem;
3993            if (!app.killedByAm) {
3994                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3995                        + ") has died.");
3996                mAllowLowerMemLevel = true;
3997            } else {
3998                // Note that we always want to do oom adj to update our state with the
3999                // new number of procs.
4000                mAllowLowerMemLevel = false;
4001                doLowMem = false;
4002            }
4003            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4004            if (DEBUG_CLEANUP) Slog.v(
4005                TAG, "Dying app: " + app + ", pid: " + pid
4006                + ", thread: " + thread.asBinder());
4007            handleAppDiedLocked(app, false, true);
4008
4009            if (doOomAdj) {
4010                updateOomAdjLocked();
4011            }
4012            if (doLowMem) {
4013                doLowMemReportIfNeededLocked(app);
4014            }
4015        } else if (app.pid != pid) {
4016            // A new process has already been started.
4017            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4018                    + ") has died and restarted (pid " + app.pid + ").");
4019            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4020        } else if (DEBUG_PROCESSES) {
4021            Slog.d(TAG, "Received spurious death notification for thread "
4022                    + thread.asBinder());
4023        }
4024    }
4025
4026    /**
4027     * If a stack trace dump file is configured, dump process stack traces.
4028     * @param clearTraces causes the dump file to be erased prior to the new
4029     *    traces being written, if true; when false, the new traces will be
4030     *    appended to any existing file content.
4031     * @param firstPids of dalvik VM processes to dump stack traces for first
4032     * @param lastPids of dalvik VM processes to dump stack traces for last
4033     * @param nativeProcs optional list of native process names to dump stack crawls
4034     * @return file containing stack traces, or null if no dump file is configured
4035     */
4036    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4037            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4038        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4039        if (tracesPath == null || tracesPath.length() == 0) {
4040            return null;
4041        }
4042
4043        File tracesFile = new File(tracesPath);
4044        try {
4045            File tracesDir = tracesFile.getParentFile();
4046            if (!tracesDir.exists()) {
4047                tracesFile.mkdirs();
4048                if (!SELinux.restorecon(tracesDir)) {
4049                    return null;
4050                }
4051            }
4052            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4053
4054            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4055            tracesFile.createNewFile();
4056            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4057        } catch (IOException e) {
4058            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4059            return null;
4060        }
4061
4062        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4063        return tracesFile;
4064    }
4065
4066    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4067            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4068        // Use a FileObserver to detect when traces finish writing.
4069        // The order of traces is considered important to maintain for legibility.
4070        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4071            @Override
4072            public synchronized void onEvent(int event, String path) { notify(); }
4073        };
4074
4075        try {
4076            observer.startWatching();
4077
4078            // First collect all of the stacks of the most important pids.
4079            if (firstPids != null) {
4080                try {
4081                    int num = firstPids.size();
4082                    for (int i = 0; i < num; i++) {
4083                        synchronized (observer) {
4084                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4085                            observer.wait(200);  // Wait for write-close, give up after 200msec
4086                        }
4087                    }
4088                } catch (InterruptedException e) {
4089                    Log.wtf(TAG, e);
4090                }
4091            }
4092
4093            // Next collect the stacks of the native pids
4094            if (nativeProcs != null) {
4095                int[] pids = Process.getPidsForCommands(nativeProcs);
4096                if (pids != null) {
4097                    for (int pid : pids) {
4098                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4099                    }
4100                }
4101            }
4102
4103            // Lastly, measure CPU usage.
4104            if (processCpuTracker != null) {
4105                processCpuTracker.init();
4106                System.gc();
4107                processCpuTracker.update();
4108                try {
4109                    synchronized (processCpuTracker) {
4110                        processCpuTracker.wait(500); // measure over 1/2 second.
4111                    }
4112                } catch (InterruptedException e) {
4113                }
4114                processCpuTracker.update();
4115
4116                // We'll take the stack crawls of just the top apps using CPU.
4117                final int N = processCpuTracker.countWorkingStats();
4118                int numProcs = 0;
4119                for (int i=0; i<N && numProcs<5; i++) {
4120                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4121                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4122                        numProcs++;
4123                        try {
4124                            synchronized (observer) {
4125                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4126                                observer.wait(200);  // Wait for write-close, give up after 200msec
4127                            }
4128                        } catch (InterruptedException e) {
4129                            Log.wtf(TAG, e);
4130                        }
4131
4132                    }
4133                }
4134            }
4135        } finally {
4136            observer.stopWatching();
4137        }
4138    }
4139
4140    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4141        if (true || IS_USER_BUILD) {
4142            return;
4143        }
4144        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4145        if (tracesPath == null || tracesPath.length() == 0) {
4146            return;
4147        }
4148
4149        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4150        StrictMode.allowThreadDiskWrites();
4151        try {
4152            final File tracesFile = new File(tracesPath);
4153            final File tracesDir = tracesFile.getParentFile();
4154            final File tracesTmp = new File(tracesDir, "__tmp__");
4155            try {
4156                if (!tracesDir.exists()) {
4157                    tracesFile.mkdirs();
4158                    if (!SELinux.restorecon(tracesDir.getPath())) {
4159                        return;
4160                    }
4161                }
4162                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4163
4164                if (tracesFile.exists()) {
4165                    tracesTmp.delete();
4166                    tracesFile.renameTo(tracesTmp);
4167                }
4168                StringBuilder sb = new StringBuilder();
4169                Time tobj = new Time();
4170                tobj.set(System.currentTimeMillis());
4171                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4172                sb.append(": ");
4173                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4174                sb.append(" since ");
4175                sb.append(msg);
4176                FileOutputStream fos = new FileOutputStream(tracesFile);
4177                fos.write(sb.toString().getBytes());
4178                if (app == null) {
4179                    fos.write("\n*** No application process!".getBytes());
4180                }
4181                fos.close();
4182                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4183            } catch (IOException e) {
4184                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4185                return;
4186            }
4187
4188            if (app != null) {
4189                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4190                firstPids.add(app.pid);
4191                dumpStackTraces(tracesPath, firstPids, null, null, null);
4192            }
4193
4194            File lastTracesFile = null;
4195            File curTracesFile = null;
4196            for (int i=9; i>=0; i--) {
4197                String name = String.format(Locale.US, "slow%02d.txt", i);
4198                curTracesFile = new File(tracesDir, name);
4199                if (curTracesFile.exists()) {
4200                    if (lastTracesFile != null) {
4201                        curTracesFile.renameTo(lastTracesFile);
4202                    } else {
4203                        curTracesFile.delete();
4204                    }
4205                }
4206                lastTracesFile = curTracesFile;
4207            }
4208            tracesFile.renameTo(curTracesFile);
4209            if (tracesTmp.exists()) {
4210                tracesTmp.renameTo(tracesFile);
4211            }
4212        } finally {
4213            StrictMode.setThreadPolicy(oldPolicy);
4214        }
4215    }
4216
4217    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4218            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4219        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4220        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4221
4222        if (mController != null) {
4223            try {
4224                // 0 == continue, -1 = kill process immediately
4225                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4226                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4227            } catch (RemoteException e) {
4228                mController = null;
4229                Watchdog.getInstance().setActivityController(null);
4230            }
4231        }
4232
4233        long anrTime = SystemClock.uptimeMillis();
4234        if (MONITOR_CPU_USAGE) {
4235            updateCpuStatsNow();
4236        }
4237
4238        synchronized (this) {
4239            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4240            if (mShuttingDown) {
4241                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4242                return;
4243            } else if (app.notResponding) {
4244                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4245                return;
4246            } else if (app.crashing) {
4247                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4248                return;
4249            }
4250
4251            // In case we come through here for the same app before completing
4252            // this one, mark as anring now so we will bail out.
4253            app.notResponding = true;
4254
4255            // Log the ANR to the event log.
4256            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4257                    app.processName, app.info.flags, annotation);
4258
4259            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4260            firstPids.add(app.pid);
4261
4262            int parentPid = app.pid;
4263            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4264            if (parentPid != app.pid) firstPids.add(parentPid);
4265
4266            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4267
4268            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4269                ProcessRecord r = mLruProcesses.get(i);
4270                if (r != null && r.thread != null) {
4271                    int pid = r.pid;
4272                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4273                        if (r.persistent) {
4274                            firstPids.add(pid);
4275                        } else {
4276                            lastPids.put(pid, Boolean.TRUE);
4277                        }
4278                    }
4279                }
4280            }
4281        }
4282
4283        // Log the ANR to the main log.
4284        StringBuilder info = new StringBuilder();
4285        info.setLength(0);
4286        info.append("ANR in ").append(app.processName);
4287        if (activity != null && activity.shortComponentName != null) {
4288            info.append(" (").append(activity.shortComponentName).append(")");
4289        }
4290        info.append("\n");
4291        info.append("PID: ").append(app.pid).append("\n");
4292        if (annotation != null) {
4293            info.append("Reason: ").append(annotation).append("\n");
4294        }
4295        if (parent != null && parent != activity) {
4296            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4297        }
4298
4299        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4300
4301        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4302                NATIVE_STACKS_OF_INTEREST);
4303
4304        String cpuInfo = null;
4305        if (MONITOR_CPU_USAGE) {
4306            updateCpuStatsNow();
4307            synchronized (mProcessCpuThread) {
4308                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4309            }
4310            info.append(processCpuTracker.printCurrentLoad());
4311            info.append(cpuInfo);
4312        }
4313
4314        info.append(processCpuTracker.printCurrentState(anrTime));
4315
4316        Slog.e(TAG, info.toString());
4317        if (tracesFile == null) {
4318            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4319            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4320        }
4321
4322        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4323                cpuInfo, tracesFile, null);
4324
4325        if (mController != null) {
4326            try {
4327                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4328                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4329                if (res != 0) {
4330                    if (res < 0 && app.pid != MY_PID) {
4331                        Process.killProcess(app.pid);
4332                    } else {
4333                        synchronized (this) {
4334                            mServices.scheduleServiceTimeoutLocked(app);
4335                        }
4336                    }
4337                    return;
4338                }
4339            } catch (RemoteException e) {
4340                mController = null;
4341                Watchdog.getInstance().setActivityController(null);
4342            }
4343        }
4344
4345        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4346        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4347                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4348
4349        synchronized (this) {
4350            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4351                killUnneededProcessLocked(app, "background ANR");
4352                return;
4353            }
4354
4355            // Set the app's notResponding state, and look up the errorReportReceiver
4356            makeAppNotRespondingLocked(app,
4357                    activity != null ? activity.shortComponentName : null,
4358                    annotation != null ? "ANR " + annotation : "ANR",
4359                    info.toString());
4360
4361            // Bring up the infamous App Not Responding dialog
4362            Message msg = Message.obtain();
4363            HashMap<String, Object> map = new HashMap<String, Object>();
4364            msg.what = SHOW_NOT_RESPONDING_MSG;
4365            msg.obj = map;
4366            msg.arg1 = aboveSystem ? 1 : 0;
4367            map.put("app", app);
4368            if (activity != null) {
4369                map.put("activity", activity);
4370            }
4371
4372            mHandler.sendMessage(msg);
4373        }
4374    }
4375
4376    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4377        if (!mLaunchWarningShown) {
4378            mLaunchWarningShown = true;
4379            mHandler.post(new Runnable() {
4380                @Override
4381                public void run() {
4382                    synchronized (ActivityManagerService.this) {
4383                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4384                        d.show();
4385                        mHandler.postDelayed(new Runnable() {
4386                            @Override
4387                            public void run() {
4388                                synchronized (ActivityManagerService.this) {
4389                                    d.dismiss();
4390                                    mLaunchWarningShown = false;
4391                                }
4392                            }
4393                        }, 4000);
4394                    }
4395                }
4396            });
4397        }
4398    }
4399
4400    @Override
4401    public boolean clearApplicationUserData(final String packageName,
4402            final IPackageDataObserver observer, int userId) {
4403        enforceNotIsolatedCaller("clearApplicationUserData");
4404        int uid = Binder.getCallingUid();
4405        int pid = Binder.getCallingPid();
4406        userId = handleIncomingUser(pid, uid,
4407                userId, false, true, "clearApplicationUserData", null);
4408        long callingId = Binder.clearCallingIdentity();
4409        try {
4410            IPackageManager pm = AppGlobals.getPackageManager();
4411            int pkgUid = -1;
4412            synchronized(this) {
4413                try {
4414                    pkgUid = pm.getPackageUid(packageName, userId);
4415                } catch (RemoteException e) {
4416                }
4417                if (pkgUid == -1) {
4418                    Slog.w(TAG, "Invalid packageName: " + packageName);
4419                    if (observer != null) {
4420                        try {
4421                            observer.onRemoveCompleted(packageName, false);
4422                        } catch (RemoteException e) {
4423                            Slog.i(TAG, "Observer no longer exists.");
4424                        }
4425                    }
4426                    return false;
4427                }
4428                if (uid == pkgUid || checkComponentPermission(
4429                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4430                        pid, uid, -1, true)
4431                        == PackageManager.PERMISSION_GRANTED) {
4432                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4433                } else {
4434                    throw new SecurityException("PID " + pid + " does not have permission "
4435                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4436                                    + " of package " + packageName);
4437                }
4438            }
4439
4440            try {
4441                // Clear application user data
4442                pm.clearApplicationUserData(packageName, observer, userId);
4443
4444                // Remove all permissions granted from/to this package
4445                removeUriPermissionsForPackageLocked(packageName, userId, true);
4446
4447                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4448                        Uri.fromParts("package", packageName, null));
4449                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4450                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4451                        null, null, 0, null, null, null, false, false, userId);
4452            } catch (RemoteException e) {
4453            }
4454        } finally {
4455            Binder.restoreCallingIdentity(callingId);
4456        }
4457        return true;
4458    }
4459
4460    @Override
4461    public void killBackgroundProcesses(final String packageName, int userId) {
4462        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4463                != PackageManager.PERMISSION_GRANTED &&
4464                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4465                        != PackageManager.PERMISSION_GRANTED) {
4466            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4467                    + Binder.getCallingPid()
4468                    + ", uid=" + Binder.getCallingUid()
4469                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4470            Slog.w(TAG, msg);
4471            throw new SecurityException(msg);
4472        }
4473
4474        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4475                userId, true, true, "killBackgroundProcesses", null);
4476        long callingId = Binder.clearCallingIdentity();
4477        try {
4478            IPackageManager pm = AppGlobals.getPackageManager();
4479            synchronized(this) {
4480                int appId = -1;
4481                try {
4482                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4483                } catch (RemoteException e) {
4484                }
4485                if (appId == -1) {
4486                    Slog.w(TAG, "Invalid packageName: " + packageName);
4487                    return;
4488                }
4489                killPackageProcessesLocked(packageName, appId, userId,
4490                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4491            }
4492        } finally {
4493            Binder.restoreCallingIdentity(callingId);
4494        }
4495    }
4496
4497    @Override
4498    public void killAllBackgroundProcesses() {
4499        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4500                != PackageManager.PERMISSION_GRANTED) {
4501            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4502                    + Binder.getCallingPid()
4503                    + ", uid=" + Binder.getCallingUid()
4504                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4505            Slog.w(TAG, msg);
4506            throw new SecurityException(msg);
4507        }
4508
4509        long callingId = Binder.clearCallingIdentity();
4510        try {
4511            synchronized(this) {
4512                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4513                final int NP = mProcessNames.getMap().size();
4514                for (int ip=0; ip<NP; ip++) {
4515                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4516                    final int NA = apps.size();
4517                    for (int ia=0; ia<NA; ia++) {
4518                        ProcessRecord app = apps.valueAt(ia);
4519                        if (app.persistent) {
4520                            // we don't kill persistent processes
4521                            continue;
4522                        }
4523                        if (app.removed) {
4524                            procs.add(app);
4525                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4526                            app.removed = true;
4527                            procs.add(app);
4528                        }
4529                    }
4530                }
4531
4532                int N = procs.size();
4533                for (int i=0; i<N; i++) {
4534                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4535                }
4536                mAllowLowerMemLevel = true;
4537                updateOomAdjLocked();
4538                doLowMemReportIfNeededLocked(null);
4539            }
4540        } finally {
4541            Binder.restoreCallingIdentity(callingId);
4542        }
4543    }
4544
4545    @Override
4546    public void forceStopPackage(final String packageName, int userId) {
4547        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4548                != PackageManager.PERMISSION_GRANTED) {
4549            String msg = "Permission Denial: forceStopPackage() from pid="
4550                    + Binder.getCallingPid()
4551                    + ", uid=" + Binder.getCallingUid()
4552                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4553            Slog.w(TAG, msg);
4554            throw new SecurityException(msg);
4555        }
4556        final int callingPid = Binder.getCallingPid();
4557        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4558                userId, true, true, "forceStopPackage", null);
4559        long callingId = Binder.clearCallingIdentity();
4560        try {
4561            IPackageManager pm = AppGlobals.getPackageManager();
4562            synchronized(this) {
4563                int[] users = userId == UserHandle.USER_ALL
4564                        ? getUsersLocked() : new int[] { userId };
4565                for (int user : users) {
4566                    int pkgUid = -1;
4567                    try {
4568                        pkgUid = pm.getPackageUid(packageName, user);
4569                    } catch (RemoteException e) {
4570                    }
4571                    if (pkgUid == -1) {
4572                        Slog.w(TAG, "Invalid packageName: " + packageName);
4573                        continue;
4574                    }
4575                    try {
4576                        pm.setPackageStoppedState(packageName, true, user);
4577                    } catch (RemoteException e) {
4578                    } catch (IllegalArgumentException e) {
4579                        Slog.w(TAG, "Failed trying to unstop package "
4580                                + packageName + ": " + e);
4581                    }
4582                    if (isUserRunningLocked(user, false)) {
4583                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4584                    }
4585                }
4586            }
4587        } finally {
4588            Binder.restoreCallingIdentity(callingId);
4589        }
4590    }
4591
4592    /*
4593     * The pkg name and app id have to be specified.
4594     */
4595    @Override
4596    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4597        if (pkg == null) {
4598            return;
4599        }
4600        // Make sure the uid is valid.
4601        if (appid < 0) {
4602            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4603            return;
4604        }
4605        int callerUid = Binder.getCallingUid();
4606        // Only the system server can kill an application
4607        if (callerUid == Process.SYSTEM_UID) {
4608            // Post an aysnc message to kill the application
4609            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4610            msg.arg1 = appid;
4611            msg.arg2 = 0;
4612            Bundle bundle = new Bundle();
4613            bundle.putString("pkg", pkg);
4614            bundle.putString("reason", reason);
4615            msg.obj = bundle;
4616            mHandler.sendMessage(msg);
4617        } else {
4618            throw new SecurityException(callerUid + " cannot kill pkg: " +
4619                    pkg);
4620        }
4621    }
4622
4623    @Override
4624    public void closeSystemDialogs(String reason) {
4625        enforceNotIsolatedCaller("closeSystemDialogs");
4626
4627        final int pid = Binder.getCallingPid();
4628        final int uid = Binder.getCallingUid();
4629        final long origId = Binder.clearCallingIdentity();
4630        try {
4631            synchronized (this) {
4632                // Only allow this from foreground processes, so that background
4633                // applications can't abuse it to prevent system UI from being shown.
4634                if (uid >= Process.FIRST_APPLICATION_UID) {
4635                    ProcessRecord proc;
4636                    synchronized (mPidsSelfLocked) {
4637                        proc = mPidsSelfLocked.get(pid);
4638                    }
4639                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4640                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4641                                + " from background process " + proc);
4642                        return;
4643                    }
4644                }
4645                closeSystemDialogsLocked(reason);
4646            }
4647        } finally {
4648            Binder.restoreCallingIdentity(origId);
4649        }
4650    }
4651
4652    void closeSystemDialogsLocked(String reason) {
4653        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4654        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4655                | Intent.FLAG_RECEIVER_FOREGROUND);
4656        if (reason != null) {
4657            intent.putExtra("reason", reason);
4658        }
4659        mWindowManager.closeSystemDialogs(reason);
4660
4661        mStackSupervisor.closeSystemDialogsLocked();
4662
4663        broadcastIntentLocked(null, null, intent, null,
4664                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4665                Process.SYSTEM_UID, UserHandle.USER_ALL);
4666    }
4667
4668    @Override
4669    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4670        enforceNotIsolatedCaller("getProcessMemoryInfo");
4671        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4672        for (int i=pids.length-1; i>=0; i--) {
4673            ProcessRecord proc;
4674            int oomAdj;
4675            synchronized (this) {
4676                synchronized (mPidsSelfLocked) {
4677                    proc = mPidsSelfLocked.get(pids[i]);
4678                    oomAdj = proc != null ? proc.setAdj : 0;
4679                }
4680            }
4681            infos[i] = new Debug.MemoryInfo();
4682            Debug.getMemoryInfo(pids[i], infos[i]);
4683            if (proc != null) {
4684                synchronized (this) {
4685                    if (proc.thread != null && proc.setAdj == oomAdj) {
4686                        // Record this for posterity if the process has been stable.
4687                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4688                                infos[i].getTotalUss(), false, proc.pkgList);
4689                    }
4690                }
4691            }
4692        }
4693        return infos;
4694    }
4695
4696    @Override
4697    public long[] getProcessPss(int[] pids) {
4698        enforceNotIsolatedCaller("getProcessPss");
4699        long[] pss = new long[pids.length];
4700        for (int i=pids.length-1; i>=0; i--) {
4701            ProcessRecord proc;
4702            int oomAdj;
4703            synchronized (this) {
4704                synchronized (mPidsSelfLocked) {
4705                    proc = mPidsSelfLocked.get(pids[i]);
4706                    oomAdj = proc != null ? proc.setAdj : 0;
4707                }
4708            }
4709            long[] tmpUss = new long[1];
4710            pss[i] = Debug.getPss(pids[i], tmpUss);
4711            if (proc != null) {
4712                synchronized (this) {
4713                    if (proc.thread != null && proc.setAdj == oomAdj) {
4714                        // Record this for posterity if the process has been stable.
4715                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4716                    }
4717                }
4718            }
4719        }
4720        return pss;
4721    }
4722
4723    @Override
4724    public void killApplicationProcess(String processName, int uid) {
4725        if (processName == null) {
4726            return;
4727        }
4728
4729        int callerUid = Binder.getCallingUid();
4730        // Only the system server can kill an application
4731        if (callerUid == Process.SYSTEM_UID) {
4732            synchronized (this) {
4733                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4734                if (app != null && app.thread != null) {
4735                    try {
4736                        app.thread.scheduleSuicide();
4737                    } catch (RemoteException e) {
4738                        // If the other end already died, then our work here is done.
4739                    }
4740                } else {
4741                    Slog.w(TAG, "Process/uid not found attempting kill of "
4742                            + processName + " / " + uid);
4743                }
4744            }
4745        } else {
4746            throw new SecurityException(callerUid + " cannot kill app process: " +
4747                    processName);
4748        }
4749    }
4750
4751    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4752        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4753                false, true, false, false, UserHandle.getUserId(uid), reason);
4754        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4755                Uri.fromParts("package", packageName, null));
4756        if (!mProcessesReady) {
4757            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4758                    | Intent.FLAG_RECEIVER_FOREGROUND);
4759        }
4760        intent.putExtra(Intent.EXTRA_UID, uid);
4761        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4762        broadcastIntentLocked(null, null, intent,
4763                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4764                false, false,
4765                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4766    }
4767
4768    private void forceStopUserLocked(int userId, String reason) {
4769        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4770        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4771        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4772                | Intent.FLAG_RECEIVER_FOREGROUND);
4773        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4774        broadcastIntentLocked(null, null, intent,
4775                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4776                false, false,
4777                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4778    }
4779
4780    private final boolean killPackageProcessesLocked(String packageName, int appId,
4781            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4782            boolean doit, boolean evenPersistent, String reason) {
4783        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4784
4785        // Remove all processes this package may have touched: all with the
4786        // same UID (except for the system or root user), and all whose name
4787        // matches the package name.
4788        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4789        final int NP = mProcessNames.getMap().size();
4790        for (int ip=0; ip<NP; ip++) {
4791            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4792            final int NA = apps.size();
4793            for (int ia=0; ia<NA; ia++) {
4794                ProcessRecord app = apps.valueAt(ia);
4795                if (app.persistent && !evenPersistent) {
4796                    // we don't kill persistent processes
4797                    continue;
4798                }
4799                if (app.removed) {
4800                    if (doit) {
4801                        procs.add(app);
4802                    }
4803                    continue;
4804                }
4805
4806                // Skip process if it doesn't meet our oom adj requirement.
4807                if (app.setAdj < minOomAdj) {
4808                    continue;
4809                }
4810
4811                // If no package is specified, we call all processes under the
4812                // give user id.
4813                if (packageName == null) {
4814                    if (app.userId != userId) {
4815                        continue;
4816                    }
4817                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4818                        continue;
4819                    }
4820                // Package has been specified, we want to hit all processes
4821                // that match it.  We need to qualify this by the processes
4822                // that are running under the specified app and user ID.
4823                } else {
4824                    if (UserHandle.getAppId(app.uid) != appId) {
4825                        continue;
4826                    }
4827                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4828                        continue;
4829                    }
4830                    if (!app.pkgList.containsKey(packageName)) {
4831                        continue;
4832                    }
4833                }
4834
4835                // Process has passed all conditions, kill it!
4836                if (!doit) {
4837                    return true;
4838                }
4839                app.removed = true;
4840                procs.add(app);
4841            }
4842        }
4843
4844        int N = procs.size();
4845        for (int i=0; i<N; i++) {
4846            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4847        }
4848        updateOomAdjLocked();
4849        return N > 0;
4850    }
4851
4852    private final boolean forceStopPackageLocked(String name, int appId,
4853            boolean callerWillRestart, boolean purgeCache, boolean doit,
4854            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4855        int i;
4856        int N;
4857
4858        if (userId == UserHandle.USER_ALL && name == null) {
4859            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4860        }
4861
4862        if (appId < 0 && name != null) {
4863            try {
4864                appId = UserHandle.getAppId(
4865                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4866            } catch (RemoteException e) {
4867            }
4868        }
4869
4870        if (doit) {
4871            if (name != null) {
4872                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4873                        + " user=" + userId + ": " + reason);
4874            } else {
4875                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4876            }
4877
4878            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4879            for (int ip=pmap.size()-1; ip>=0; ip--) {
4880                SparseArray<Long> ba = pmap.valueAt(ip);
4881                for (i=ba.size()-1; i>=0; i--) {
4882                    boolean remove = false;
4883                    final int entUid = ba.keyAt(i);
4884                    if (name != null) {
4885                        if (userId == UserHandle.USER_ALL) {
4886                            if (UserHandle.getAppId(entUid) == appId) {
4887                                remove = true;
4888                            }
4889                        } else {
4890                            if (entUid == UserHandle.getUid(userId, appId)) {
4891                                remove = true;
4892                            }
4893                        }
4894                    } else if (UserHandle.getUserId(entUid) == userId) {
4895                        remove = true;
4896                    }
4897                    if (remove) {
4898                        ba.removeAt(i);
4899                    }
4900                }
4901                if (ba.size() == 0) {
4902                    pmap.removeAt(ip);
4903                }
4904            }
4905        }
4906
4907        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4908                -100, callerWillRestart, true, doit, evenPersistent,
4909                name == null ? ("stop user " + userId) : ("stop " + name));
4910
4911        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4912            if (!doit) {
4913                return true;
4914            }
4915            didSomething = true;
4916        }
4917
4918        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4919            if (!doit) {
4920                return true;
4921            }
4922            didSomething = true;
4923        }
4924
4925        if (name == null) {
4926            // Remove all sticky broadcasts from this user.
4927            mStickyBroadcasts.remove(userId);
4928        }
4929
4930        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4931        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4932                userId, providers)) {
4933            if (!doit) {
4934                return true;
4935            }
4936            didSomething = true;
4937        }
4938        N = providers.size();
4939        for (i=0; i<N; i++) {
4940            removeDyingProviderLocked(null, providers.get(i), true);
4941        }
4942
4943        // Remove transient permissions granted from/to this package/user
4944        removeUriPermissionsForPackageLocked(name, userId, false);
4945
4946        if (name == null || uninstalling) {
4947            // Remove pending intents.  For now we only do this when force
4948            // stopping users, because we have some problems when doing this
4949            // for packages -- app widgets are not currently cleaned up for
4950            // such packages, so they can be left with bad pending intents.
4951            if (mIntentSenderRecords.size() > 0) {
4952                Iterator<WeakReference<PendingIntentRecord>> it
4953                        = mIntentSenderRecords.values().iterator();
4954                while (it.hasNext()) {
4955                    WeakReference<PendingIntentRecord> wpir = it.next();
4956                    if (wpir == null) {
4957                        it.remove();
4958                        continue;
4959                    }
4960                    PendingIntentRecord pir = wpir.get();
4961                    if (pir == null) {
4962                        it.remove();
4963                        continue;
4964                    }
4965                    if (name == null) {
4966                        // Stopping user, remove all objects for the user.
4967                        if (pir.key.userId != userId) {
4968                            // Not the same user, skip it.
4969                            continue;
4970                        }
4971                    } else {
4972                        if (UserHandle.getAppId(pir.uid) != appId) {
4973                            // Different app id, skip it.
4974                            continue;
4975                        }
4976                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4977                            // Different user, skip it.
4978                            continue;
4979                        }
4980                        if (!pir.key.packageName.equals(name)) {
4981                            // Different package, skip it.
4982                            continue;
4983                        }
4984                    }
4985                    if (!doit) {
4986                        return true;
4987                    }
4988                    didSomething = true;
4989                    it.remove();
4990                    pir.canceled = true;
4991                    if (pir.key.activity != null) {
4992                        pir.key.activity.pendingResults.remove(pir.ref);
4993                    }
4994                }
4995            }
4996        }
4997
4998        if (doit) {
4999            if (purgeCache && name != null) {
5000                AttributeCache ac = AttributeCache.instance();
5001                if (ac != null) {
5002                    ac.removePackage(name);
5003                }
5004            }
5005            if (mBooted) {
5006                mStackSupervisor.resumeTopActivitiesLocked();
5007                mStackSupervisor.scheduleIdleLocked();
5008            }
5009        }
5010
5011        return didSomething;
5012    }
5013
5014    private final boolean removeProcessLocked(ProcessRecord app,
5015            boolean callerWillRestart, boolean allowRestart, String reason) {
5016        final String name = app.processName;
5017        final int uid = app.uid;
5018        if (DEBUG_PROCESSES) Slog.d(
5019            TAG, "Force removing proc " + app.toShortString() + " (" + name
5020            + "/" + uid + ")");
5021
5022        mProcessNames.remove(name, uid);
5023        mIsolatedProcesses.remove(app.uid);
5024        if (mHeavyWeightProcess == app) {
5025            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5026                    mHeavyWeightProcess.userId, 0));
5027            mHeavyWeightProcess = null;
5028        }
5029        boolean needRestart = false;
5030        if (app.pid > 0 && app.pid != MY_PID) {
5031            int pid = app.pid;
5032            synchronized (mPidsSelfLocked) {
5033                mPidsSelfLocked.remove(pid);
5034                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5035            }
5036            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5037                    app.processName, app.info.uid);
5038            if (app.isolated) {
5039                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5040            }
5041            killUnneededProcessLocked(app, reason);
5042            handleAppDiedLocked(app, true, allowRestart);
5043            removeLruProcessLocked(app);
5044
5045            if (app.persistent && !app.isolated) {
5046                if (!callerWillRestart) {
5047                    addAppLocked(app.info, false, null /* ABI override */);
5048                } else {
5049                    needRestart = true;
5050                }
5051            }
5052        } else {
5053            mRemovedProcesses.add(app);
5054        }
5055
5056        return needRestart;
5057    }
5058
5059    private final void processStartTimedOutLocked(ProcessRecord app) {
5060        final int pid = app.pid;
5061        boolean gone = false;
5062        synchronized (mPidsSelfLocked) {
5063            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5064            if (knownApp != null && knownApp.thread == null) {
5065                mPidsSelfLocked.remove(pid);
5066                gone = true;
5067            }
5068        }
5069
5070        if (gone) {
5071            Slog.w(TAG, "Process " + app + " failed to attach");
5072            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5073                    pid, app.uid, app.processName);
5074            mProcessNames.remove(app.processName, app.uid);
5075            mIsolatedProcesses.remove(app.uid);
5076            if (mHeavyWeightProcess == app) {
5077                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5078                        mHeavyWeightProcess.userId, 0));
5079                mHeavyWeightProcess = null;
5080            }
5081            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5082                    app.processName, app.info.uid);
5083            if (app.isolated) {
5084                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5085            }
5086            // Take care of any launching providers waiting for this process.
5087            checkAppInLaunchingProvidersLocked(app, true);
5088            // Take care of any services that are waiting for the process.
5089            mServices.processStartTimedOutLocked(app);
5090            killUnneededProcessLocked(app, "start timeout");
5091            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5092                Slog.w(TAG, "Unattached app died before backup, skipping");
5093                try {
5094                    IBackupManager bm = IBackupManager.Stub.asInterface(
5095                            ServiceManager.getService(Context.BACKUP_SERVICE));
5096                    bm.agentDisconnected(app.info.packageName);
5097                } catch (RemoteException e) {
5098                    // Can't happen; the backup manager is local
5099                }
5100            }
5101            if (isPendingBroadcastProcessLocked(pid)) {
5102                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5103                skipPendingBroadcastLocked(pid);
5104            }
5105        } else {
5106            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5107        }
5108    }
5109
5110    private final boolean attachApplicationLocked(IApplicationThread thread,
5111            int pid) {
5112
5113        // Find the application record that is being attached...  either via
5114        // the pid if we are running in multiple processes, or just pull the
5115        // next app record if we are emulating process with anonymous threads.
5116        ProcessRecord app;
5117        if (pid != MY_PID && pid >= 0) {
5118            synchronized (mPidsSelfLocked) {
5119                app = mPidsSelfLocked.get(pid);
5120            }
5121        } else {
5122            app = null;
5123        }
5124
5125        if (app == null) {
5126            Slog.w(TAG, "No pending application record for pid " + pid
5127                    + " (IApplicationThread " + thread + "); dropping process");
5128            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5129            if (pid > 0 && pid != MY_PID) {
5130                Process.killProcessQuiet(pid);
5131            } else {
5132                try {
5133                    thread.scheduleExit();
5134                } catch (Exception e) {
5135                    // Ignore exceptions.
5136                }
5137            }
5138            return false;
5139        }
5140
5141        // If this application record is still attached to a previous
5142        // process, clean it up now.
5143        if (app.thread != null) {
5144            handleAppDiedLocked(app, true, true);
5145        }
5146
5147        // Tell the process all about itself.
5148
5149        if (localLOGV) Slog.v(
5150                TAG, "Binding process pid " + pid + " to record " + app);
5151
5152        final String processName = app.processName;
5153        try {
5154            AppDeathRecipient adr = new AppDeathRecipient(
5155                    app, pid, thread);
5156            thread.asBinder().linkToDeath(adr, 0);
5157            app.deathRecipient = adr;
5158        } catch (RemoteException e) {
5159            app.resetPackageList(mProcessStats);
5160            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5161            return false;
5162        }
5163
5164        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5165
5166        app.makeActive(thread, mProcessStats);
5167        app.curAdj = app.setAdj = -100;
5168        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5169        app.forcingToForeground = null;
5170        updateProcessForegroundLocked(app, false, false);
5171        app.hasShownUi = false;
5172        app.debugging = false;
5173        app.cached = false;
5174
5175        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5176
5177        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5178        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5179
5180        if (!normalMode) {
5181            Slog.i(TAG, "Launching preboot mode app: " + app);
5182        }
5183
5184        if (localLOGV) Slog.v(
5185            TAG, "New app record " + app
5186            + " thread=" + thread.asBinder() + " pid=" + pid);
5187        try {
5188            int testMode = IApplicationThread.DEBUG_OFF;
5189            if (mDebugApp != null && mDebugApp.equals(processName)) {
5190                testMode = mWaitForDebugger
5191                    ? IApplicationThread.DEBUG_WAIT
5192                    : IApplicationThread.DEBUG_ON;
5193                app.debugging = true;
5194                if (mDebugTransient) {
5195                    mDebugApp = mOrigDebugApp;
5196                    mWaitForDebugger = mOrigWaitForDebugger;
5197                }
5198            }
5199            String profileFile = app.instrumentationProfileFile;
5200            ParcelFileDescriptor profileFd = null;
5201            boolean profileAutoStop = false;
5202            if (mProfileApp != null && mProfileApp.equals(processName)) {
5203                mProfileProc = app;
5204                profileFile = mProfileFile;
5205                profileFd = mProfileFd;
5206                profileAutoStop = mAutoStopProfiler;
5207            }
5208            boolean enableOpenGlTrace = false;
5209            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5210                enableOpenGlTrace = true;
5211                mOpenGlTraceApp = null;
5212            }
5213
5214            // If the app is being launched for restore or full backup, set it up specially
5215            boolean isRestrictedBackupMode = false;
5216            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5217                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5218                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5219                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5220            }
5221
5222            ensurePackageDexOpt(app.instrumentationInfo != null
5223                    ? app.instrumentationInfo.packageName
5224                    : app.info.packageName);
5225            if (app.instrumentationClass != null) {
5226                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5227            }
5228            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5229                    + processName + " with config " + mConfiguration);
5230            ApplicationInfo appInfo = app.instrumentationInfo != null
5231                    ? app.instrumentationInfo : app.info;
5232            app.compat = compatibilityInfoForPackageLocked(appInfo);
5233            if (profileFd != null) {
5234                profileFd = profileFd.dup();
5235            }
5236            thread.bindApplication(processName, appInfo, providers,
5237                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5238                    app.instrumentationArguments, app.instrumentationWatcher,
5239                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5240                    isRestrictedBackupMode || !normalMode, app.persistent,
5241                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5242                    mCoreSettingsObserver.getCoreSettingsLocked());
5243            updateLruProcessLocked(app, false, null);
5244            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5245        } catch (Exception e) {
5246            // todo: Yikes!  What should we do?  For now we will try to
5247            // start another process, but that could easily get us in
5248            // an infinite loop of restarting processes...
5249            Slog.w(TAG, "Exception thrown during bind!", e);
5250
5251            app.resetPackageList(mProcessStats);
5252            app.unlinkDeathRecipient();
5253            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5254            return false;
5255        }
5256
5257        // Remove this record from the list of starting applications.
5258        mPersistentStartingProcesses.remove(app);
5259        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5260                "Attach application locked removing on hold: " + app);
5261        mProcessesOnHold.remove(app);
5262
5263        boolean badApp = false;
5264        boolean didSomething = false;
5265
5266        // See if the top visible activity is waiting to run in this process...
5267        if (normalMode) {
5268            try {
5269                if (mStackSupervisor.attachApplicationLocked(app)) {
5270                    didSomething = true;
5271                }
5272            } catch (Exception e) {
5273                badApp = true;
5274            }
5275        }
5276
5277        // Find any services that should be running in this process...
5278        if (!badApp) {
5279            try {
5280                didSomething |= mServices.attachApplicationLocked(app, processName);
5281            } catch (Exception e) {
5282                badApp = true;
5283            }
5284        }
5285
5286        // Check if a next-broadcast receiver is in this process...
5287        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5288            try {
5289                didSomething |= sendPendingBroadcastsLocked(app);
5290            } catch (Exception e) {
5291                // If the app died trying to launch the receiver we declare it 'bad'
5292                badApp = true;
5293            }
5294        }
5295
5296        // Check whether the next backup agent is in this process...
5297        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5298            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5299            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5300            try {
5301                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5302                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5303                        mBackupTarget.backupMode);
5304            } catch (Exception e) {
5305                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5306                e.printStackTrace();
5307            }
5308        }
5309
5310        if (badApp) {
5311            // todo: Also need to kill application to deal with all
5312            // kinds of exceptions.
5313            handleAppDiedLocked(app, false, true);
5314            return false;
5315        }
5316
5317        if (!didSomething) {
5318            updateOomAdjLocked();
5319        }
5320
5321        return true;
5322    }
5323
5324    @Override
5325    public final void attachApplication(IApplicationThread thread) {
5326        synchronized (this) {
5327            int callingPid = Binder.getCallingPid();
5328            final long origId = Binder.clearCallingIdentity();
5329            attachApplicationLocked(thread, callingPid);
5330            Binder.restoreCallingIdentity(origId);
5331        }
5332    }
5333
5334    @Override
5335    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5336        final long origId = Binder.clearCallingIdentity();
5337        synchronized (this) {
5338            ActivityStack stack = ActivityRecord.getStackLocked(token);
5339            if (stack != null) {
5340                ActivityRecord r =
5341                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5342                if (stopProfiling) {
5343                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5344                        try {
5345                            mProfileFd.close();
5346                        } catch (IOException e) {
5347                        }
5348                        clearProfilerLocked();
5349                    }
5350                }
5351            }
5352        }
5353        Binder.restoreCallingIdentity(origId);
5354    }
5355
5356    void enableScreenAfterBoot() {
5357        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5358                SystemClock.uptimeMillis());
5359        mWindowManager.enableScreenAfterBoot();
5360
5361        synchronized (this) {
5362            updateEventDispatchingLocked();
5363        }
5364    }
5365
5366    @Override
5367    public void showBootMessage(final CharSequence msg, final boolean always) {
5368        enforceNotIsolatedCaller("showBootMessage");
5369        mWindowManager.showBootMessage(msg, always);
5370    }
5371
5372    @Override
5373    public void dismissKeyguardOnNextActivity() {
5374        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5375        final long token = Binder.clearCallingIdentity();
5376        try {
5377            synchronized (this) {
5378                if (DEBUG_LOCKSCREEN) logLockScreen("");
5379                if (mLockScreenShown) {
5380                    mLockScreenShown = false;
5381                    comeOutOfSleepIfNeededLocked();
5382                }
5383                mStackSupervisor.setDismissKeyguard(true);
5384            }
5385        } finally {
5386            Binder.restoreCallingIdentity(token);
5387        }
5388    }
5389
5390    final void finishBooting() {
5391        // Register receivers to handle package update events
5392        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5393
5394        synchronized (this) {
5395            // Ensure that any processes we had put on hold are now started
5396            // up.
5397            final int NP = mProcessesOnHold.size();
5398            if (NP > 0) {
5399                ArrayList<ProcessRecord> procs =
5400                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5401                for (int ip=0; ip<NP; ip++) {
5402                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5403                            + procs.get(ip));
5404                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5405                }
5406            }
5407
5408            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5409                // Start looking for apps that are abusing wake locks.
5410                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5411                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5412                // Tell anyone interested that we are done booting!
5413                SystemProperties.set("sys.boot_completed", "1");
5414                SystemProperties.set("dev.bootcomplete", "1");
5415                for (int i=0; i<mStartedUsers.size(); i++) {
5416                    UserStartedState uss = mStartedUsers.valueAt(i);
5417                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5418                        uss.mState = UserStartedState.STATE_RUNNING;
5419                        final int userId = mStartedUsers.keyAt(i);
5420                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5421                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5422                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5423                        broadcastIntentLocked(null, null, intent, null,
5424                                new IIntentReceiver.Stub() {
5425                                    @Override
5426                                    public void performReceive(Intent intent, int resultCode,
5427                                            String data, Bundle extras, boolean ordered,
5428                                            boolean sticky, int sendingUser) {
5429                                        synchronized (ActivityManagerService.this) {
5430                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5431                                                    true, false);
5432                                        }
5433                                    }
5434                                },
5435                                0, null, null,
5436                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5437                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5438                                userId);
5439                    }
5440                }
5441                scheduleStartProfilesLocked();
5442            }
5443        }
5444    }
5445
5446    final void ensureBootCompleted() {
5447        boolean booting;
5448        boolean enableScreen;
5449        synchronized (this) {
5450            booting = mBooting;
5451            mBooting = false;
5452            enableScreen = !mBooted;
5453            mBooted = true;
5454        }
5455
5456        if (booting) {
5457            finishBooting();
5458        }
5459
5460        if (enableScreen) {
5461            enableScreenAfterBoot();
5462        }
5463    }
5464
5465    @Override
5466    public final void activityResumed(IBinder token) {
5467        final long origId = Binder.clearCallingIdentity();
5468        synchronized(this) {
5469            ActivityStack stack = ActivityRecord.getStackLocked(token);
5470            if (stack != null) {
5471                ActivityRecord.activityResumedLocked(token);
5472            }
5473        }
5474        Binder.restoreCallingIdentity(origId);
5475    }
5476
5477    @Override
5478    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5479        final long origId = Binder.clearCallingIdentity();
5480        synchronized(this) {
5481            ActivityStack stack = ActivityRecord.getStackLocked(token);
5482            if (stack != null) {
5483                stack.activityPausedLocked(token, false, persistentState);
5484            }
5485        }
5486        Binder.restoreCallingIdentity(origId);
5487    }
5488
5489    @Override
5490    public final void activityStopped(IBinder token, Bundle icicle,
5491            PersistableBundle persistentState, CharSequence description) {
5492        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5493
5494        // Refuse possible leaked file descriptors
5495        if (icicle != null && icicle.hasFileDescriptors()) {
5496            throw new IllegalArgumentException("File descriptors passed in Bundle");
5497        }
5498
5499        final long origId = Binder.clearCallingIdentity();
5500
5501        synchronized (this) {
5502            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5503            if (r != null) {
5504                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5505            }
5506        }
5507
5508        trimApplications();
5509
5510        Binder.restoreCallingIdentity(origId);
5511    }
5512
5513    @Override
5514    public final void activityDestroyed(IBinder token) {
5515        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5516        synchronized (this) {
5517            ActivityStack stack = ActivityRecord.getStackLocked(token);
5518            if (stack != null) {
5519                stack.activityDestroyedLocked(token);
5520            }
5521        }
5522    }
5523
5524    @Override
5525    public String getCallingPackage(IBinder token) {
5526        synchronized (this) {
5527            ActivityRecord r = getCallingRecordLocked(token);
5528            return r != null ? r.info.packageName : null;
5529        }
5530    }
5531
5532    @Override
5533    public ComponentName getCallingActivity(IBinder token) {
5534        synchronized (this) {
5535            ActivityRecord r = getCallingRecordLocked(token);
5536            return r != null ? r.intent.getComponent() : null;
5537        }
5538    }
5539
5540    private ActivityRecord getCallingRecordLocked(IBinder token) {
5541        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5542        if (r == null) {
5543            return null;
5544        }
5545        return r.resultTo;
5546    }
5547
5548    @Override
5549    public ComponentName getActivityClassForToken(IBinder token) {
5550        synchronized(this) {
5551            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5552            if (r == null) {
5553                return null;
5554            }
5555            return r.intent.getComponent();
5556        }
5557    }
5558
5559    @Override
5560    public String getPackageForToken(IBinder token) {
5561        synchronized(this) {
5562            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5563            if (r == null) {
5564                return null;
5565            }
5566            return r.packageName;
5567        }
5568    }
5569
5570    @Override
5571    public IIntentSender getIntentSender(int type,
5572            String packageName, IBinder token, String resultWho,
5573            int requestCode, Intent[] intents, String[] resolvedTypes,
5574            int flags, Bundle options, int userId) {
5575        enforceNotIsolatedCaller("getIntentSender");
5576        // Refuse possible leaked file descriptors
5577        if (intents != null) {
5578            if (intents.length < 1) {
5579                throw new IllegalArgumentException("Intents array length must be >= 1");
5580            }
5581            for (int i=0; i<intents.length; i++) {
5582                Intent intent = intents[i];
5583                if (intent != null) {
5584                    if (intent.hasFileDescriptors()) {
5585                        throw new IllegalArgumentException("File descriptors passed in Intent");
5586                    }
5587                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5588                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5589                        throw new IllegalArgumentException(
5590                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5591                    }
5592                    intents[i] = new Intent(intent);
5593                }
5594            }
5595            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5596                throw new IllegalArgumentException(
5597                        "Intent array length does not match resolvedTypes length");
5598            }
5599        }
5600        if (options != null) {
5601            if (options.hasFileDescriptors()) {
5602                throw new IllegalArgumentException("File descriptors passed in options");
5603            }
5604        }
5605
5606        synchronized(this) {
5607            int callingUid = Binder.getCallingUid();
5608            int origUserId = userId;
5609            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5610                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5611                    "getIntentSender", null);
5612            if (origUserId == UserHandle.USER_CURRENT) {
5613                // We don't want to evaluate this until the pending intent is
5614                // actually executed.  However, we do want to always do the
5615                // security checking for it above.
5616                userId = UserHandle.USER_CURRENT;
5617            }
5618            try {
5619                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5620                    int uid = AppGlobals.getPackageManager()
5621                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5622                    if (!UserHandle.isSameApp(callingUid, uid)) {
5623                        String msg = "Permission Denial: getIntentSender() from pid="
5624                            + Binder.getCallingPid()
5625                            + ", uid=" + Binder.getCallingUid()
5626                            + ", (need uid=" + uid + ")"
5627                            + " is not allowed to send as package " + packageName;
5628                        Slog.w(TAG, msg);
5629                        throw new SecurityException(msg);
5630                    }
5631                }
5632
5633                return getIntentSenderLocked(type, packageName, callingUid, userId,
5634                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5635
5636            } catch (RemoteException e) {
5637                throw new SecurityException(e);
5638            }
5639        }
5640    }
5641
5642    IIntentSender getIntentSenderLocked(int type, String packageName,
5643            int callingUid, int userId, IBinder token, String resultWho,
5644            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5645            Bundle options) {
5646        if (DEBUG_MU)
5647            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5648        ActivityRecord activity = null;
5649        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5650            activity = ActivityRecord.isInStackLocked(token);
5651            if (activity == null) {
5652                return null;
5653            }
5654            if (activity.finishing) {
5655                return null;
5656            }
5657        }
5658
5659        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5660        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5661        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5662        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5663                |PendingIntent.FLAG_UPDATE_CURRENT);
5664
5665        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5666                type, packageName, activity, resultWho,
5667                requestCode, intents, resolvedTypes, flags, options, userId);
5668        WeakReference<PendingIntentRecord> ref;
5669        ref = mIntentSenderRecords.get(key);
5670        PendingIntentRecord rec = ref != null ? ref.get() : null;
5671        if (rec != null) {
5672            if (!cancelCurrent) {
5673                if (updateCurrent) {
5674                    if (rec.key.requestIntent != null) {
5675                        rec.key.requestIntent.replaceExtras(intents != null ?
5676                                intents[intents.length - 1] : null);
5677                    }
5678                    if (intents != null) {
5679                        intents[intents.length-1] = rec.key.requestIntent;
5680                        rec.key.allIntents = intents;
5681                        rec.key.allResolvedTypes = resolvedTypes;
5682                    } else {
5683                        rec.key.allIntents = null;
5684                        rec.key.allResolvedTypes = null;
5685                    }
5686                }
5687                return rec;
5688            }
5689            rec.canceled = true;
5690            mIntentSenderRecords.remove(key);
5691        }
5692        if (noCreate) {
5693            return rec;
5694        }
5695        rec = new PendingIntentRecord(this, key, callingUid);
5696        mIntentSenderRecords.put(key, rec.ref);
5697        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5698            if (activity.pendingResults == null) {
5699                activity.pendingResults
5700                        = new HashSet<WeakReference<PendingIntentRecord>>();
5701            }
5702            activity.pendingResults.add(rec.ref);
5703        }
5704        return rec;
5705    }
5706
5707    @Override
5708    public void cancelIntentSender(IIntentSender sender) {
5709        if (!(sender instanceof PendingIntentRecord)) {
5710            return;
5711        }
5712        synchronized(this) {
5713            PendingIntentRecord rec = (PendingIntentRecord)sender;
5714            try {
5715                int uid = AppGlobals.getPackageManager()
5716                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5717                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5718                    String msg = "Permission Denial: cancelIntentSender() from pid="
5719                        + Binder.getCallingPid()
5720                        + ", uid=" + Binder.getCallingUid()
5721                        + " is not allowed to cancel packges "
5722                        + rec.key.packageName;
5723                    Slog.w(TAG, msg);
5724                    throw new SecurityException(msg);
5725                }
5726            } catch (RemoteException e) {
5727                throw new SecurityException(e);
5728            }
5729            cancelIntentSenderLocked(rec, true);
5730        }
5731    }
5732
5733    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5734        rec.canceled = true;
5735        mIntentSenderRecords.remove(rec.key);
5736        if (cleanActivity && rec.key.activity != null) {
5737            rec.key.activity.pendingResults.remove(rec.ref);
5738        }
5739    }
5740
5741    @Override
5742    public String getPackageForIntentSender(IIntentSender pendingResult) {
5743        if (!(pendingResult instanceof PendingIntentRecord)) {
5744            return null;
5745        }
5746        try {
5747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5748            return res.key.packageName;
5749        } catch (ClassCastException e) {
5750        }
5751        return null;
5752    }
5753
5754    @Override
5755    public int getUidForIntentSender(IIntentSender sender) {
5756        if (sender instanceof PendingIntentRecord) {
5757            try {
5758                PendingIntentRecord res = (PendingIntentRecord)sender;
5759                return res.uid;
5760            } catch (ClassCastException e) {
5761            }
5762        }
5763        return -1;
5764    }
5765
5766    @Override
5767    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5768        if (!(pendingResult instanceof PendingIntentRecord)) {
5769            return false;
5770        }
5771        try {
5772            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5773            if (res.key.allIntents == null) {
5774                return false;
5775            }
5776            for (int i=0; i<res.key.allIntents.length; i++) {
5777                Intent intent = res.key.allIntents[i];
5778                if (intent.getPackage() != null && intent.getComponent() != null) {
5779                    return false;
5780                }
5781            }
5782            return true;
5783        } catch (ClassCastException e) {
5784        }
5785        return false;
5786    }
5787
5788    @Override
5789    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5790        if (!(pendingResult instanceof PendingIntentRecord)) {
5791            return false;
5792        }
5793        try {
5794            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5795            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5796                return true;
5797            }
5798            return false;
5799        } catch (ClassCastException e) {
5800        }
5801        return false;
5802    }
5803
5804    @Override
5805    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5806        if (!(pendingResult instanceof PendingIntentRecord)) {
5807            return null;
5808        }
5809        try {
5810            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5811            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5812        } catch (ClassCastException e) {
5813        }
5814        return null;
5815    }
5816
5817    @Override
5818    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5819        if (!(pendingResult instanceof PendingIntentRecord)) {
5820            return null;
5821        }
5822        try {
5823            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5824            Intent intent = res.key.requestIntent;
5825            if (intent != null) {
5826                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5827                        || res.lastTagPrefix.equals(prefix))) {
5828                    return res.lastTag;
5829                }
5830                res.lastTagPrefix = prefix;
5831                StringBuilder sb = new StringBuilder(128);
5832                if (prefix != null) {
5833                    sb.append(prefix);
5834                }
5835                if (intent.getAction() != null) {
5836                    sb.append(intent.getAction());
5837                } else if (intent.getComponent() != null) {
5838                    intent.getComponent().appendShortString(sb);
5839                } else {
5840                    sb.append("?");
5841                }
5842                return res.lastTag = sb.toString();
5843            }
5844        } catch (ClassCastException e) {
5845        }
5846        return null;
5847    }
5848
5849    @Override
5850    public void setProcessLimit(int max) {
5851        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5852                "setProcessLimit()");
5853        synchronized (this) {
5854            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5855            mProcessLimitOverride = max;
5856        }
5857        trimApplications();
5858    }
5859
5860    @Override
5861    public int getProcessLimit() {
5862        synchronized (this) {
5863            return mProcessLimitOverride;
5864        }
5865    }
5866
5867    void foregroundTokenDied(ForegroundToken token) {
5868        synchronized (ActivityManagerService.this) {
5869            synchronized (mPidsSelfLocked) {
5870                ForegroundToken cur
5871                    = mForegroundProcesses.get(token.pid);
5872                if (cur != token) {
5873                    return;
5874                }
5875                mForegroundProcesses.remove(token.pid);
5876                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5877                if (pr == null) {
5878                    return;
5879                }
5880                pr.forcingToForeground = null;
5881                updateProcessForegroundLocked(pr, false, false);
5882            }
5883            updateOomAdjLocked();
5884        }
5885    }
5886
5887    @Override
5888    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5889        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5890                "setProcessForeground()");
5891        synchronized(this) {
5892            boolean changed = false;
5893
5894            synchronized (mPidsSelfLocked) {
5895                ProcessRecord pr = mPidsSelfLocked.get(pid);
5896                if (pr == null && isForeground) {
5897                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5898                    return;
5899                }
5900                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5901                if (oldToken != null) {
5902                    oldToken.token.unlinkToDeath(oldToken, 0);
5903                    mForegroundProcesses.remove(pid);
5904                    if (pr != null) {
5905                        pr.forcingToForeground = null;
5906                    }
5907                    changed = true;
5908                }
5909                if (isForeground && token != null) {
5910                    ForegroundToken newToken = new ForegroundToken() {
5911                        @Override
5912                        public void binderDied() {
5913                            foregroundTokenDied(this);
5914                        }
5915                    };
5916                    newToken.pid = pid;
5917                    newToken.token = token;
5918                    try {
5919                        token.linkToDeath(newToken, 0);
5920                        mForegroundProcesses.put(pid, newToken);
5921                        pr.forcingToForeground = token;
5922                        changed = true;
5923                    } catch (RemoteException e) {
5924                        // If the process died while doing this, we will later
5925                        // do the cleanup with the process death link.
5926                    }
5927                }
5928            }
5929
5930            if (changed) {
5931                updateOomAdjLocked();
5932            }
5933        }
5934    }
5935
5936    // =========================================================
5937    // PERMISSIONS
5938    // =========================================================
5939
5940    static class PermissionController extends IPermissionController.Stub {
5941        ActivityManagerService mActivityManagerService;
5942        PermissionController(ActivityManagerService activityManagerService) {
5943            mActivityManagerService = activityManagerService;
5944        }
5945
5946        @Override
5947        public boolean checkPermission(String permission, int pid, int uid) {
5948            return mActivityManagerService.checkPermission(permission, pid,
5949                    uid) == PackageManager.PERMISSION_GRANTED;
5950        }
5951    }
5952
5953    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5954        @Override
5955        public int checkComponentPermission(String permission, int pid, int uid,
5956                int owningUid, boolean exported) {
5957            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5958                    owningUid, exported);
5959        }
5960
5961        @Override
5962        public Object getAMSLock() {
5963            return ActivityManagerService.this;
5964        }
5965    }
5966
5967    /**
5968     * This can be called with or without the global lock held.
5969     */
5970    int checkComponentPermission(String permission, int pid, int uid,
5971            int owningUid, boolean exported) {
5972        // We might be performing an operation on behalf of an indirect binder
5973        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5974        // client identity accordingly before proceeding.
5975        Identity tlsIdentity = sCallerIdentity.get();
5976        if (tlsIdentity != null) {
5977            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5978                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5979            uid = tlsIdentity.uid;
5980            pid = tlsIdentity.pid;
5981        }
5982
5983        if (pid == MY_PID) {
5984            return PackageManager.PERMISSION_GRANTED;
5985        }
5986
5987        return ActivityManager.checkComponentPermission(permission, uid,
5988                owningUid, exported);
5989    }
5990
5991    /**
5992     * As the only public entry point for permissions checking, this method
5993     * can enforce the semantic that requesting a check on a null global
5994     * permission is automatically denied.  (Internally a null permission
5995     * string is used when calling {@link #checkComponentPermission} in cases
5996     * when only uid-based security is needed.)
5997     *
5998     * This can be called with or without the global lock held.
5999     */
6000    @Override
6001    public int checkPermission(String permission, int pid, int uid) {
6002        if (permission == null) {
6003            return PackageManager.PERMISSION_DENIED;
6004        }
6005        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6006    }
6007
6008    /**
6009     * Binder IPC calls go through the public entry point.
6010     * This can be called with or without the global lock held.
6011     */
6012    int checkCallingPermission(String permission) {
6013        return checkPermission(permission,
6014                Binder.getCallingPid(),
6015                UserHandle.getAppId(Binder.getCallingUid()));
6016    }
6017
6018    /**
6019     * This can be called with or without the global lock held.
6020     */
6021    void enforceCallingPermission(String permission, String func) {
6022        if (checkCallingPermission(permission)
6023                == PackageManager.PERMISSION_GRANTED) {
6024            return;
6025        }
6026
6027        String msg = "Permission Denial: " + func + " from pid="
6028                + Binder.getCallingPid()
6029                + ", uid=" + Binder.getCallingUid()
6030                + " requires " + permission;
6031        Slog.w(TAG, msg);
6032        throw new SecurityException(msg);
6033    }
6034
6035    /**
6036     * Determine if UID is holding permissions required to access {@link Uri} in
6037     * the given {@link ProviderInfo}. Final permission checking is always done
6038     * in {@link ContentProvider}.
6039     */
6040    private final boolean checkHoldingPermissionsLocked(
6041            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6042        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6043                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6044        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6045            return false;
6046        }
6047
6048        if (pi.applicationInfo.uid == uid) {
6049            return true;
6050        } else if (!pi.exported) {
6051            return false;
6052        }
6053
6054        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6055        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6056        try {
6057            // check if target holds top-level <provider> permissions
6058            if (!readMet && pi.readPermission != null
6059                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6060                readMet = true;
6061            }
6062            if (!writeMet && pi.writePermission != null
6063                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6064                writeMet = true;
6065            }
6066
6067            // track if unprotected read/write is allowed; any denied
6068            // <path-permission> below removes this ability
6069            boolean allowDefaultRead = pi.readPermission == null;
6070            boolean allowDefaultWrite = pi.writePermission == null;
6071
6072            // check if target holds any <path-permission> that match uri
6073            final PathPermission[] pps = pi.pathPermissions;
6074            if (pps != null) {
6075                final String path = grantUri.uri.getPath();
6076                int i = pps.length;
6077                while (i > 0 && (!readMet || !writeMet)) {
6078                    i--;
6079                    PathPermission pp = pps[i];
6080                    if (pp.match(path)) {
6081                        if (!readMet) {
6082                            final String pprperm = pp.getReadPermission();
6083                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6084                                    + pprperm + " for " + pp.getPath()
6085                                    + ": match=" + pp.match(path)
6086                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6087                            if (pprperm != null) {
6088                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6089                                    readMet = true;
6090                                } else {
6091                                    allowDefaultRead = false;
6092                                }
6093                            }
6094                        }
6095                        if (!writeMet) {
6096                            final String ppwperm = pp.getWritePermission();
6097                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6098                                    + ppwperm + " for " + pp.getPath()
6099                                    + ": match=" + pp.match(path)
6100                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6101                            if (ppwperm != null) {
6102                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6103                                    writeMet = true;
6104                                } else {
6105                                    allowDefaultWrite = false;
6106                                }
6107                            }
6108                        }
6109                    }
6110                }
6111            }
6112
6113            // grant unprotected <provider> read/write, if not blocked by
6114            // <path-permission> above
6115            if (allowDefaultRead) readMet = true;
6116            if (allowDefaultWrite) writeMet = true;
6117
6118        } catch (RemoteException e) {
6119            return false;
6120        }
6121
6122        return readMet && writeMet;
6123    }
6124
6125    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6126        ProviderInfo pi = null;
6127        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6128        if (cpr != null) {
6129            pi = cpr.info;
6130        } else {
6131            try {
6132                pi = AppGlobals.getPackageManager().resolveContentProvider(
6133                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6134            } catch (RemoteException ex) {
6135            }
6136        }
6137        return pi;
6138    }
6139
6140    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6141        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6142        if (targetUris != null) {
6143            return targetUris.get(grantUri);
6144        }
6145        return null;
6146    }
6147
6148    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6149            String targetPkg, int targetUid, GrantUri grantUri) {
6150        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6151        if (targetUris == null) {
6152            targetUris = Maps.newArrayMap();
6153            mGrantedUriPermissions.put(targetUid, targetUris);
6154        }
6155
6156        UriPermission perm = targetUris.get(grantUri);
6157        if (perm == null) {
6158            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6159            targetUris.put(grantUri, perm);
6160        }
6161
6162        return perm;
6163    }
6164
6165    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6166            final int modeFlags) {
6167        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6168        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6169                : UriPermission.STRENGTH_OWNED;
6170
6171        // Root gets to do everything.
6172        if (uid == 0) {
6173            return true;
6174        }
6175
6176        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6177        if (perms == null) return false;
6178
6179        // First look for exact match
6180        final UriPermission exactPerm = perms.get(grantUri);
6181        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6182            return true;
6183        }
6184
6185        // No exact match, look for prefixes
6186        final int N = perms.size();
6187        for (int i = 0; i < N; i++) {
6188            final UriPermission perm = perms.valueAt(i);
6189            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6190                    && perm.getStrength(modeFlags) >= minStrength) {
6191                return true;
6192            }
6193        }
6194
6195        return false;
6196    }
6197
6198    @Override
6199    public int checkUriPermission(Uri uri, int pid, int uid,
6200            final int modeFlags, int userId) {
6201        enforceNotIsolatedCaller("checkUriPermission");
6202
6203        // Another redirected-binder-call permissions check as in
6204        // {@link checkComponentPermission}.
6205        Identity tlsIdentity = sCallerIdentity.get();
6206        if (tlsIdentity != null) {
6207            uid = tlsIdentity.uid;
6208            pid = tlsIdentity.pid;
6209        }
6210
6211        // Our own process gets to do everything.
6212        if (pid == MY_PID) {
6213            return PackageManager.PERMISSION_GRANTED;
6214        }
6215        synchronized (this) {
6216            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6217                    ? PackageManager.PERMISSION_GRANTED
6218                    : PackageManager.PERMISSION_DENIED;
6219        }
6220    }
6221
6222    /**
6223     * Check if the targetPkg can be granted permission to access uri by
6224     * the callingUid using the given modeFlags.  Throws a security exception
6225     * if callingUid is not allowed to do this.  Returns the uid of the target
6226     * if the URI permission grant should be performed; returns -1 if it is not
6227     * needed (for example targetPkg already has permission to access the URI).
6228     * If you already know the uid of the target, you can supply it in
6229     * lastTargetUid else set that to -1.
6230     */
6231    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6232            final int modeFlags, int lastTargetUid) {
6233        if (!Intent.isAccessUriMode(modeFlags)) {
6234            return -1;
6235        }
6236
6237        if (targetPkg != null) {
6238            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6239                    "Checking grant " + targetPkg + " permission to " + grantUri);
6240        }
6241
6242        final IPackageManager pm = AppGlobals.getPackageManager();
6243
6244        // If this is not a content: uri, we can't do anything with it.
6245        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6246            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6247                    "Can't grant URI permission for non-content URI: " + grantUri);
6248            return -1;
6249        }
6250
6251        final String authority = grantUri.uri.getAuthority();
6252        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6253        if (pi == null) {
6254            Slog.w(TAG, "No content provider found for permission check: " +
6255                    grantUri.uri.toSafeString());
6256            return -1;
6257        }
6258
6259        int targetUid = lastTargetUid;
6260        if (targetUid < 0 && targetPkg != null) {
6261            try {
6262                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6263                if (targetUid < 0) {
6264                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6265                            "Can't grant URI permission no uid for: " + targetPkg);
6266                    return -1;
6267                }
6268            } catch (RemoteException ex) {
6269                return -1;
6270            }
6271        }
6272
6273        if (targetUid >= 0) {
6274            // First...  does the target actually need this permission?
6275            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6276                // No need to grant the target this permission.
6277                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6278                        "Target " + targetPkg + " already has full permission to " + grantUri);
6279                return -1;
6280            }
6281        } else {
6282            // First...  there is no target package, so can anyone access it?
6283            boolean allowed = pi.exported;
6284            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6285                if (pi.readPermission != null) {
6286                    allowed = false;
6287                }
6288            }
6289            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6290                if (pi.writePermission != null) {
6291                    allowed = false;
6292                }
6293            }
6294            if (allowed) {
6295                return -1;
6296            }
6297        }
6298
6299        // Second...  is the provider allowing granting of URI permissions?
6300        if (!pi.grantUriPermissions) {
6301            throw new SecurityException("Provider " + pi.packageName
6302                    + "/" + pi.name
6303                    + " does not allow granting of Uri permissions (uri "
6304                    + grantUri + ")");
6305        }
6306        if (pi.uriPermissionPatterns != null) {
6307            final int N = pi.uriPermissionPatterns.length;
6308            boolean allowed = false;
6309            for (int i=0; i<N; i++) {
6310                if (pi.uriPermissionPatterns[i] != null
6311                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6312                    allowed = true;
6313                    break;
6314                }
6315            }
6316            if (!allowed) {
6317                throw new SecurityException("Provider " + pi.packageName
6318                        + "/" + pi.name
6319                        + " does not allow granting of permission to path of Uri "
6320                        + grantUri);
6321            }
6322        }
6323
6324        // Third...  does the caller itself have permission to access
6325        // this uri?
6326        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6327            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6328                // Require they hold a strong enough Uri permission
6329                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6330                    throw new SecurityException("Uid " + callingUid
6331                            + " does not have permission to uri " + grantUri);
6332                }
6333            }
6334        }
6335        return targetUid;
6336    }
6337
6338    @Override
6339    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6340            final int modeFlags, int userId) {
6341        enforceNotIsolatedCaller("checkGrantUriPermission");
6342        synchronized(this) {
6343            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6344                    new GrantUri(userId, uri, false), modeFlags, -1);
6345        }
6346    }
6347
6348    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6349            final int modeFlags, UriPermissionOwner owner) {
6350        if (!Intent.isAccessUriMode(modeFlags)) {
6351            return;
6352        }
6353
6354        // So here we are: the caller has the assumed permission
6355        // to the uri, and the target doesn't.  Let's now give this to
6356        // the target.
6357
6358        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6359                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6360
6361        final String authority = grantUri.uri.getAuthority();
6362        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6363        if (pi == null) {
6364            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6365            return;
6366        }
6367
6368        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6369            grantUri.prefix = true;
6370        }
6371        final UriPermission perm = findOrCreateUriPermissionLocked(
6372                pi.packageName, targetPkg, targetUid, grantUri);
6373        perm.grantModes(modeFlags, owner);
6374    }
6375
6376    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6377            final int modeFlags, UriPermissionOwner owner) {
6378        if (targetPkg == null) {
6379            throw new NullPointerException("targetPkg");
6380        }
6381
6382        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6383                -1);
6384        if (targetUid < 0) {
6385            return;
6386        }
6387
6388        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6389                owner);
6390    }
6391
6392    static class NeededUriGrants extends ArrayList<GrantUri> {
6393        final String targetPkg;
6394        final int targetUid;
6395        final int flags;
6396
6397        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6398            this.targetPkg = targetPkg;
6399            this.targetUid = targetUid;
6400            this.flags = flags;
6401        }
6402    }
6403
6404    /**
6405     * Like checkGrantUriPermissionLocked, but takes an Intent.
6406     */
6407    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6408            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6409        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6410                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6411                + " clip=" + (intent != null ? intent.getClipData() : null)
6412                + " from " + intent + "; flags=0x"
6413                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6414
6415        if (targetPkg == null) {
6416            throw new NullPointerException("targetPkg");
6417        }
6418
6419        if (intent == null) {
6420            return null;
6421        }
6422        Uri data = intent.getData();
6423        ClipData clip = intent.getClipData();
6424        if (data == null && clip == null) {
6425            return null;
6426        }
6427        final IPackageManager pm = AppGlobals.getPackageManager();
6428        int targetUid;
6429        if (needed != null) {
6430            targetUid = needed.targetUid;
6431        } else {
6432            try {
6433                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6434            } catch (RemoteException ex) {
6435                return null;
6436            }
6437            if (targetUid < 0) {
6438                if (DEBUG_URI_PERMISSION) {
6439                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6440                            + " on user " + targetUserId);
6441                }
6442                return null;
6443            }
6444        }
6445        if (data != null) {
6446            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6447            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6448                    targetUid);
6449            if (targetUid > 0) {
6450                if (needed == null) {
6451                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6452                }
6453                needed.add(grantUri);
6454            }
6455        }
6456        if (clip != null) {
6457            for (int i=0; i<clip.getItemCount(); i++) {
6458                Uri uri = clip.getItemAt(i).getUri();
6459                if (uri != null) {
6460                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6461                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6462                            targetUid);
6463                    if (targetUid > 0) {
6464                        if (needed == null) {
6465                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6466                        }
6467                        needed.add(grantUri);
6468                    }
6469                } else {
6470                    Intent clipIntent = clip.getItemAt(i).getIntent();
6471                    if (clipIntent != null) {
6472                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6473                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6474                        if (newNeeded != null) {
6475                            needed = newNeeded;
6476                        }
6477                    }
6478                }
6479            }
6480        }
6481
6482        return needed;
6483    }
6484
6485    /**
6486     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6487     */
6488    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6489            UriPermissionOwner owner) {
6490        if (needed != null) {
6491            for (int i=0; i<needed.size(); i++) {
6492                GrantUri grantUri = needed.get(i);
6493                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6494                        grantUri, needed.flags, owner);
6495            }
6496        }
6497    }
6498
6499    void grantUriPermissionFromIntentLocked(int callingUid,
6500            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6501        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6502                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6503        if (needed == null) {
6504            return;
6505        }
6506
6507        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6508    }
6509
6510    @Override
6511    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6512            final int modeFlags, int userId) {
6513        enforceNotIsolatedCaller("grantUriPermission");
6514        GrantUri grantUri = new GrantUri(userId, uri, false);
6515        synchronized(this) {
6516            final ProcessRecord r = getRecordForAppLocked(caller);
6517            if (r == null) {
6518                throw new SecurityException("Unable to find app for caller "
6519                        + caller
6520                        + " when granting permission to uri " + grantUri);
6521            }
6522            if (targetPkg == null) {
6523                throw new IllegalArgumentException("null target");
6524            }
6525            if (grantUri == null) {
6526                throw new IllegalArgumentException("null uri");
6527            }
6528
6529            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6530                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6531                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6532                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6533
6534            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6535        }
6536    }
6537
6538    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6539        if (perm.modeFlags == 0) {
6540            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6541                    perm.targetUid);
6542            if (perms != null) {
6543                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6544                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6545
6546                perms.remove(perm.uri);
6547                if (perms.isEmpty()) {
6548                    mGrantedUriPermissions.remove(perm.targetUid);
6549                }
6550            }
6551        }
6552    }
6553
6554    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6555        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6556
6557        final IPackageManager pm = AppGlobals.getPackageManager();
6558        final String authority = grantUri.uri.getAuthority();
6559        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6560        if (pi == null) {
6561            Slog.w(TAG, "No content provider found for permission revoke: "
6562                    + grantUri.toSafeString());
6563            return;
6564        }
6565
6566        // Does the caller have this permission on the URI?
6567        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6568            // Right now, if you are not the original owner of the permission,
6569            // you are not allowed to revoke it.
6570            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6571                throw new SecurityException("Uid " + callingUid
6572                        + " does not have permission to uri " + grantUri);
6573            //}
6574        }
6575
6576        boolean persistChanged = false;
6577
6578        // Go through all of the permissions and remove any that match.
6579        int N = mGrantedUriPermissions.size();
6580        for (int i = 0; i < N; i++) {
6581            final int targetUid = mGrantedUriPermissions.keyAt(i);
6582            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6583
6584            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6585                final UriPermission perm = it.next();
6586                if (perm.uri.sourceUserId == grantUri.sourceUserId
6587                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6588                    if (DEBUG_URI_PERMISSION)
6589                        Slog.v(TAG,
6590                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6591                    persistChanged |= perm.revokeModes(
6592                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6593                    if (perm.modeFlags == 0) {
6594                        it.remove();
6595                    }
6596                }
6597            }
6598
6599            if (perms.isEmpty()) {
6600                mGrantedUriPermissions.remove(targetUid);
6601                N--;
6602                i--;
6603            }
6604        }
6605
6606        if (persistChanged) {
6607            schedulePersistUriGrants();
6608        }
6609    }
6610
6611    @Override
6612    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6613            int userId) {
6614        enforceNotIsolatedCaller("revokeUriPermission");
6615        synchronized(this) {
6616            final ProcessRecord r = getRecordForAppLocked(caller);
6617            if (r == null) {
6618                throw new SecurityException("Unable to find app for caller "
6619                        + caller
6620                        + " when revoking permission to uri " + uri);
6621            }
6622            if (uri == null) {
6623                Slog.w(TAG, "revokeUriPermission: null uri");
6624                return;
6625            }
6626
6627            if (!Intent.isAccessUriMode(modeFlags)) {
6628                return;
6629            }
6630
6631            final IPackageManager pm = AppGlobals.getPackageManager();
6632            final String authority = uri.getAuthority();
6633            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6634            if (pi == null) {
6635                Slog.w(TAG, "No content provider found for permission revoke: "
6636                        + uri.toSafeString());
6637                return;
6638            }
6639
6640            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6641        }
6642    }
6643
6644    /**
6645     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6646     * given package.
6647     *
6648     * @param packageName Package name to match, or {@code null} to apply to all
6649     *            packages.
6650     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6651     *            to all users.
6652     * @param persistable If persistable grants should be removed.
6653     */
6654    private void removeUriPermissionsForPackageLocked(
6655            String packageName, int userHandle, boolean persistable) {
6656        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6657            throw new IllegalArgumentException("Must narrow by either package or user");
6658        }
6659
6660        boolean persistChanged = false;
6661
6662        int N = mGrantedUriPermissions.size();
6663        for (int i = 0; i < N; i++) {
6664            final int targetUid = mGrantedUriPermissions.keyAt(i);
6665            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6666
6667            // Only inspect grants matching user
6668            if (userHandle == UserHandle.USER_ALL
6669                    || userHandle == UserHandle.getUserId(targetUid)) {
6670                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6671                    final UriPermission perm = it.next();
6672
6673                    // Only inspect grants matching package
6674                    if (packageName == null || perm.sourcePkg.equals(packageName)
6675                            || perm.targetPkg.equals(packageName)) {
6676                        persistChanged |= perm.revokeModes(
6677                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6678
6679                        // Only remove when no modes remain; any persisted grants
6680                        // will keep this alive.
6681                        if (perm.modeFlags == 0) {
6682                            it.remove();
6683                        }
6684                    }
6685                }
6686
6687                if (perms.isEmpty()) {
6688                    mGrantedUriPermissions.remove(targetUid);
6689                    N--;
6690                    i--;
6691                }
6692            }
6693        }
6694
6695        if (persistChanged) {
6696            schedulePersistUriGrants();
6697        }
6698    }
6699
6700    @Override
6701    public IBinder newUriPermissionOwner(String name) {
6702        enforceNotIsolatedCaller("newUriPermissionOwner");
6703        synchronized(this) {
6704            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6705            return owner.getExternalTokenLocked();
6706        }
6707    }
6708
6709    @Override
6710    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6711            final int modeFlags, int userId) {
6712        synchronized(this) {
6713            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6714            if (owner == null) {
6715                throw new IllegalArgumentException("Unknown owner: " + token);
6716            }
6717            if (fromUid != Binder.getCallingUid()) {
6718                if (Binder.getCallingUid() != Process.myUid()) {
6719                    // Only system code can grant URI permissions on behalf
6720                    // of other users.
6721                    throw new SecurityException("nice try");
6722                }
6723            }
6724            if (targetPkg == null) {
6725                throw new IllegalArgumentException("null target");
6726            }
6727            if (uri == null) {
6728                throw new IllegalArgumentException("null uri");
6729            }
6730
6731            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6732                    modeFlags, owner);
6733        }
6734    }
6735
6736    @Override
6737    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6738        synchronized(this) {
6739            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6740            if (owner == null) {
6741                throw new IllegalArgumentException("Unknown owner: " + token);
6742            }
6743
6744            if (uri == null) {
6745                owner.removeUriPermissionsLocked(mode);
6746            } else {
6747                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6748            }
6749        }
6750    }
6751
6752    private void schedulePersistUriGrants() {
6753        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6754            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6755                    10 * DateUtils.SECOND_IN_MILLIS);
6756        }
6757    }
6758
6759    private void writeGrantedUriPermissions() {
6760        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6761
6762        // Snapshot permissions so we can persist without lock
6763        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6764        synchronized (this) {
6765            final int size = mGrantedUriPermissions.size();
6766            for (int i = 0; i < size; i++) {
6767                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6768                for (UriPermission perm : perms.values()) {
6769                    if (perm.persistedModeFlags != 0) {
6770                        persist.add(perm.snapshot());
6771                    }
6772                }
6773            }
6774        }
6775
6776        FileOutputStream fos = null;
6777        try {
6778            fos = mGrantFile.startWrite();
6779
6780            XmlSerializer out = new FastXmlSerializer();
6781            out.setOutput(fos, "utf-8");
6782            out.startDocument(null, true);
6783            out.startTag(null, TAG_URI_GRANTS);
6784            for (UriPermission.Snapshot perm : persist) {
6785                out.startTag(null, TAG_URI_GRANT);
6786                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6787                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6788                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6789                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6790                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6791                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6792                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6793                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6794                out.endTag(null, TAG_URI_GRANT);
6795            }
6796            out.endTag(null, TAG_URI_GRANTS);
6797            out.endDocument();
6798
6799            mGrantFile.finishWrite(fos);
6800        } catch (IOException e) {
6801            if (fos != null) {
6802                mGrantFile.failWrite(fos);
6803            }
6804        }
6805    }
6806
6807    private void readGrantedUriPermissionsLocked() {
6808        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6809
6810        final long now = System.currentTimeMillis();
6811
6812        FileInputStream fis = null;
6813        try {
6814            fis = mGrantFile.openRead();
6815            final XmlPullParser in = Xml.newPullParser();
6816            in.setInput(fis, null);
6817
6818            int type;
6819            while ((type = in.next()) != END_DOCUMENT) {
6820                final String tag = in.getName();
6821                if (type == START_TAG) {
6822                    if (TAG_URI_GRANT.equals(tag)) {
6823                        final int sourceUserId;
6824                        final int targetUserId;
6825                        final int userHandle = readIntAttribute(in,
6826                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6827                        if (userHandle != UserHandle.USER_NULL) {
6828                            // For backwards compatibility.
6829                            sourceUserId = userHandle;
6830                            targetUserId = userHandle;
6831                        } else {
6832                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6833                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6834                        }
6835                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6836                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6837                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6838                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6839                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6840                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6841
6842                        // Sanity check that provider still belongs to source package
6843                        final ProviderInfo pi = getProviderInfoLocked(
6844                                uri.getAuthority(), sourceUserId);
6845                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6846                            int targetUid = -1;
6847                            try {
6848                                targetUid = AppGlobals.getPackageManager()
6849                                        .getPackageUid(targetPkg, targetUserId);
6850                            } catch (RemoteException e) {
6851                            }
6852                            if (targetUid != -1) {
6853                                final UriPermission perm = findOrCreateUriPermissionLocked(
6854                                        sourcePkg, targetPkg, targetUid,
6855                                        new GrantUri(sourceUserId, uri, prefix));
6856                                perm.initPersistedModes(modeFlags, createdTime);
6857                            }
6858                        } else {
6859                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6860                                    + " but instead found " + pi);
6861                        }
6862                    }
6863                }
6864            }
6865        } catch (FileNotFoundException e) {
6866            // Missing grants is okay
6867        } catch (IOException e) {
6868            Log.wtf(TAG, "Failed reading Uri grants", e);
6869        } catch (XmlPullParserException e) {
6870            Log.wtf(TAG, "Failed reading Uri grants", e);
6871        } finally {
6872            IoUtils.closeQuietly(fis);
6873        }
6874    }
6875
6876    @Override
6877    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6878        enforceNotIsolatedCaller("takePersistableUriPermission");
6879
6880        Preconditions.checkFlagsArgument(modeFlags,
6881                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6882
6883        synchronized (this) {
6884            final int callingUid = Binder.getCallingUid();
6885            boolean persistChanged = false;
6886            GrantUri grantUri = new GrantUri(userId, uri, false);
6887
6888            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6889                    new GrantUri(userId, uri, false));
6890            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6891                    new GrantUri(userId, uri, true));
6892
6893            final boolean exactValid = (exactPerm != null)
6894                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6895            final boolean prefixValid = (prefixPerm != null)
6896                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6897
6898            if (!(exactValid || prefixValid)) {
6899                throw new SecurityException("No persistable permission grants found for UID "
6900                        + callingUid + " and Uri " + grantUri.toSafeString());
6901            }
6902
6903            if (exactValid) {
6904                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6905            }
6906            if (prefixValid) {
6907                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6908            }
6909
6910            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6911
6912            if (persistChanged) {
6913                schedulePersistUriGrants();
6914            }
6915        }
6916    }
6917
6918    @Override
6919    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6920        enforceNotIsolatedCaller("releasePersistableUriPermission");
6921
6922        Preconditions.checkFlagsArgument(modeFlags,
6923                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6924
6925        synchronized (this) {
6926            final int callingUid = Binder.getCallingUid();
6927            boolean persistChanged = false;
6928
6929            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6930                    new GrantUri(userId, uri, false));
6931            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6932                    new GrantUri(userId, uri, true));
6933            if (exactPerm == null && prefixPerm == null) {
6934                throw new SecurityException("No permission grants found for UID " + callingUid
6935                        + " and Uri " + uri.toSafeString());
6936            }
6937
6938            if (exactPerm != null) {
6939                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6940                removeUriPermissionIfNeededLocked(exactPerm);
6941            }
6942            if (prefixPerm != null) {
6943                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6944                removeUriPermissionIfNeededLocked(prefixPerm);
6945            }
6946
6947            if (persistChanged) {
6948                schedulePersistUriGrants();
6949            }
6950        }
6951    }
6952
6953    /**
6954     * Prune any older {@link UriPermission} for the given UID until outstanding
6955     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6956     *
6957     * @return if any mutations occured that require persisting.
6958     */
6959    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6960        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6961        if (perms == null) return false;
6962        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6963
6964        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6965        for (UriPermission perm : perms.values()) {
6966            if (perm.persistedModeFlags != 0) {
6967                persisted.add(perm);
6968            }
6969        }
6970
6971        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6972        if (trimCount <= 0) return false;
6973
6974        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6975        for (int i = 0; i < trimCount; i++) {
6976            final UriPermission perm = persisted.get(i);
6977
6978            if (DEBUG_URI_PERMISSION) {
6979                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6980            }
6981
6982            perm.releasePersistableModes(~0);
6983            removeUriPermissionIfNeededLocked(perm);
6984        }
6985
6986        return true;
6987    }
6988
6989    @Override
6990    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6991            String packageName, boolean incoming) {
6992        enforceNotIsolatedCaller("getPersistedUriPermissions");
6993        Preconditions.checkNotNull(packageName, "packageName");
6994
6995        final int callingUid = Binder.getCallingUid();
6996        final IPackageManager pm = AppGlobals.getPackageManager();
6997        try {
6998            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6999            if (packageUid != callingUid) {
7000                throw new SecurityException(
7001                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7002            }
7003        } catch (RemoteException e) {
7004            throw new SecurityException("Failed to verify package name ownership");
7005        }
7006
7007        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7008        synchronized (this) {
7009            if (incoming) {
7010                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7011                        callingUid);
7012                if (perms == null) {
7013                    Slog.w(TAG, "No permission grants found for " + packageName);
7014                } else {
7015                    for (UriPermission perm : perms.values()) {
7016                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7017                            result.add(perm.buildPersistedPublicApiObject());
7018                        }
7019                    }
7020                }
7021            } else {
7022                final int size = mGrantedUriPermissions.size();
7023                for (int i = 0; i < size; i++) {
7024                    final ArrayMap<GrantUri, UriPermission> perms =
7025                            mGrantedUriPermissions.valueAt(i);
7026                    for (UriPermission perm : perms.values()) {
7027                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7028                            result.add(perm.buildPersistedPublicApiObject());
7029                        }
7030                    }
7031                }
7032            }
7033        }
7034        return new ParceledListSlice<android.content.UriPermission>(result);
7035    }
7036
7037    @Override
7038    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7039        synchronized (this) {
7040            ProcessRecord app =
7041                who != null ? getRecordForAppLocked(who) : null;
7042            if (app == null) return;
7043
7044            Message msg = Message.obtain();
7045            msg.what = WAIT_FOR_DEBUGGER_MSG;
7046            msg.obj = app;
7047            msg.arg1 = waiting ? 1 : 0;
7048            mHandler.sendMessage(msg);
7049        }
7050    }
7051
7052    @Override
7053    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7054        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7055        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7056        outInfo.availMem = Process.getFreeMemory();
7057        outInfo.totalMem = Process.getTotalMemory();
7058        outInfo.threshold = homeAppMem;
7059        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7060        outInfo.hiddenAppThreshold = cachedAppMem;
7061        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7062                ProcessList.SERVICE_ADJ);
7063        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7064                ProcessList.VISIBLE_APP_ADJ);
7065        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7066                ProcessList.FOREGROUND_APP_ADJ);
7067    }
7068
7069    // =========================================================
7070    // TASK MANAGEMENT
7071    // =========================================================
7072
7073    @Override
7074    public List<IAppTask> getAppTasks() {
7075        int callingUid = Binder.getCallingUid();
7076        long ident = Binder.clearCallingIdentity();
7077        synchronized(this) {
7078            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7079            try {
7080                if (localLOGV) Slog.v(TAG, "getAppTasks");
7081
7082                final int N = mRecentTasks.size();
7083                for (int i = 0; i < N; i++) {
7084                    TaskRecord tr = mRecentTasks.get(i);
7085                    // Skip tasks that are not created by the caller
7086                    if (tr.creatorUid == callingUid) {
7087                        ActivityManager.RecentTaskInfo taskInfo =
7088                                createRecentTaskInfoFromTaskRecord(tr);
7089                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7090                        list.add(taskImpl);
7091                    }
7092                }
7093            } finally {
7094                Binder.restoreCallingIdentity(ident);
7095            }
7096            return list;
7097        }
7098    }
7099
7100    @Override
7101    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7102        final int callingUid = Binder.getCallingUid();
7103        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7104
7105        synchronized(this) {
7106            if (localLOGV) Slog.v(
7107                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7108
7109            final boolean allowed = checkCallingPermission(
7110                    android.Manifest.permission.GET_TASKS)
7111                    == PackageManager.PERMISSION_GRANTED;
7112            if (!allowed) {
7113                Slog.w(TAG, "getTasks: caller " + callingUid
7114                        + " does not hold GET_TASKS; limiting output");
7115            }
7116
7117            // TODO: Improve with MRU list from all ActivityStacks.
7118            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7119        }
7120
7121        return list;
7122    }
7123
7124    TaskRecord getMostRecentTask() {
7125        return mRecentTasks.get(0);
7126    }
7127
7128    /**
7129     * Creates a new RecentTaskInfo from a TaskRecord.
7130     */
7131    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7132        // Update the task description to reflect any changes in the task stack
7133        tr.updateTaskDescription();
7134
7135        // Compose the recent task info
7136        ActivityManager.RecentTaskInfo rti
7137                = new ActivityManager.RecentTaskInfo();
7138        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7139        rti.persistentId = tr.taskId;
7140        rti.baseIntent = new Intent(tr.getBaseIntent());
7141        rti.origActivity = tr.origActivity;
7142        rti.description = tr.lastDescription;
7143        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7144        rti.userId = tr.userId;
7145        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7146        return rti;
7147    }
7148
7149    @Override
7150    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7151            int flags, int userId) {
7152        final int callingUid = Binder.getCallingUid();
7153        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7154                false, true, "getRecentTasks", null);
7155
7156        synchronized (this) {
7157            final boolean allowed = checkCallingPermission(
7158                    android.Manifest.permission.GET_TASKS)
7159                    == PackageManager.PERMISSION_GRANTED;
7160            if (!allowed) {
7161                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7162                        + " does not hold GET_TASKS; limiting output");
7163            }
7164            final boolean detailed = checkCallingPermission(
7165                    android.Manifest.permission.GET_DETAILED_TASKS)
7166                    == PackageManager.PERMISSION_GRANTED;
7167
7168            IPackageManager pm = AppGlobals.getPackageManager();
7169
7170            final int N = mRecentTasks.size();
7171            ArrayList<ActivityManager.RecentTaskInfo> res
7172                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7173                            maxNum < N ? maxNum : N);
7174
7175            final Set<Integer> includedUsers;
7176            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7177                includedUsers = getProfileIdsLocked(userId);
7178            } else {
7179                includedUsers = new HashSet<Integer>();
7180            }
7181            includedUsers.add(Integer.valueOf(userId));
7182            for (int i=0; i<N && maxNum > 0; i++) {
7183                TaskRecord tr = mRecentTasks.get(i);
7184                // Only add calling user or related users recent tasks
7185                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7186
7187                // Return the entry if desired by the caller.  We always return
7188                // the first entry, because callers always expect this to be the
7189                // foreground app.  We may filter others if the caller has
7190                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7191                // we should exclude the entry.
7192
7193                if (i == 0
7194                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7195                        || (tr.intent == null)
7196                        || ((tr.intent.getFlags()
7197                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7198                    if (!allowed) {
7199                        // If the caller doesn't have the GET_TASKS permission, then only
7200                        // allow them to see a small subset of tasks -- their own and home.
7201                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7202                            continue;
7203                        }
7204                    }
7205
7206                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7207                    if (!detailed) {
7208                        rti.baseIntent.replaceExtras((Bundle)null);
7209                    }
7210
7211                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7212                        // Check whether this activity is currently available.
7213                        try {
7214                            if (rti.origActivity != null) {
7215                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7216                                        == null) {
7217                                    continue;
7218                                }
7219                            } else if (rti.baseIntent != null) {
7220                                if (pm.queryIntentActivities(rti.baseIntent,
7221                                        null, 0, userId) == null) {
7222                                    continue;
7223                                }
7224                            }
7225                        } catch (RemoteException e) {
7226                            // Will never happen.
7227                        }
7228                    }
7229
7230                    res.add(rti);
7231                    maxNum--;
7232                }
7233            }
7234            return res;
7235        }
7236    }
7237
7238    private TaskRecord recentTaskForIdLocked(int id) {
7239        final int N = mRecentTasks.size();
7240            for (int i=0; i<N; i++) {
7241                TaskRecord tr = mRecentTasks.get(i);
7242                if (tr.taskId == id) {
7243                    return tr;
7244                }
7245            }
7246            return null;
7247    }
7248
7249    @Override
7250    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7251        synchronized (this) {
7252            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7253                    "getTaskThumbnails()");
7254            TaskRecord tr = recentTaskForIdLocked(id);
7255            if (tr != null) {
7256                return tr.getTaskThumbnailsLocked();
7257            }
7258        }
7259        return null;
7260    }
7261
7262    @Override
7263    public Bitmap getTaskTopThumbnail(int id) {
7264        synchronized (this) {
7265            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7266                    "getTaskTopThumbnail()");
7267            TaskRecord tr = recentTaskForIdLocked(id);
7268            if (tr != null) {
7269                return tr.getTaskTopThumbnailLocked();
7270            }
7271        }
7272        return null;
7273    }
7274
7275    @Override
7276    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7277        synchronized (this) {
7278            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7279            if (r != null) {
7280                r.taskDescription = td;
7281                r.task.updateTaskDescription();
7282            }
7283        }
7284    }
7285
7286    @Override
7287    public boolean removeSubTask(int taskId, int subTaskIndex) {
7288        synchronized (this) {
7289            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7290                    "removeSubTask()");
7291            long ident = Binder.clearCallingIdentity();
7292            try {
7293                TaskRecord tr = recentTaskForIdLocked(taskId);
7294                if (tr != null) {
7295                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7296                }
7297                return false;
7298            } finally {
7299                Binder.restoreCallingIdentity(ident);
7300            }
7301        }
7302    }
7303
7304    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7305        if (!pr.killedByAm) {
7306            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7307            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7308                    pr.processName, pr.setAdj, reason);
7309            pr.killedByAm = true;
7310            Process.killProcessQuiet(pr.pid);
7311        }
7312    }
7313
7314    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7315        tr.disposeThumbnail();
7316        mRecentTasks.remove(tr);
7317        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7318        Intent baseIntent = new Intent(
7319                tr.intent != null ? tr.intent : tr.affinityIntent);
7320        ComponentName component = baseIntent.getComponent();
7321        if (component == null) {
7322            Slog.w(TAG, "Now component for base intent of task: " + tr);
7323            return;
7324        }
7325
7326        // Find any running services associated with this app.
7327        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7328
7329        if (killProcesses) {
7330            // Find any running processes associated with this app.
7331            final String pkg = component.getPackageName();
7332            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7333            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7334            for (int i=0; i<pmap.size(); i++) {
7335                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7336                for (int j=0; j<uids.size(); j++) {
7337                    ProcessRecord proc = uids.valueAt(j);
7338                    if (proc.userId != tr.userId) {
7339                        continue;
7340                    }
7341                    if (!proc.pkgList.containsKey(pkg)) {
7342                        continue;
7343                    }
7344                    procs.add(proc);
7345                }
7346            }
7347
7348            // Kill the running processes.
7349            for (int i=0; i<procs.size(); i++) {
7350                ProcessRecord pr = procs.get(i);
7351                if (pr == mHomeProcess) {
7352                    // Don't kill the home process along with tasks from the same package.
7353                    continue;
7354                }
7355                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7356                    killUnneededProcessLocked(pr, "remove task");
7357                } else {
7358                    pr.waitingToKill = "remove task";
7359                }
7360            }
7361        }
7362    }
7363
7364    /**
7365     * Removes the task with the specified task id.
7366     *
7367     * @param taskId Identifier of the task to be removed.
7368     * @param flags Additional operational flags.  May be 0 or
7369     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7370     * @return Returns true if the given task was found and removed.
7371     */
7372    private boolean removeTaskByIdLocked(int taskId, int flags) {
7373        TaskRecord tr = recentTaskForIdLocked(taskId);
7374        if (tr != null) {
7375            tr.removeTaskActivitiesLocked(-1, false);
7376            cleanUpRemovedTaskLocked(tr, flags);
7377            if (tr.isPersistable) {
7378                notifyTaskPersisterLocked(tr, true);
7379            }
7380            return true;
7381        }
7382        return false;
7383    }
7384
7385    @Override
7386    public boolean removeTask(int taskId, int flags) {
7387        synchronized (this) {
7388            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7389                    "removeTask()");
7390            long ident = Binder.clearCallingIdentity();
7391            try {
7392                return removeTaskByIdLocked(taskId, flags);
7393            } finally {
7394                Binder.restoreCallingIdentity(ident);
7395            }
7396        }
7397    }
7398
7399    /**
7400     * TODO: Add mController hook
7401     */
7402    @Override
7403    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7404        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7405                "moveTaskToFront()");
7406
7407        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7408        synchronized(this) {
7409            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7410                    Binder.getCallingUid(), "Task to front")) {
7411                ActivityOptions.abort(options);
7412                return;
7413            }
7414            final long origId = Binder.clearCallingIdentity();
7415            try {
7416                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7417                if (task == null) {
7418                    return;
7419                }
7420                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7421                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7422                    return;
7423                }
7424                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7425            } finally {
7426                Binder.restoreCallingIdentity(origId);
7427            }
7428            ActivityOptions.abort(options);
7429        }
7430    }
7431
7432    @Override
7433    public void moveTaskToBack(int taskId) {
7434        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7435                "moveTaskToBack()");
7436
7437        synchronized(this) {
7438            TaskRecord tr = recentTaskForIdLocked(taskId);
7439            if (tr != null) {
7440                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7441                ActivityStack stack = tr.stack;
7442                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7443                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7444                            Binder.getCallingUid(), "Task to back")) {
7445                        return;
7446                    }
7447                }
7448                final long origId = Binder.clearCallingIdentity();
7449                try {
7450                    stack.moveTaskToBackLocked(taskId, null);
7451                } finally {
7452                    Binder.restoreCallingIdentity(origId);
7453                }
7454            }
7455        }
7456    }
7457
7458    /**
7459     * Moves an activity, and all of the other activities within the same task, to the bottom
7460     * of the history stack.  The activity's order within the task is unchanged.
7461     *
7462     * @param token A reference to the activity we wish to move
7463     * @param nonRoot If false then this only works if the activity is the root
7464     *                of a task; if true it will work for any activity in a task.
7465     * @return Returns true if the move completed, false if not.
7466     */
7467    @Override
7468    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7469        enforceNotIsolatedCaller("moveActivityTaskToBack");
7470        synchronized(this) {
7471            final long origId = Binder.clearCallingIdentity();
7472            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7473            if (taskId >= 0) {
7474                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7475            }
7476            Binder.restoreCallingIdentity(origId);
7477        }
7478        return false;
7479    }
7480
7481    @Override
7482    public void moveTaskBackwards(int task) {
7483        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7484                "moveTaskBackwards()");
7485
7486        synchronized(this) {
7487            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7488                    Binder.getCallingUid(), "Task backwards")) {
7489                return;
7490            }
7491            final long origId = Binder.clearCallingIdentity();
7492            moveTaskBackwardsLocked(task);
7493            Binder.restoreCallingIdentity(origId);
7494        }
7495    }
7496
7497    private final void moveTaskBackwardsLocked(int task) {
7498        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7499    }
7500
7501    @Override
7502    public IBinder getHomeActivityToken() throws RemoteException {
7503        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7504                "getHomeActivityToken()");
7505        synchronized (this) {
7506            return mStackSupervisor.getHomeActivityToken();
7507        }
7508    }
7509
7510    @Override
7511    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7512            IActivityContainerCallback callback) throws RemoteException {
7513        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7514                "createActivityContainer()");
7515        synchronized (this) {
7516            if (parentActivityToken == null) {
7517                throw new IllegalArgumentException("parent token must not be null");
7518            }
7519            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7520            if (r == null) {
7521                return null;
7522            }
7523            if (callback == null) {
7524                throw new IllegalArgumentException("callback must not be null");
7525            }
7526            return mStackSupervisor.createActivityContainer(r, callback);
7527        }
7528    }
7529
7530    @Override
7531    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7532        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7533                "deleteActivityContainer()");
7534        synchronized (this) {
7535            mStackSupervisor.deleteActivityContainer(container);
7536        }
7537    }
7538
7539    @Override
7540    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7541            throws RemoteException {
7542        synchronized (this) {
7543            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7544            if (stack != null) {
7545                return stack.mActivityContainer;
7546            }
7547            return null;
7548        }
7549    }
7550
7551    @Override
7552    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7553        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7554                "moveTaskToStack()");
7555        if (stackId == HOME_STACK_ID) {
7556            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7557                    new RuntimeException("here").fillInStackTrace());
7558        }
7559        synchronized (this) {
7560            long ident = Binder.clearCallingIdentity();
7561            try {
7562                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7563                        + stackId + " toTop=" + toTop);
7564                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7565            } finally {
7566                Binder.restoreCallingIdentity(ident);
7567            }
7568        }
7569    }
7570
7571    @Override
7572    public void resizeStack(int stackBoxId, Rect bounds) {
7573        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7574                "resizeStackBox()");
7575        long ident = Binder.clearCallingIdentity();
7576        try {
7577            mWindowManager.resizeStack(stackBoxId, bounds);
7578        } finally {
7579            Binder.restoreCallingIdentity(ident);
7580        }
7581    }
7582
7583    @Override
7584    public List<StackInfo> getAllStackInfos() {
7585        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7586                "getAllStackInfos()");
7587        long ident = Binder.clearCallingIdentity();
7588        try {
7589            synchronized (this) {
7590                return mStackSupervisor.getAllStackInfosLocked();
7591            }
7592        } finally {
7593            Binder.restoreCallingIdentity(ident);
7594        }
7595    }
7596
7597    @Override
7598    public StackInfo getStackInfo(int stackId) {
7599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7600                "getStackInfo()");
7601        long ident = Binder.clearCallingIdentity();
7602        try {
7603            synchronized (this) {
7604                return mStackSupervisor.getStackInfoLocked(stackId);
7605            }
7606        } finally {
7607            Binder.restoreCallingIdentity(ident);
7608        }
7609    }
7610
7611    @Override
7612    public boolean isInHomeStack(int taskId) {
7613        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7614                "getStackInfo()");
7615        long ident = Binder.clearCallingIdentity();
7616        try {
7617            synchronized (this) {
7618                TaskRecord tr = recentTaskForIdLocked(taskId);
7619                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7620            }
7621        } finally {
7622            Binder.restoreCallingIdentity(ident);
7623        }
7624    }
7625
7626    @Override
7627    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7628        synchronized(this) {
7629            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7630        }
7631    }
7632
7633    private boolean isLockTaskAuthorized(ComponentName name) {
7634        final DevicePolicyManager dpm = (DevicePolicyManager)
7635                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7636        return dpm != null && dpm.isLockTaskPermitted(name);
7637    }
7638
7639    private void startLockTaskMode(TaskRecord task) {
7640        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7641            return;
7642        }
7643        long ident = Binder.clearCallingIdentity();
7644        try {
7645            synchronized (this) {
7646                // Since we lost lock on task, make sure it is still there.
7647                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7648                if (task != null) {
7649                    mStackSupervisor.setLockTaskModeLocked(task);
7650                }
7651            }
7652        } finally {
7653            Binder.restoreCallingIdentity(ident);
7654        }
7655    }
7656
7657    @Override
7658    public void startLockTaskMode(int taskId) {
7659        long ident = Binder.clearCallingIdentity();
7660        try {
7661            final TaskRecord task;
7662            synchronized (this) {
7663                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7664            }
7665            if (task != null) {
7666                startLockTaskMode(task);
7667            }
7668        } finally {
7669            Binder.restoreCallingIdentity(ident);
7670        }
7671    }
7672
7673    @Override
7674    public void startLockTaskMode(IBinder token) {
7675        long ident = Binder.clearCallingIdentity();
7676        try {
7677            final TaskRecord task;
7678            synchronized (this) {
7679                final ActivityRecord r = ActivityRecord.forToken(token);
7680                if (r == null) {
7681                    return;
7682                }
7683                task = r.task;
7684            }
7685            if (task != null) {
7686                startLockTaskMode(task);
7687            }
7688        } finally {
7689            Binder.restoreCallingIdentity(ident);
7690        }
7691    }
7692
7693    @Override
7694    public void stopLockTaskMode() {
7695        // Check if the calling task is eligible to use lock task
7696        final int uid = Binder.getCallingUid();
7697        try {
7698            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7699            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7700                return;
7701            }
7702        } catch (RemoteException e) {
7703            Log.d(TAG, "stopLockTaskMode " + e);
7704            return;
7705        }
7706        // Stop lock task
7707        synchronized (this) {
7708            mStackSupervisor.setLockTaskModeLocked(null);
7709        }
7710    }
7711
7712    @Override
7713    public boolean isInLockTaskMode() {
7714        synchronized (this) {
7715            return mStackSupervisor.isInLockTaskMode();
7716        }
7717    }
7718
7719    // =========================================================
7720    // CONTENT PROVIDERS
7721    // =========================================================
7722
7723    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7724        List<ProviderInfo> providers = null;
7725        try {
7726            providers = AppGlobals.getPackageManager().
7727                queryContentProviders(app.processName, app.uid,
7728                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7729        } catch (RemoteException ex) {
7730        }
7731        if (DEBUG_MU)
7732            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7733        int userId = app.userId;
7734        if (providers != null) {
7735            int N = providers.size();
7736            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7737            for (int i=0; i<N; i++) {
7738                ProviderInfo cpi =
7739                    (ProviderInfo)providers.get(i);
7740                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7741                        cpi.name, cpi.flags);
7742                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7743                    // This is a singleton provider, but a user besides the
7744                    // default user is asking to initialize a process it runs
7745                    // in...  well, no, it doesn't actually run in this process,
7746                    // it runs in the process of the default user.  Get rid of it.
7747                    providers.remove(i);
7748                    N--;
7749                    i--;
7750                    continue;
7751                }
7752
7753                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7754                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7755                if (cpr == null) {
7756                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7757                    mProviderMap.putProviderByClass(comp, cpr);
7758                }
7759                if (DEBUG_MU)
7760                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7761                app.pubProviders.put(cpi.name, cpr);
7762                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7763                    // Don't add this if it is a platform component that is marked
7764                    // to run in multiple processes, because this is actually
7765                    // part of the framework so doesn't make sense to track as a
7766                    // separate apk in the process.
7767                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7768                }
7769                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7770            }
7771        }
7772        return providers;
7773    }
7774
7775    /**
7776     * Check if {@link ProcessRecord} has a possible chance at accessing the
7777     * given {@link ProviderInfo}. Final permission checking is always done
7778     * in {@link ContentProvider}.
7779     */
7780    private final String checkContentProviderPermissionLocked(
7781            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7782        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7783        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7784        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7785        // Looking for cross-user grants before to enforce the typical cross-users permissions
7786        if (userId != UserHandle.getUserId(callingUid)) {
7787            if (perms != null) {
7788                for (GrantUri grantUri : perms.keySet()) {
7789                    if (grantUri.sourceUserId == userId) {
7790                        String authority = grantUri.uri.getAuthority();
7791                        if (authority.equals(cpi.authority)) {
7792                            return null;
7793                        }
7794                    }
7795                }
7796            }
7797        }
7798        if (checkUser) {
7799            userId = handleIncomingUser(callingPid, callingUid, userId,
7800                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7801        }
7802        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7803                cpi.applicationInfo.uid, cpi.exported)
7804                == PackageManager.PERMISSION_GRANTED) {
7805            return null;
7806        }
7807        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7808                cpi.applicationInfo.uid, cpi.exported)
7809                == PackageManager.PERMISSION_GRANTED) {
7810            return null;
7811        }
7812
7813        PathPermission[] pps = cpi.pathPermissions;
7814        if (pps != null) {
7815            int i = pps.length;
7816            while (i > 0) {
7817                i--;
7818                PathPermission pp = pps[i];
7819                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7820                        cpi.applicationInfo.uid, cpi.exported)
7821                        == PackageManager.PERMISSION_GRANTED) {
7822                    return null;
7823                }
7824                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7825                        cpi.applicationInfo.uid, cpi.exported)
7826                        == PackageManager.PERMISSION_GRANTED) {
7827                    return null;
7828                }
7829            }
7830        }
7831
7832        if (perms != null) {
7833            for (GrantUri grantUri : perms.keySet()) {
7834                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7835                    return null;
7836                }
7837            }
7838        }
7839
7840        String msg;
7841        if (!cpi.exported) {
7842            msg = "Permission Denial: opening provider " + cpi.name
7843                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7844                    + ", uid=" + callingUid + ") that is not exported from uid "
7845                    + cpi.applicationInfo.uid;
7846        } else {
7847            msg = "Permission Denial: opening provider " + cpi.name
7848                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7849                    + ", uid=" + callingUid + ") requires "
7850                    + cpi.readPermission + " or " + cpi.writePermission;
7851        }
7852        Slog.w(TAG, msg);
7853        return msg;
7854    }
7855
7856    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7857            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7858        if (r != null) {
7859            for (int i=0; i<r.conProviders.size(); i++) {
7860                ContentProviderConnection conn = r.conProviders.get(i);
7861                if (conn.provider == cpr) {
7862                    if (DEBUG_PROVIDER) Slog.v(TAG,
7863                            "Adding provider requested by "
7864                            + r.processName + " from process "
7865                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7866                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7867                    if (stable) {
7868                        conn.stableCount++;
7869                        conn.numStableIncs++;
7870                    } else {
7871                        conn.unstableCount++;
7872                        conn.numUnstableIncs++;
7873                    }
7874                    return conn;
7875                }
7876            }
7877            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7878            if (stable) {
7879                conn.stableCount = 1;
7880                conn.numStableIncs = 1;
7881            } else {
7882                conn.unstableCount = 1;
7883                conn.numUnstableIncs = 1;
7884            }
7885            cpr.connections.add(conn);
7886            r.conProviders.add(conn);
7887            return conn;
7888        }
7889        cpr.addExternalProcessHandleLocked(externalProcessToken);
7890        return null;
7891    }
7892
7893    boolean decProviderCountLocked(ContentProviderConnection conn,
7894            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7895        if (conn != null) {
7896            cpr = conn.provider;
7897            if (DEBUG_PROVIDER) Slog.v(TAG,
7898                    "Removing provider requested by "
7899                    + conn.client.processName + " from process "
7900                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7901                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7902            if (stable) {
7903                conn.stableCount--;
7904            } else {
7905                conn.unstableCount--;
7906            }
7907            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7908                cpr.connections.remove(conn);
7909                conn.client.conProviders.remove(conn);
7910                return true;
7911            }
7912            return false;
7913        }
7914        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7915        return false;
7916    }
7917
7918    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7919            String name, IBinder token, boolean stable, int userId) {
7920        ContentProviderRecord cpr;
7921        ContentProviderConnection conn = null;
7922        ProviderInfo cpi = null;
7923
7924        synchronized(this) {
7925            ProcessRecord r = null;
7926            if (caller != null) {
7927                r = getRecordForAppLocked(caller);
7928                if (r == null) {
7929                    throw new SecurityException(
7930                            "Unable to find app for caller " + caller
7931                          + " (pid=" + Binder.getCallingPid()
7932                          + ") when getting content provider " + name);
7933                }
7934            }
7935
7936            boolean checkCrossUser = true;
7937
7938            // First check if this content provider has been published...
7939            cpr = mProviderMap.getProviderByName(name, userId);
7940            // If that didn't work, check if it exists for user 0 and then
7941            // verify that it's a singleton provider before using it.
7942            if (cpr == null && userId != UserHandle.USER_OWNER) {
7943                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
7944                if (cpr != null) {
7945                    cpi = cpr.info;
7946                    if (isSingleton(cpi.processName, cpi.applicationInfo,
7947                            cpi.name, cpi.flags)
7948                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
7949                        userId = UserHandle.USER_OWNER;
7950                        checkCrossUser = false;
7951                    } else {
7952                        cpr = null;
7953                        cpi = null;
7954                    }
7955                }
7956            }
7957
7958            boolean providerRunning = cpr != null;
7959            if (providerRunning) {
7960                cpi = cpr.info;
7961                String msg;
7962                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
7963                        != null) {
7964                    throw new SecurityException(msg);
7965                }
7966
7967                if (r != null && cpr.canRunHere(r)) {
7968                    // This provider has been published or is in the process
7969                    // of being published...  but it is also allowed to run
7970                    // in the caller's process, so don't make a connection
7971                    // and just let the caller instantiate its own instance.
7972                    ContentProviderHolder holder = cpr.newHolder(null);
7973                    // don't give caller the provider object, it needs
7974                    // to make its own.
7975                    holder.provider = null;
7976                    return holder;
7977                }
7978
7979                final long origId = Binder.clearCallingIdentity();
7980
7981                // In this case the provider instance already exists, so we can
7982                // return it right away.
7983                conn = incProviderCountLocked(r, cpr, token, stable);
7984                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7985                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7986                        // If this is a perceptible app accessing the provider,
7987                        // make sure to count it as being accessed and thus
7988                        // back up on the LRU list.  This is good because
7989                        // content providers are often expensive to start.
7990                        updateLruProcessLocked(cpr.proc, false, null);
7991                    }
7992                }
7993
7994                if (cpr.proc != null) {
7995                    if (false) {
7996                        if (cpr.name.flattenToShortString().equals(
7997                                "com.android.providers.calendar/.CalendarProvider2")) {
7998                            Slog.v(TAG, "****************** KILLING "
7999                                + cpr.name.flattenToShortString());
8000                            Process.killProcess(cpr.proc.pid);
8001                        }
8002                    }
8003                    boolean success = updateOomAdjLocked(cpr.proc);
8004                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8005                    // NOTE: there is still a race here where a signal could be
8006                    // pending on the process even though we managed to update its
8007                    // adj level.  Not sure what to do about this, but at least
8008                    // the race is now smaller.
8009                    if (!success) {
8010                        // Uh oh...  it looks like the provider's process
8011                        // has been killed on us.  We need to wait for a new
8012                        // process to be started, and make sure its death
8013                        // doesn't kill our process.
8014                        Slog.i(TAG,
8015                                "Existing provider " + cpr.name.flattenToShortString()
8016                                + " is crashing; detaching " + r);
8017                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8018                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8019                        if (!lastRef) {
8020                            // This wasn't the last ref our process had on
8021                            // the provider...  we have now been killed, bail.
8022                            return null;
8023                        }
8024                        providerRunning = false;
8025                        conn = null;
8026                    }
8027                }
8028
8029                Binder.restoreCallingIdentity(origId);
8030            }
8031
8032            boolean singleton;
8033            if (!providerRunning) {
8034                try {
8035                    cpi = AppGlobals.getPackageManager().
8036                        resolveContentProvider(name,
8037                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8038                } catch (RemoteException ex) {
8039                }
8040                if (cpi == null) {
8041                    return null;
8042                }
8043                // If the provider is a singleton AND
8044                // (it's a call within the same user || the provider is a
8045                // privileged app)
8046                // Then allow connecting to the singleton provider
8047                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8048                        cpi.name, cpi.flags)
8049                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8050                if (singleton) {
8051                    userId = UserHandle.USER_OWNER;
8052                }
8053                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8054
8055                String msg;
8056                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8057                        != null) {
8058                    throw new SecurityException(msg);
8059                }
8060
8061                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8062                        && !cpi.processName.equals("system")) {
8063                    // If this content provider does not run in the system
8064                    // process, and the system is not yet ready to run other
8065                    // processes, then fail fast instead of hanging.
8066                    throw new IllegalArgumentException(
8067                            "Attempt to launch content provider before system ready");
8068                }
8069
8070                // Make sure that the user who owns this provider is started.  If not,
8071                // we don't want to allow it to run.
8072                if (mStartedUsers.get(userId) == null) {
8073                    Slog.w(TAG, "Unable to launch app "
8074                            + cpi.applicationInfo.packageName + "/"
8075                            + cpi.applicationInfo.uid + " for provider "
8076                            + name + ": user " + userId + " is stopped");
8077                    return null;
8078                }
8079
8080                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8081                cpr = mProviderMap.getProviderByClass(comp, userId);
8082                final boolean firstClass = cpr == null;
8083                if (firstClass) {
8084                    try {
8085                        ApplicationInfo ai =
8086                            AppGlobals.getPackageManager().
8087                                getApplicationInfo(
8088                                        cpi.applicationInfo.packageName,
8089                                        STOCK_PM_FLAGS, userId);
8090                        if (ai == null) {
8091                            Slog.w(TAG, "No package info for content provider "
8092                                    + cpi.name);
8093                            return null;
8094                        }
8095                        ai = getAppInfoForUser(ai, userId);
8096                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8097                    } catch (RemoteException ex) {
8098                        // pm is in same process, this will never happen.
8099                    }
8100                }
8101
8102                if (r != null && cpr.canRunHere(r)) {
8103                    // If this is a multiprocess provider, then just return its
8104                    // info and allow the caller to instantiate it.  Only do
8105                    // this if the provider is the same user as the caller's
8106                    // process, or can run as root (so can be in any process).
8107                    return cpr.newHolder(null);
8108                }
8109
8110                if (DEBUG_PROVIDER) {
8111                    RuntimeException e = new RuntimeException("here");
8112                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8113                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8114                }
8115
8116                // This is single process, and our app is now connecting to it.
8117                // See if we are already in the process of launching this
8118                // provider.
8119                final int N = mLaunchingProviders.size();
8120                int i;
8121                for (i=0; i<N; i++) {
8122                    if (mLaunchingProviders.get(i) == cpr) {
8123                        break;
8124                    }
8125                }
8126
8127                // If the provider is not already being launched, then get it
8128                // started.
8129                if (i >= N) {
8130                    final long origId = Binder.clearCallingIdentity();
8131
8132                    try {
8133                        // Content provider is now in use, its package can't be stopped.
8134                        try {
8135                            AppGlobals.getPackageManager().setPackageStoppedState(
8136                                    cpr.appInfo.packageName, false, userId);
8137                        } catch (RemoteException e) {
8138                        } catch (IllegalArgumentException e) {
8139                            Slog.w(TAG, "Failed trying to unstop package "
8140                                    + cpr.appInfo.packageName + ": " + e);
8141                        }
8142
8143                        // Use existing process if already started
8144                        ProcessRecord proc = getProcessRecordLocked(
8145                                cpi.processName, cpr.appInfo.uid, false);
8146                        if (proc != null && proc.thread != null) {
8147                            if (DEBUG_PROVIDER) {
8148                                Slog.d(TAG, "Installing in existing process " + proc);
8149                            }
8150                            proc.pubProviders.put(cpi.name, cpr);
8151                            try {
8152                                proc.thread.scheduleInstallProvider(cpi);
8153                            } catch (RemoteException e) {
8154                            }
8155                        } else {
8156                            proc = startProcessLocked(cpi.processName,
8157                                    cpr.appInfo, false, 0, "content provider",
8158                                    new ComponentName(cpi.applicationInfo.packageName,
8159                                            cpi.name), false, false, false);
8160                            if (proc == null) {
8161                                Slog.w(TAG, "Unable to launch app "
8162                                        + cpi.applicationInfo.packageName + "/"
8163                                        + cpi.applicationInfo.uid + " for provider "
8164                                        + name + ": process is bad");
8165                                return null;
8166                            }
8167                        }
8168                        cpr.launchingApp = proc;
8169                        mLaunchingProviders.add(cpr);
8170                    } finally {
8171                        Binder.restoreCallingIdentity(origId);
8172                    }
8173                }
8174
8175                // Make sure the provider is published (the same provider class
8176                // may be published under multiple names).
8177                if (firstClass) {
8178                    mProviderMap.putProviderByClass(comp, cpr);
8179                }
8180
8181                mProviderMap.putProviderByName(name, cpr);
8182                conn = incProviderCountLocked(r, cpr, token, stable);
8183                if (conn != null) {
8184                    conn.waiting = true;
8185                }
8186            }
8187        }
8188
8189        // Wait for the provider to be published...
8190        synchronized (cpr) {
8191            while (cpr.provider == null) {
8192                if (cpr.launchingApp == null) {
8193                    Slog.w(TAG, "Unable to launch app "
8194                            + cpi.applicationInfo.packageName + "/"
8195                            + cpi.applicationInfo.uid + " for provider "
8196                            + name + ": launching app became null");
8197                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8198                            UserHandle.getUserId(cpi.applicationInfo.uid),
8199                            cpi.applicationInfo.packageName,
8200                            cpi.applicationInfo.uid, name);
8201                    return null;
8202                }
8203                try {
8204                    if (DEBUG_MU) {
8205                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8206                                + cpr.launchingApp);
8207                    }
8208                    if (conn != null) {
8209                        conn.waiting = true;
8210                    }
8211                    cpr.wait();
8212                } catch (InterruptedException ex) {
8213                } finally {
8214                    if (conn != null) {
8215                        conn.waiting = false;
8216                    }
8217                }
8218            }
8219        }
8220        return cpr != null ? cpr.newHolder(conn) : null;
8221    }
8222
8223    @Override
8224    public final ContentProviderHolder getContentProvider(
8225            IApplicationThread caller, String name, int userId, boolean stable) {
8226        enforceNotIsolatedCaller("getContentProvider");
8227        if (caller == null) {
8228            String msg = "null IApplicationThread when getting content provider "
8229                    + name;
8230            Slog.w(TAG, msg);
8231            throw new SecurityException(msg);
8232        }
8233        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8234        // with cross-user grant.
8235        return getContentProviderImpl(caller, name, null, stable, userId);
8236    }
8237
8238    public ContentProviderHolder getContentProviderExternal(
8239            String name, int userId, IBinder token) {
8240        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8241            "Do not have permission in call getContentProviderExternal()");
8242        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8243                false, true, "getContentProvider", null);
8244        return getContentProviderExternalUnchecked(name, token, userId);
8245    }
8246
8247    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8248            IBinder token, int userId) {
8249        return getContentProviderImpl(null, name, token, true, userId);
8250    }
8251
8252    /**
8253     * Drop a content provider from a ProcessRecord's bookkeeping
8254     */
8255    public void removeContentProvider(IBinder connection, boolean stable) {
8256        enforceNotIsolatedCaller("removeContentProvider");
8257        long ident = Binder.clearCallingIdentity();
8258        try {
8259            synchronized (this) {
8260                ContentProviderConnection conn;
8261                try {
8262                    conn = (ContentProviderConnection)connection;
8263                } catch (ClassCastException e) {
8264                    String msg ="removeContentProvider: " + connection
8265                            + " not a ContentProviderConnection";
8266                    Slog.w(TAG, msg);
8267                    throw new IllegalArgumentException(msg);
8268                }
8269                if (conn == null) {
8270                    throw new NullPointerException("connection is null");
8271                }
8272                if (decProviderCountLocked(conn, null, null, stable)) {
8273                    updateOomAdjLocked();
8274                }
8275            }
8276        } finally {
8277            Binder.restoreCallingIdentity(ident);
8278        }
8279    }
8280
8281    public void removeContentProviderExternal(String name, IBinder token) {
8282        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8283            "Do not have permission in call removeContentProviderExternal()");
8284        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8285    }
8286
8287    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8288        synchronized (this) {
8289            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8290            if(cpr == null) {
8291                //remove from mProvidersByClass
8292                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8293                return;
8294            }
8295
8296            //update content provider record entry info
8297            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8298            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8299            if (localCpr.hasExternalProcessHandles()) {
8300                if (localCpr.removeExternalProcessHandleLocked(token)) {
8301                    updateOomAdjLocked();
8302                } else {
8303                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8304                            + " with no external reference for token: "
8305                            + token + ".");
8306                }
8307            } else {
8308                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8309                        + " with no external references.");
8310            }
8311        }
8312    }
8313
8314    public final void publishContentProviders(IApplicationThread caller,
8315            List<ContentProviderHolder> providers) {
8316        if (providers == null) {
8317            return;
8318        }
8319
8320        enforceNotIsolatedCaller("publishContentProviders");
8321        synchronized (this) {
8322            final ProcessRecord r = getRecordForAppLocked(caller);
8323            if (DEBUG_MU)
8324                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8325            if (r == null) {
8326                throw new SecurityException(
8327                        "Unable to find app for caller " + caller
8328                      + " (pid=" + Binder.getCallingPid()
8329                      + ") when publishing content providers");
8330            }
8331
8332            final long origId = Binder.clearCallingIdentity();
8333
8334            final int N = providers.size();
8335            for (int i=0; i<N; i++) {
8336                ContentProviderHolder src = providers.get(i);
8337                if (src == null || src.info == null || src.provider == null) {
8338                    continue;
8339                }
8340                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8341                if (DEBUG_MU)
8342                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8343                if (dst != null) {
8344                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8345                    mProviderMap.putProviderByClass(comp, dst);
8346                    String names[] = dst.info.authority.split(";");
8347                    for (int j = 0; j < names.length; j++) {
8348                        mProviderMap.putProviderByName(names[j], dst);
8349                    }
8350
8351                    int NL = mLaunchingProviders.size();
8352                    int j;
8353                    for (j=0; j<NL; j++) {
8354                        if (mLaunchingProviders.get(j) == dst) {
8355                            mLaunchingProviders.remove(j);
8356                            j--;
8357                            NL--;
8358                        }
8359                    }
8360                    synchronized (dst) {
8361                        dst.provider = src.provider;
8362                        dst.proc = r;
8363                        dst.notifyAll();
8364                    }
8365                    updateOomAdjLocked(r);
8366                }
8367            }
8368
8369            Binder.restoreCallingIdentity(origId);
8370        }
8371    }
8372
8373    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8374        ContentProviderConnection conn;
8375        try {
8376            conn = (ContentProviderConnection)connection;
8377        } catch (ClassCastException e) {
8378            String msg ="refContentProvider: " + connection
8379                    + " not a ContentProviderConnection";
8380            Slog.w(TAG, msg);
8381            throw new IllegalArgumentException(msg);
8382        }
8383        if (conn == null) {
8384            throw new NullPointerException("connection is null");
8385        }
8386
8387        synchronized (this) {
8388            if (stable > 0) {
8389                conn.numStableIncs += stable;
8390            }
8391            stable = conn.stableCount + stable;
8392            if (stable < 0) {
8393                throw new IllegalStateException("stableCount < 0: " + stable);
8394            }
8395
8396            if (unstable > 0) {
8397                conn.numUnstableIncs += unstable;
8398            }
8399            unstable = conn.unstableCount + unstable;
8400            if (unstable < 0) {
8401                throw new IllegalStateException("unstableCount < 0: " + unstable);
8402            }
8403
8404            if ((stable+unstable) <= 0) {
8405                throw new IllegalStateException("ref counts can't go to zero here: stable="
8406                        + stable + " unstable=" + unstable);
8407            }
8408            conn.stableCount = stable;
8409            conn.unstableCount = unstable;
8410            return !conn.dead;
8411        }
8412    }
8413
8414    public void unstableProviderDied(IBinder connection) {
8415        ContentProviderConnection conn;
8416        try {
8417            conn = (ContentProviderConnection)connection;
8418        } catch (ClassCastException e) {
8419            String msg ="refContentProvider: " + connection
8420                    + " not a ContentProviderConnection";
8421            Slog.w(TAG, msg);
8422            throw new IllegalArgumentException(msg);
8423        }
8424        if (conn == null) {
8425            throw new NullPointerException("connection is null");
8426        }
8427
8428        // Safely retrieve the content provider associated with the connection.
8429        IContentProvider provider;
8430        synchronized (this) {
8431            provider = conn.provider.provider;
8432        }
8433
8434        if (provider == null) {
8435            // Um, yeah, we're way ahead of you.
8436            return;
8437        }
8438
8439        // Make sure the caller is being honest with us.
8440        if (provider.asBinder().pingBinder()) {
8441            // Er, no, still looks good to us.
8442            synchronized (this) {
8443                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8444                        + " says " + conn + " died, but we don't agree");
8445                return;
8446            }
8447        }
8448
8449        // Well look at that!  It's dead!
8450        synchronized (this) {
8451            if (conn.provider.provider != provider) {
8452                // But something changed...  good enough.
8453                return;
8454            }
8455
8456            ProcessRecord proc = conn.provider.proc;
8457            if (proc == null || proc.thread == null) {
8458                // Seems like the process is already cleaned up.
8459                return;
8460            }
8461
8462            // As far as we're concerned, this is just like receiving a
8463            // death notification...  just a bit prematurely.
8464            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8465                    + ") early provider death");
8466            final long ident = Binder.clearCallingIdentity();
8467            try {
8468                appDiedLocked(proc, proc.pid, proc.thread);
8469            } finally {
8470                Binder.restoreCallingIdentity(ident);
8471            }
8472        }
8473    }
8474
8475    @Override
8476    public void appNotRespondingViaProvider(IBinder connection) {
8477        enforceCallingPermission(
8478                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8479
8480        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8481        if (conn == null) {
8482            Slog.w(TAG, "ContentProviderConnection is null");
8483            return;
8484        }
8485
8486        final ProcessRecord host = conn.provider.proc;
8487        if (host == null) {
8488            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8489            return;
8490        }
8491
8492        final long token = Binder.clearCallingIdentity();
8493        try {
8494            appNotResponding(host, null, null, false, "ContentProvider not responding");
8495        } finally {
8496            Binder.restoreCallingIdentity(token);
8497        }
8498    }
8499
8500    public final void installSystemProviders() {
8501        List<ProviderInfo> providers;
8502        synchronized (this) {
8503            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8504            providers = generateApplicationProvidersLocked(app);
8505            if (providers != null) {
8506                for (int i=providers.size()-1; i>=0; i--) {
8507                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8508                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8509                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8510                                + ": not system .apk");
8511                        providers.remove(i);
8512                    }
8513                }
8514            }
8515        }
8516        if (providers != null) {
8517            mSystemThread.installSystemProviders(providers);
8518        }
8519
8520        mCoreSettingsObserver = new CoreSettingsObserver(this);
8521
8522        mUsageStatsService.monitorPackages();
8523    }
8524
8525    /**
8526     * Allows app to retrieve the MIME type of a URI without having permission
8527     * to access its content provider.
8528     *
8529     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8530     *
8531     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8532     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8533     */
8534    public String getProviderMimeType(Uri uri, int userId) {
8535        enforceNotIsolatedCaller("getProviderMimeType");
8536        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8537                userId, false, true, "getProviderMimeType", null);
8538        final String name = uri.getAuthority();
8539        final long ident = Binder.clearCallingIdentity();
8540        ContentProviderHolder holder = null;
8541
8542        try {
8543            holder = getContentProviderExternalUnchecked(name, null, userId);
8544            if (holder != null) {
8545                return holder.provider.getType(uri);
8546            }
8547        } catch (RemoteException e) {
8548            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8549            return null;
8550        } finally {
8551            if (holder != null) {
8552                removeContentProviderExternalUnchecked(name, null, userId);
8553            }
8554            Binder.restoreCallingIdentity(ident);
8555        }
8556
8557        return null;
8558    }
8559
8560    // =========================================================
8561    // GLOBAL MANAGEMENT
8562    // =========================================================
8563
8564    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8565            boolean isolated) {
8566        String proc = customProcess != null ? customProcess : info.processName;
8567        BatteryStatsImpl.Uid.Proc ps = null;
8568        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8569        int uid = info.uid;
8570        if (isolated) {
8571            int userId = UserHandle.getUserId(uid);
8572            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8573            while (true) {
8574                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8575                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8576                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8577                }
8578                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8579                mNextIsolatedProcessUid++;
8580                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8581                    // No process for this uid, use it.
8582                    break;
8583                }
8584                stepsLeft--;
8585                if (stepsLeft <= 0) {
8586                    return null;
8587                }
8588            }
8589        }
8590        return new ProcessRecord(stats, info, proc, uid);
8591    }
8592
8593    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8594            String abiOverride) {
8595        ProcessRecord app;
8596        if (!isolated) {
8597            app = getProcessRecordLocked(info.processName, info.uid, true);
8598        } else {
8599            app = null;
8600        }
8601
8602        if (app == null) {
8603            app = newProcessRecordLocked(info, null, isolated);
8604            mProcessNames.put(info.processName, app.uid, app);
8605            if (isolated) {
8606                mIsolatedProcesses.put(app.uid, app);
8607            }
8608            updateLruProcessLocked(app, false, null);
8609            updateOomAdjLocked();
8610        }
8611
8612        // This package really, really can not be stopped.
8613        try {
8614            AppGlobals.getPackageManager().setPackageStoppedState(
8615                    info.packageName, false, UserHandle.getUserId(app.uid));
8616        } catch (RemoteException e) {
8617        } catch (IllegalArgumentException e) {
8618            Slog.w(TAG, "Failed trying to unstop package "
8619                    + info.packageName + ": " + e);
8620        }
8621
8622        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8623                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8624            app.persistent = true;
8625            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8626        }
8627        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8628            mPersistentStartingProcesses.add(app);
8629            startProcessLocked(app, "added application", app.processName,
8630                    abiOverride);
8631        }
8632
8633        return app;
8634    }
8635
8636    public void unhandledBack() {
8637        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8638                "unhandledBack()");
8639
8640        synchronized(this) {
8641            final long origId = Binder.clearCallingIdentity();
8642            try {
8643                getFocusedStack().unhandledBackLocked();
8644            } finally {
8645                Binder.restoreCallingIdentity(origId);
8646            }
8647        }
8648    }
8649
8650    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8651        enforceNotIsolatedCaller("openContentUri");
8652        final int userId = UserHandle.getCallingUserId();
8653        String name = uri.getAuthority();
8654        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8655        ParcelFileDescriptor pfd = null;
8656        if (cph != null) {
8657            // We record the binder invoker's uid in thread-local storage before
8658            // going to the content provider to open the file.  Later, in the code
8659            // that handles all permissions checks, we look for this uid and use
8660            // that rather than the Activity Manager's own uid.  The effect is that
8661            // we do the check against the caller's permissions even though it looks
8662            // to the content provider like the Activity Manager itself is making
8663            // the request.
8664            sCallerIdentity.set(new Identity(
8665                    Binder.getCallingPid(), Binder.getCallingUid()));
8666            try {
8667                pfd = cph.provider.openFile(null, uri, "r", null);
8668            } catch (FileNotFoundException e) {
8669                // do nothing; pfd will be returned null
8670            } finally {
8671                // Ensure that whatever happens, we clean up the identity state
8672                sCallerIdentity.remove();
8673            }
8674
8675            // We've got the fd now, so we're done with the provider.
8676            removeContentProviderExternalUnchecked(name, null, userId);
8677        } else {
8678            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8679        }
8680        return pfd;
8681    }
8682
8683    // Actually is sleeping or shutting down or whatever else in the future
8684    // is an inactive state.
8685    public boolean isSleepingOrShuttingDown() {
8686        return mSleeping || mShuttingDown;
8687    }
8688
8689    public boolean isSleeping() {
8690        return mSleeping;
8691    }
8692
8693    void goingToSleep() {
8694        synchronized(this) {
8695            mWentToSleep = true;
8696            updateEventDispatchingLocked();
8697            goToSleepIfNeededLocked();
8698        }
8699    }
8700
8701    void finishRunningVoiceLocked() {
8702        if (mRunningVoice) {
8703            mRunningVoice = false;
8704            goToSleepIfNeededLocked();
8705        }
8706    }
8707
8708    void goToSleepIfNeededLocked() {
8709        if (mWentToSleep && !mRunningVoice) {
8710            if (!mSleeping) {
8711                mSleeping = true;
8712                mStackSupervisor.goingToSleepLocked();
8713
8714                // Initialize the wake times of all processes.
8715                checkExcessivePowerUsageLocked(false);
8716                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8717                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8718                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8719            }
8720        }
8721    }
8722
8723    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8724        mTaskPersister.notify(task, flush);
8725    }
8726
8727    @Override
8728    public boolean shutdown(int timeout) {
8729        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8730                != PackageManager.PERMISSION_GRANTED) {
8731            throw new SecurityException("Requires permission "
8732                    + android.Manifest.permission.SHUTDOWN);
8733        }
8734
8735        boolean timedout = false;
8736
8737        synchronized(this) {
8738            mShuttingDown = true;
8739            updateEventDispatchingLocked();
8740            timedout = mStackSupervisor.shutdownLocked(timeout);
8741        }
8742
8743        mAppOpsService.shutdown();
8744        mUsageStatsService.shutdown();
8745        mBatteryStatsService.shutdown();
8746        synchronized (this) {
8747            mProcessStats.shutdownLocked();
8748        }
8749        notifyTaskPersisterLocked(null, true);
8750
8751        return timedout;
8752    }
8753
8754    public final void activitySlept(IBinder token) {
8755        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8756
8757        final long origId = Binder.clearCallingIdentity();
8758
8759        synchronized (this) {
8760            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8761            if (r != null) {
8762                mStackSupervisor.activitySleptLocked(r);
8763            }
8764        }
8765
8766        Binder.restoreCallingIdentity(origId);
8767    }
8768
8769    void logLockScreen(String msg) {
8770        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8771                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8772                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8773                mStackSupervisor.mDismissKeyguardOnNextActivity);
8774    }
8775
8776    private void comeOutOfSleepIfNeededLocked() {
8777        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8778            if (mSleeping) {
8779                mSleeping = false;
8780                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8781            }
8782        }
8783    }
8784
8785    void wakingUp() {
8786        synchronized(this) {
8787            mWentToSleep = false;
8788            updateEventDispatchingLocked();
8789            comeOutOfSleepIfNeededLocked();
8790        }
8791    }
8792
8793    void startRunningVoiceLocked() {
8794        if (!mRunningVoice) {
8795            mRunningVoice = true;
8796            comeOutOfSleepIfNeededLocked();
8797        }
8798    }
8799
8800    private void updateEventDispatchingLocked() {
8801        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8802    }
8803
8804    public void setLockScreenShown(boolean shown) {
8805        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8806                != PackageManager.PERMISSION_GRANTED) {
8807            throw new SecurityException("Requires permission "
8808                    + android.Manifest.permission.DEVICE_POWER);
8809        }
8810
8811        synchronized(this) {
8812            long ident = Binder.clearCallingIdentity();
8813            try {
8814                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8815                mLockScreenShown = shown;
8816                comeOutOfSleepIfNeededLocked();
8817            } finally {
8818                Binder.restoreCallingIdentity(ident);
8819            }
8820        }
8821    }
8822
8823    public void stopAppSwitches() {
8824        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8825                != PackageManager.PERMISSION_GRANTED) {
8826            throw new SecurityException("Requires permission "
8827                    + android.Manifest.permission.STOP_APP_SWITCHES);
8828        }
8829
8830        synchronized(this) {
8831            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8832                    + APP_SWITCH_DELAY_TIME;
8833            mDidAppSwitch = false;
8834            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8835            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8836            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8837        }
8838    }
8839
8840    public void resumeAppSwitches() {
8841        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8842                != PackageManager.PERMISSION_GRANTED) {
8843            throw new SecurityException("Requires permission "
8844                    + android.Manifest.permission.STOP_APP_SWITCHES);
8845        }
8846
8847        synchronized(this) {
8848            // Note that we don't execute any pending app switches... we will
8849            // let those wait until either the timeout, or the next start
8850            // activity request.
8851            mAppSwitchesAllowedTime = 0;
8852        }
8853    }
8854
8855    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8856            String name) {
8857        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8858            return true;
8859        }
8860
8861        final int perm = checkComponentPermission(
8862                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8863                callingUid, -1, true);
8864        if (perm == PackageManager.PERMISSION_GRANTED) {
8865            return true;
8866        }
8867
8868        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8869        return false;
8870    }
8871
8872    public void setDebugApp(String packageName, boolean waitForDebugger,
8873            boolean persistent) {
8874        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8875                "setDebugApp()");
8876
8877        long ident = Binder.clearCallingIdentity();
8878        try {
8879            // Note that this is not really thread safe if there are multiple
8880            // callers into it at the same time, but that's not a situation we
8881            // care about.
8882            if (persistent) {
8883                final ContentResolver resolver = mContext.getContentResolver();
8884                Settings.Global.putString(
8885                    resolver, Settings.Global.DEBUG_APP,
8886                    packageName);
8887                Settings.Global.putInt(
8888                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8889                    waitForDebugger ? 1 : 0);
8890            }
8891
8892            synchronized (this) {
8893                if (!persistent) {
8894                    mOrigDebugApp = mDebugApp;
8895                    mOrigWaitForDebugger = mWaitForDebugger;
8896                }
8897                mDebugApp = packageName;
8898                mWaitForDebugger = waitForDebugger;
8899                mDebugTransient = !persistent;
8900                if (packageName != null) {
8901                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8902                            false, UserHandle.USER_ALL, "set debug app");
8903                }
8904            }
8905        } finally {
8906            Binder.restoreCallingIdentity(ident);
8907        }
8908    }
8909
8910    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8911        synchronized (this) {
8912            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8913            if (!isDebuggable) {
8914                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8915                    throw new SecurityException("Process not debuggable: " + app.packageName);
8916                }
8917            }
8918
8919            mOpenGlTraceApp = processName;
8920        }
8921    }
8922
8923    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8924            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8925        synchronized (this) {
8926            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8927            if (!isDebuggable) {
8928                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8929                    throw new SecurityException("Process not debuggable: " + app.packageName);
8930                }
8931            }
8932            mProfileApp = processName;
8933            mProfileFile = profileFile;
8934            if (mProfileFd != null) {
8935                try {
8936                    mProfileFd.close();
8937                } catch (IOException e) {
8938                }
8939                mProfileFd = null;
8940            }
8941            mProfileFd = profileFd;
8942            mProfileType = 0;
8943            mAutoStopProfiler = autoStopProfiler;
8944        }
8945    }
8946
8947    @Override
8948    public void setAlwaysFinish(boolean enabled) {
8949        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8950                "setAlwaysFinish()");
8951
8952        Settings.Global.putInt(
8953                mContext.getContentResolver(),
8954                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8955
8956        synchronized (this) {
8957            mAlwaysFinishActivities = enabled;
8958        }
8959    }
8960
8961    @Override
8962    public void setActivityController(IActivityController controller) {
8963        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8964                "setActivityController()");
8965        synchronized (this) {
8966            mController = controller;
8967            Watchdog.getInstance().setActivityController(controller);
8968        }
8969    }
8970
8971    @Override
8972    public void setUserIsMonkey(boolean userIsMonkey) {
8973        synchronized (this) {
8974            synchronized (mPidsSelfLocked) {
8975                final int callingPid = Binder.getCallingPid();
8976                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8977                if (precessRecord == null) {
8978                    throw new SecurityException("Unknown process: " + callingPid);
8979                }
8980                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8981                    throw new SecurityException("Only an instrumentation process "
8982                            + "with a UiAutomation can call setUserIsMonkey");
8983                }
8984            }
8985            mUserIsMonkey = userIsMonkey;
8986        }
8987    }
8988
8989    @Override
8990    public boolean isUserAMonkey() {
8991        synchronized (this) {
8992            // If there is a controller also implies the user is a monkey.
8993            return (mUserIsMonkey || mController != null);
8994        }
8995    }
8996
8997    public void requestBugReport() {
8998        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8999        SystemProperties.set("ctl.start", "bugreport");
9000    }
9001
9002    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9003        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9004    }
9005
9006    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9007        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9008            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9009        }
9010        return KEY_DISPATCHING_TIMEOUT;
9011    }
9012
9013    @Override
9014    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9015        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9016                != PackageManager.PERMISSION_GRANTED) {
9017            throw new SecurityException("Requires permission "
9018                    + android.Manifest.permission.FILTER_EVENTS);
9019        }
9020        ProcessRecord proc;
9021        long timeout;
9022        synchronized (this) {
9023            synchronized (mPidsSelfLocked) {
9024                proc = mPidsSelfLocked.get(pid);
9025            }
9026            timeout = getInputDispatchingTimeoutLocked(proc);
9027        }
9028
9029        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9030            return -1;
9031        }
9032
9033        return timeout;
9034    }
9035
9036    /**
9037     * Handle input dispatching timeouts.
9038     * Returns whether input dispatching should be aborted or not.
9039     */
9040    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9041            final ActivityRecord activity, final ActivityRecord parent,
9042            final boolean aboveSystem, String reason) {
9043        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9044                != PackageManager.PERMISSION_GRANTED) {
9045            throw new SecurityException("Requires permission "
9046                    + android.Manifest.permission.FILTER_EVENTS);
9047        }
9048
9049        final String annotation;
9050        if (reason == null) {
9051            annotation = "Input dispatching timed out";
9052        } else {
9053            annotation = "Input dispatching timed out (" + reason + ")";
9054        }
9055
9056        if (proc != null) {
9057            synchronized (this) {
9058                if (proc.debugging) {
9059                    return false;
9060                }
9061
9062                if (mDidDexOpt) {
9063                    // Give more time since we were dexopting.
9064                    mDidDexOpt = false;
9065                    return false;
9066                }
9067
9068                if (proc.instrumentationClass != null) {
9069                    Bundle info = new Bundle();
9070                    info.putString("shortMsg", "keyDispatchingTimedOut");
9071                    info.putString("longMsg", annotation);
9072                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9073                    return true;
9074                }
9075            }
9076            mHandler.post(new Runnable() {
9077                @Override
9078                public void run() {
9079                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9080                }
9081            });
9082        }
9083
9084        return true;
9085    }
9086
9087    public Bundle getAssistContextExtras(int requestType) {
9088        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9089                "getAssistContextExtras()");
9090        PendingAssistExtras pae;
9091        Bundle extras = new Bundle();
9092        synchronized (this) {
9093            ActivityRecord activity = getFocusedStack().mResumedActivity;
9094            if (activity == null) {
9095                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9096                return null;
9097            }
9098            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9099            if (activity.app == null || activity.app.thread == null) {
9100                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9101                return extras;
9102            }
9103            if (activity.app.pid == Binder.getCallingPid()) {
9104                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9105                return extras;
9106            }
9107            pae = new PendingAssistExtras(activity);
9108            try {
9109                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9110                        requestType);
9111                mPendingAssistExtras.add(pae);
9112                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9113            } catch (RemoteException e) {
9114                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9115                return extras;
9116            }
9117        }
9118        synchronized (pae) {
9119            while (!pae.haveResult) {
9120                try {
9121                    pae.wait();
9122                } catch (InterruptedException e) {
9123                }
9124            }
9125            if (pae.result != null) {
9126                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9127            }
9128        }
9129        synchronized (this) {
9130            mPendingAssistExtras.remove(pae);
9131            mHandler.removeCallbacks(pae);
9132        }
9133        return extras;
9134    }
9135
9136    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9137        PendingAssistExtras pae = (PendingAssistExtras)token;
9138        synchronized (pae) {
9139            pae.result = extras;
9140            pae.haveResult = true;
9141            pae.notifyAll();
9142        }
9143    }
9144
9145    public void registerProcessObserver(IProcessObserver observer) {
9146        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9147                "registerProcessObserver()");
9148        synchronized (this) {
9149            mProcessObservers.register(observer);
9150        }
9151    }
9152
9153    @Override
9154    public void unregisterProcessObserver(IProcessObserver observer) {
9155        synchronized (this) {
9156            mProcessObservers.unregister(observer);
9157        }
9158    }
9159
9160    @Override
9161    public boolean convertFromTranslucent(IBinder token) {
9162        final long origId = Binder.clearCallingIdentity();
9163        try {
9164            synchronized (this) {
9165                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9166                if (r == null) {
9167                    return false;
9168                }
9169                if (r.changeWindowTranslucency(true)) {
9170                    mWindowManager.setAppFullscreen(token, true);
9171                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9172                    return true;
9173                }
9174                return false;
9175            }
9176        } finally {
9177            Binder.restoreCallingIdentity(origId);
9178        }
9179    }
9180
9181    @Override
9182    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9183        final long origId = Binder.clearCallingIdentity();
9184        try {
9185            synchronized (this) {
9186                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9187                if (r == null) {
9188                    return false;
9189                }
9190                if (r.changeWindowTranslucency(false)) {
9191                    r.task.stack.convertToTranslucent(r, options);
9192                    mWindowManager.setAppFullscreen(token, false);
9193                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9194                    return true;
9195                }
9196                return false;
9197            }
9198        } finally {
9199            Binder.restoreCallingIdentity(origId);
9200        }
9201    }
9202
9203    @Override
9204    public ActivityOptions getActivityOptions(IBinder token) {
9205        final long origId = Binder.clearCallingIdentity();
9206        try {
9207            synchronized (this) {
9208                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9209                if (r != null) {
9210                    final ActivityOptions activityOptions = r.pendingOptions;
9211                    r.pendingOptions = null;
9212                    return activityOptions;
9213                }
9214                return null;
9215            }
9216        } finally {
9217            Binder.restoreCallingIdentity(origId);
9218        }
9219    }
9220
9221    @Override
9222    public void setImmersive(IBinder token, boolean immersive) {
9223        synchronized(this) {
9224            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9225            if (r == null) {
9226                throw new IllegalArgumentException();
9227            }
9228            r.immersive = immersive;
9229
9230            // update associated state if we're frontmost
9231            if (r == mFocusedActivity) {
9232                if (DEBUG_IMMERSIVE) {
9233                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9234                }
9235                applyUpdateLockStateLocked(r);
9236            }
9237        }
9238    }
9239
9240    @Override
9241    public boolean isImmersive(IBinder token) {
9242        synchronized (this) {
9243            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9244            if (r == null) {
9245                throw new IllegalArgumentException();
9246            }
9247            return r.immersive;
9248        }
9249    }
9250
9251    public boolean isTopActivityImmersive() {
9252        enforceNotIsolatedCaller("startActivity");
9253        synchronized (this) {
9254            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9255            return (r != null) ? r.immersive : false;
9256        }
9257    }
9258
9259    public final void enterSafeMode() {
9260        synchronized(this) {
9261            // It only makes sense to do this before the system is ready
9262            // and started launching other packages.
9263            if (!mSystemReady) {
9264                try {
9265                    AppGlobals.getPackageManager().enterSafeMode();
9266                } catch (RemoteException e) {
9267                }
9268            }
9269
9270            mSafeMode = true;
9271        }
9272    }
9273
9274    public final void showSafeModeOverlay() {
9275        View v = LayoutInflater.from(mContext).inflate(
9276                com.android.internal.R.layout.safe_mode, null);
9277        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9278        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9279        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9280        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9281        lp.gravity = Gravity.BOTTOM | Gravity.START;
9282        lp.format = v.getBackground().getOpacity();
9283        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9284                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9285        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9286        ((WindowManager)mContext.getSystemService(
9287                Context.WINDOW_SERVICE)).addView(v, lp);
9288    }
9289
9290    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9291        if (!(sender instanceof PendingIntentRecord)) {
9292            return;
9293        }
9294        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9295        synchronized (stats) {
9296            if (mBatteryStatsService.isOnBattery()) {
9297                mBatteryStatsService.enforceCallingPermission();
9298                PendingIntentRecord rec = (PendingIntentRecord)sender;
9299                int MY_UID = Binder.getCallingUid();
9300                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9301                BatteryStatsImpl.Uid.Pkg pkg =
9302                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9303                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9304                pkg.incWakeupsLocked();
9305            }
9306        }
9307    }
9308
9309    public boolean killPids(int[] pids, String pReason, boolean secure) {
9310        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9311            throw new SecurityException("killPids only available to the system");
9312        }
9313        String reason = (pReason == null) ? "Unknown" : pReason;
9314        // XXX Note: don't acquire main activity lock here, because the window
9315        // manager calls in with its locks held.
9316
9317        boolean killed = false;
9318        synchronized (mPidsSelfLocked) {
9319            int[] types = new int[pids.length];
9320            int worstType = 0;
9321            for (int i=0; i<pids.length; i++) {
9322                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9323                if (proc != null) {
9324                    int type = proc.setAdj;
9325                    types[i] = type;
9326                    if (type > worstType) {
9327                        worstType = type;
9328                    }
9329                }
9330            }
9331
9332            // If the worst oom_adj is somewhere in the cached proc LRU range,
9333            // then constrain it so we will kill all cached procs.
9334            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9335                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9336                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9337            }
9338
9339            // If this is not a secure call, don't let it kill processes that
9340            // are important.
9341            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9342                worstType = ProcessList.SERVICE_ADJ;
9343            }
9344
9345            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9346            for (int i=0; i<pids.length; i++) {
9347                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9348                if (proc == null) {
9349                    continue;
9350                }
9351                int adj = proc.setAdj;
9352                if (adj >= worstType && !proc.killedByAm) {
9353                    killUnneededProcessLocked(proc, reason);
9354                    killed = true;
9355                }
9356            }
9357        }
9358        return killed;
9359    }
9360
9361    @Override
9362    public void killUid(int uid, String reason) {
9363        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9364            throw new SecurityException("killUid only available to the system");
9365        }
9366        synchronized (this) {
9367            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9368                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9369                    reason != null ? reason : "kill uid");
9370        }
9371    }
9372
9373    @Override
9374    public boolean killProcessesBelowForeground(String reason) {
9375        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9376            throw new SecurityException("killProcessesBelowForeground() only available to system");
9377        }
9378
9379        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9380    }
9381
9382    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9383        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9384            throw new SecurityException("killProcessesBelowAdj() only available to system");
9385        }
9386
9387        boolean killed = false;
9388        synchronized (mPidsSelfLocked) {
9389            final int size = mPidsSelfLocked.size();
9390            for (int i = 0; i < size; i++) {
9391                final int pid = mPidsSelfLocked.keyAt(i);
9392                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9393                if (proc == null) continue;
9394
9395                final int adj = proc.setAdj;
9396                if (adj > belowAdj && !proc.killedByAm) {
9397                    killUnneededProcessLocked(proc, reason);
9398                    killed = true;
9399                }
9400            }
9401        }
9402        return killed;
9403    }
9404
9405    @Override
9406    public void hang(final IBinder who, boolean allowRestart) {
9407        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9408                != PackageManager.PERMISSION_GRANTED) {
9409            throw new SecurityException("Requires permission "
9410                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9411        }
9412
9413        final IBinder.DeathRecipient death = new DeathRecipient() {
9414            @Override
9415            public void binderDied() {
9416                synchronized (this) {
9417                    notifyAll();
9418                }
9419            }
9420        };
9421
9422        try {
9423            who.linkToDeath(death, 0);
9424        } catch (RemoteException e) {
9425            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9426            return;
9427        }
9428
9429        synchronized (this) {
9430            Watchdog.getInstance().setAllowRestart(allowRestart);
9431            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9432            synchronized (death) {
9433                while (who.isBinderAlive()) {
9434                    try {
9435                        death.wait();
9436                    } catch (InterruptedException e) {
9437                    }
9438                }
9439            }
9440            Watchdog.getInstance().setAllowRestart(true);
9441        }
9442    }
9443
9444    @Override
9445    public void restart() {
9446        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9447                != PackageManager.PERMISSION_GRANTED) {
9448            throw new SecurityException("Requires permission "
9449                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9450        }
9451
9452        Log.i(TAG, "Sending shutdown broadcast...");
9453
9454        BroadcastReceiver br = new BroadcastReceiver() {
9455            @Override public void onReceive(Context context, Intent intent) {
9456                // Now the broadcast is done, finish up the low-level shutdown.
9457                Log.i(TAG, "Shutting down activity manager...");
9458                shutdown(10000);
9459                Log.i(TAG, "Shutdown complete, restarting!");
9460                Process.killProcess(Process.myPid());
9461                System.exit(10);
9462            }
9463        };
9464
9465        // First send the high-level shut down broadcast.
9466        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9467        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9468        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9469        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9470        mContext.sendOrderedBroadcastAsUser(intent,
9471                UserHandle.ALL, null, br, mHandler, 0, null, null);
9472        */
9473        br.onReceive(mContext, intent);
9474    }
9475
9476    private long getLowRamTimeSinceIdle(long now) {
9477        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9478    }
9479
9480    @Override
9481    public void performIdleMaintenance() {
9482        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9483                != PackageManager.PERMISSION_GRANTED) {
9484            throw new SecurityException("Requires permission "
9485                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9486        }
9487
9488        synchronized (this) {
9489            final long now = SystemClock.uptimeMillis();
9490            final long timeSinceLastIdle = now - mLastIdleTime;
9491            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9492            mLastIdleTime = now;
9493            mLowRamTimeSinceLastIdle = 0;
9494            if (mLowRamStartTime != 0) {
9495                mLowRamStartTime = now;
9496            }
9497
9498            StringBuilder sb = new StringBuilder(128);
9499            sb.append("Idle maintenance over ");
9500            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9501            sb.append(" low RAM for ");
9502            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9503            Slog.i(TAG, sb.toString());
9504
9505            // If at least 1/3 of our time since the last idle period has been spent
9506            // with RAM low, then we want to kill processes.
9507            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9508
9509            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9510                ProcessRecord proc = mLruProcesses.get(i);
9511                if (proc.notCachedSinceIdle) {
9512                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9513                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9514                        if (doKilling && proc.initialIdlePss != 0
9515                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9516                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9517                                    + " from " + proc.initialIdlePss + ")");
9518                        }
9519                    }
9520                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9521                    proc.notCachedSinceIdle = true;
9522                    proc.initialIdlePss = 0;
9523                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9524                            isSleeping(), now);
9525                }
9526            }
9527
9528            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9529            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9530        }
9531    }
9532
9533    private void retrieveSettings() {
9534        final ContentResolver resolver = mContext.getContentResolver();
9535        String debugApp = Settings.Global.getString(
9536            resolver, Settings.Global.DEBUG_APP);
9537        boolean waitForDebugger = Settings.Global.getInt(
9538            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9539        boolean alwaysFinishActivities = Settings.Global.getInt(
9540            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9541        boolean forceRtl = Settings.Global.getInt(
9542                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9543        // Transfer any global setting for forcing RTL layout, into a System Property
9544        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9545
9546        Configuration configuration = new Configuration();
9547        Settings.System.getConfiguration(resolver, configuration);
9548        if (forceRtl) {
9549            // This will take care of setting the correct layout direction flags
9550            configuration.setLayoutDirection(configuration.locale);
9551        }
9552
9553        synchronized (this) {
9554            mDebugApp = mOrigDebugApp = debugApp;
9555            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9556            mAlwaysFinishActivities = alwaysFinishActivities;
9557            // This happens before any activities are started, so we can
9558            // change mConfiguration in-place.
9559            updateConfigurationLocked(configuration, null, false, true);
9560            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9561        }
9562    }
9563
9564    public boolean testIsSystemReady() {
9565        // no need to synchronize(this) just to read & return the value
9566        return mSystemReady;
9567    }
9568
9569    private static File getCalledPreBootReceiversFile() {
9570        File dataDir = Environment.getDataDirectory();
9571        File systemDir = new File(dataDir, "system");
9572        File fname = new File(systemDir, "called_pre_boots.dat");
9573        return fname;
9574    }
9575
9576    static final int LAST_DONE_VERSION = 10000;
9577
9578    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9579        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9580        File file = getCalledPreBootReceiversFile();
9581        FileInputStream fis = null;
9582        try {
9583            fis = new FileInputStream(file);
9584            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9585            int fvers = dis.readInt();
9586            if (fvers == LAST_DONE_VERSION) {
9587                String vers = dis.readUTF();
9588                String codename = dis.readUTF();
9589                String build = dis.readUTF();
9590                if (android.os.Build.VERSION.RELEASE.equals(vers)
9591                        && android.os.Build.VERSION.CODENAME.equals(codename)
9592                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9593                    int num = dis.readInt();
9594                    while (num > 0) {
9595                        num--;
9596                        String pkg = dis.readUTF();
9597                        String cls = dis.readUTF();
9598                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9599                    }
9600                }
9601            }
9602        } catch (FileNotFoundException e) {
9603        } catch (IOException e) {
9604            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9605        } finally {
9606            if (fis != null) {
9607                try {
9608                    fis.close();
9609                } catch (IOException e) {
9610                }
9611            }
9612        }
9613        return lastDoneReceivers;
9614    }
9615
9616    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9617        File file = getCalledPreBootReceiversFile();
9618        FileOutputStream fos = null;
9619        DataOutputStream dos = null;
9620        try {
9621            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9622            fos = new FileOutputStream(file);
9623            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9624            dos.writeInt(LAST_DONE_VERSION);
9625            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9626            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9627            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9628            dos.writeInt(list.size());
9629            for (int i=0; i<list.size(); i++) {
9630                dos.writeUTF(list.get(i).getPackageName());
9631                dos.writeUTF(list.get(i).getClassName());
9632            }
9633        } catch (IOException e) {
9634            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9635            file.delete();
9636        } finally {
9637            FileUtils.sync(fos);
9638            if (dos != null) {
9639                try {
9640                    dos.close();
9641                } catch (IOException e) {
9642                    // TODO Auto-generated catch block
9643                    e.printStackTrace();
9644                }
9645            }
9646        }
9647    }
9648
9649    public void systemReady(final Runnable goingCallback) {
9650        synchronized(this) {
9651            if (mSystemReady) {
9652                if (goingCallback != null) goingCallback.run();
9653                return;
9654            }
9655
9656            if (mRecentTasks == null) {
9657                mRecentTasks = mTaskPersister.restoreTasksLocked();
9658                if (!mRecentTasks.isEmpty()) {
9659                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9660                }
9661                mTaskPersister.startPersisting();
9662            }
9663
9664            // Check to see if there are any update receivers to run.
9665            if (!mDidUpdate) {
9666                if (mWaitingUpdate) {
9667                    return;
9668                }
9669                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9670                List<ResolveInfo> ris = null;
9671                try {
9672                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9673                            intent, null, 0, 0);
9674                } catch (RemoteException e) {
9675                }
9676                if (ris != null) {
9677                    for (int i=ris.size()-1; i>=0; i--) {
9678                        if ((ris.get(i).activityInfo.applicationInfo.flags
9679                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9680                            ris.remove(i);
9681                        }
9682                    }
9683                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9684
9685                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9686
9687                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9688                    for (int i=0; i<ris.size(); i++) {
9689                        ActivityInfo ai = ris.get(i).activityInfo;
9690                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9691                        if (lastDoneReceivers.contains(comp)) {
9692                            // We already did the pre boot receiver for this app with the current
9693                            // platform version, so don't do it again...
9694                            ris.remove(i);
9695                            i--;
9696                            // ...however, do keep it as one that has been done, so we don't
9697                            // forget about it when rewriting the file of last done receivers.
9698                            doneReceivers.add(comp);
9699                        }
9700                    }
9701
9702                    final int[] users = getUsersLocked();
9703                    for (int i=0; i<ris.size(); i++) {
9704                        ActivityInfo ai = ris.get(i).activityInfo;
9705                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9706                        doneReceivers.add(comp);
9707                        intent.setComponent(comp);
9708                        for (int j=0; j<users.length; j++) {
9709                            IIntentReceiver finisher = null;
9710                            if (i == ris.size()-1 && j == users.length-1) {
9711                                finisher = new IIntentReceiver.Stub() {
9712                                    public void performReceive(Intent intent, int resultCode,
9713                                            String data, Bundle extras, boolean ordered,
9714                                            boolean sticky, int sendingUser) {
9715                                        // The raw IIntentReceiver interface is called
9716                                        // with the AM lock held, so redispatch to
9717                                        // execute our code without the lock.
9718                                        mHandler.post(new Runnable() {
9719                                            public void run() {
9720                                                synchronized (ActivityManagerService.this) {
9721                                                    mDidUpdate = true;
9722                                                }
9723                                                writeLastDonePreBootReceivers(doneReceivers);
9724                                                showBootMessage(mContext.getText(
9725                                                        R.string.android_upgrading_complete),
9726                                                        false);
9727                                                systemReady(goingCallback);
9728                                            }
9729                                        });
9730                                    }
9731                                };
9732                            }
9733                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9734                                    + " for user " + users[j]);
9735                            broadcastIntentLocked(null, null, intent, null, finisher,
9736                                    0, null, null, null, AppOpsManager.OP_NONE,
9737                                    true, false, MY_PID, Process.SYSTEM_UID,
9738                                    users[j]);
9739                            if (finisher != null) {
9740                                mWaitingUpdate = true;
9741                            }
9742                        }
9743                    }
9744                }
9745                if (mWaitingUpdate) {
9746                    return;
9747                }
9748                mDidUpdate = true;
9749            }
9750
9751            mAppOpsService.systemReady();
9752            mUsageStatsService.systemReady();
9753            mSystemReady = true;
9754        }
9755
9756        ArrayList<ProcessRecord> procsToKill = null;
9757        synchronized(mPidsSelfLocked) {
9758            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9759                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9760                if (!isAllowedWhileBooting(proc.info)){
9761                    if (procsToKill == null) {
9762                        procsToKill = new ArrayList<ProcessRecord>();
9763                    }
9764                    procsToKill.add(proc);
9765                }
9766            }
9767        }
9768
9769        synchronized(this) {
9770            if (procsToKill != null) {
9771                for (int i=procsToKill.size()-1; i>=0; i--) {
9772                    ProcessRecord proc = procsToKill.get(i);
9773                    Slog.i(TAG, "Removing system update proc: " + proc);
9774                    removeProcessLocked(proc, true, false, "system update done");
9775                }
9776            }
9777
9778            // Now that we have cleaned up any update processes, we
9779            // are ready to start launching real processes and know that
9780            // we won't trample on them any more.
9781            mProcessesReady = true;
9782        }
9783
9784        Slog.i(TAG, "System now ready");
9785        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9786            SystemClock.uptimeMillis());
9787
9788        synchronized(this) {
9789            // Make sure we have no pre-ready processes sitting around.
9790
9791            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9792                ResolveInfo ri = mContext.getPackageManager()
9793                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9794                                STOCK_PM_FLAGS);
9795                CharSequence errorMsg = null;
9796                if (ri != null) {
9797                    ActivityInfo ai = ri.activityInfo;
9798                    ApplicationInfo app = ai.applicationInfo;
9799                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9800                        mTopAction = Intent.ACTION_FACTORY_TEST;
9801                        mTopData = null;
9802                        mTopComponent = new ComponentName(app.packageName,
9803                                ai.name);
9804                    } else {
9805                        errorMsg = mContext.getResources().getText(
9806                                com.android.internal.R.string.factorytest_not_system);
9807                    }
9808                } else {
9809                    errorMsg = mContext.getResources().getText(
9810                            com.android.internal.R.string.factorytest_no_action);
9811                }
9812                if (errorMsg != null) {
9813                    mTopAction = null;
9814                    mTopData = null;
9815                    mTopComponent = null;
9816                    Message msg = Message.obtain();
9817                    msg.what = SHOW_FACTORY_ERROR_MSG;
9818                    msg.getData().putCharSequence("msg", errorMsg);
9819                    mHandler.sendMessage(msg);
9820                }
9821            }
9822        }
9823
9824        retrieveSettings();
9825
9826        synchronized (this) {
9827            readGrantedUriPermissionsLocked();
9828        }
9829
9830        if (goingCallback != null) goingCallback.run();
9831
9832        mSystemServiceManager.startUser(mCurrentUserId);
9833
9834        synchronized (this) {
9835            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9836                try {
9837                    List apps = AppGlobals.getPackageManager().
9838                        getPersistentApplications(STOCK_PM_FLAGS);
9839                    if (apps != null) {
9840                        int N = apps.size();
9841                        int i;
9842                        for (i=0; i<N; i++) {
9843                            ApplicationInfo info
9844                                = (ApplicationInfo)apps.get(i);
9845                            if (info != null &&
9846                                    !info.packageName.equals("android")) {
9847                                addAppLocked(info, false, null /* ABI override */);
9848                            }
9849                        }
9850                    }
9851                } catch (RemoteException ex) {
9852                    // pm is in same process, this will never happen.
9853                }
9854            }
9855
9856            // Start up initial activity.
9857            mBooting = true;
9858
9859            try {
9860                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9861                    Message msg = Message.obtain();
9862                    msg.what = SHOW_UID_ERROR_MSG;
9863                    mHandler.sendMessage(msg);
9864                }
9865            } catch (RemoteException e) {
9866            }
9867
9868            long ident = Binder.clearCallingIdentity();
9869            try {
9870                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9871                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9872                        | Intent.FLAG_RECEIVER_FOREGROUND);
9873                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9874                broadcastIntentLocked(null, null, intent,
9875                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9876                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9877                intent = new Intent(Intent.ACTION_USER_STARTING);
9878                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9879                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9880                broadcastIntentLocked(null, null, intent,
9881                        null, new IIntentReceiver.Stub() {
9882                            @Override
9883                            public void performReceive(Intent intent, int resultCode, String data,
9884                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9885                                    throws RemoteException {
9886                            }
9887                        }, 0, null, null,
9888                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9889                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9890            } catch (Throwable t) {
9891                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9892            } finally {
9893                Binder.restoreCallingIdentity(ident);
9894            }
9895            mStackSupervisor.resumeTopActivitiesLocked();
9896            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9897        }
9898    }
9899
9900    private boolean makeAppCrashingLocked(ProcessRecord app,
9901            String shortMsg, String longMsg, String stackTrace) {
9902        app.crashing = true;
9903        app.crashingReport = generateProcessError(app,
9904                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9905        startAppProblemLocked(app);
9906        app.stopFreezingAllLocked();
9907        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9908    }
9909
9910    private void makeAppNotRespondingLocked(ProcessRecord app,
9911            String activity, String shortMsg, String longMsg) {
9912        app.notResponding = true;
9913        app.notRespondingReport = generateProcessError(app,
9914                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9915                activity, shortMsg, longMsg, null);
9916        startAppProblemLocked(app);
9917        app.stopFreezingAllLocked();
9918    }
9919
9920    /**
9921     * Generate a process error record, suitable for attachment to a ProcessRecord.
9922     *
9923     * @param app The ProcessRecord in which the error occurred.
9924     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9925     *                      ActivityManager.AppErrorStateInfo
9926     * @param activity The activity associated with the crash, if known.
9927     * @param shortMsg Short message describing the crash.
9928     * @param longMsg Long message describing the crash.
9929     * @param stackTrace Full crash stack trace, may be null.
9930     *
9931     * @return Returns a fully-formed AppErrorStateInfo record.
9932     */
9933    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9934            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9935        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9936
9937        report.condition = condition;
9938        report.processName = app.processName;
9939        report.pid = app.pid;
9940        report.uid = app.info.uid;
9941        report.tag = activity;
9942        report.shortMsg = shortMsg;
9943        report.longMsg = longMsg;
9944        report.stackTrace = stackTrace;
9945
9946        return report;
9947    }
9948
9949    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9950        synchronized (this) {
9951            app.crashing = false;
9952            app.crashingReport = null;
9953            app.notResponding = false;
9954            app.notRespondingReport = null;
9955            if (app.anrDialog == fromDialog) {
9956                app.anrDialog = null;
9957            }
9958            if (app.waitDialog == fromDialog) {
9959                app.waitDialog = null;
9960            }
9961            if (app.pid > 0 && app.pid != MY_PID) {
9962                handleAppCrashLocked(app, null, null, null);
9963                killUnneededProcessLocked(app, "user request after error");
9964            }
9965        }
9966    }
9967
9968    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9969            String stackTrace) {
9970        long now = SystemClock.uptimeMillis();
9971
9972        Long crashTime;
9973        if (!app.isolated) {
9974            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9975        } else {
9976            crashTime = null;
9977        }
9978        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9979            // This process loses!
9980            Slog.w(TAG, "Process " + app.info.processName
9981                    + " has crashed too many times: killing!");
9982            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9983                    app.userId, app.info.processName, app.uid);
9984            mStackSupervisor.handleAppCrashLocked(app);
9985            if (!app.persistent) {
9986                // We don't want to start this process again until the user
9987                // explicitly does so...  but for persistent process, we really
9988                // need to keep it running.  If a persistent process is actually
9989                // repeatedly crashing, then badness for everyone.
9990                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9991                        app.info.processName);
9992                if (!app.isolated) {
9993                    // XXX We don't have a way to mark isolated processes
9994                    // as bad, since they don't have a peristent identity.
9995                    mBadProcesses.put(app.info.processName, app.uid,
9996                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9997                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9998                }
9999                app.bad = true;
10000                app.removed = true;
10001                // Don't let services in this process be restarted and potentially
10002                // annoy the user repeatedly.  Unless it is persistent, since those
10003                // processes run critical code.
10004                removeProcessLocked(app, false, false, "crash");
10005                mStackSupervisor.resumeTopActivitiesLocked();
10006                return false;
10007            }
10008            mStackSupervisor.resumeTopActivitiesLocked();
10009        } else {
10010            mStackSupervisor.finishTopRunningActivityLocked(app);
10011        }
10012
10013        // Bump up the crash count of any services currently running in the proc.
10014        for (int i=app.services.size()-1; i>=0; i--) {
10015            // Any services running in the application need to be placed
10016            // back in the pending list.
10017            ServiceRecord sr = app.services.valueAt(i);
10018            sr.crashCount++;
10019        }
10020
10021        // If the crashing process is what we consider to be the "home process" and it has been
10022        // replaced by a third-party app, clear the package preferred activities from packages
10023        // with a home activity running in the process to prevent a repeatedly crashing app
10024        // from blocking the user to manually clear the list.
10025        final ArrayList<ActivityRecord> activities = app.activities;
10026        if (app == mHomeProcess && activities.size() > 0
10027                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10028            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10029                final ActivityRecord r = activities.get(activityNdx);
10030                if (r.isHomeActivity()) {
10031                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10032                    try {
10033                        ActivityThread.getPackageManager()
10034                                .clearPackagePreferredActivities(r.packageName);
10035                    } catch (RemoteException c) {
10036                        // pm is in same process, this will never happen.
10037                    }
10038                }
10039            }
10040        }
10041
10042        if (!app.isolated) {
10043            // XXX Can't keep track of crash times for isolated processes,
10044            // because they don't have a perisistent identity.
10045            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10046        }
10047
10048        return true;
10049    }
10050
10051    void startAppProblemLocked(ProcessRecord app) {
10052        if (app.userId == mCurrentUserId) {
10053            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10054                    mContext, app.info.packageName, app.info.flags);
10055        } else {
10056            // If this app is not running under the current user, then we
10057            // can't give it a report button because that would require
10058            // launching the report UI under a different user.
10059            app.errorReportReceiver = null;
10060        }
10061        skipCurrentReceiverLocked(app);
10062    }
10063
10064    void skipCurrentReceiverLocked(ProcessRecord app) {
10065        for (BroadcastQueue queue : mBroadcastQueues) {
10066            queue.skipCurrentReceiverLocked(app);
10067        }
10068    }
10069
10070    /**
10071     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10072     * The application process will exit immediately after this call returns.
10073     * @param app object of the crashing app, null for the system server
10074     * @param crashInfo describing the exception
10075     */
10076    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10077        ProcessRecord r = findAppProcess(app, "Crash");
10078        final String processName = app == null ? "system_server"
10079                : (r == null ? "unknown" : r.processName);
10080
10081        handleApplicationCrashInner("crash", r, processName, crashInfo);
10082    }
10083
10084    /* Native crash reporting uses this inner version because it needs to be somewhat
10085     * decoupled from the AM-managed cleanup lifecycle
10086     */
10087    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10088            ApplicationErrorReport.CrashInfo crashInfo) {
10089        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10090                UserHandle.getUserId(Binder.getCallingUid()), processName,
10091                r == null ? -1 : r.info.flags,
10092                crashInfo.exceptionClassName,
10093                crashInfo.exceptionMessage,
10094                crashInfo.throwFileName,
10095                crashInfo.throwLineNumber);
10096
10097        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10098
10099        crashApplication(r, crashInfo);
10100    }
10101
10102    public void handleApplicationStrictModeViolation(
10103            IBinder app,
10104            int violationMask,
10105            StrictMode.ViolationInfo info) {
10106        ProcessRecord r = findAppProcess(app, "StrictMode");
10107        if (r == null) {
10108            return;
10109        }
10110
10111        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10112            Integer stackFingerprint = info.hashCode();
10113            boolean logIt = true;
10114            synchronized (mAlreadyLoggedViolatedStacks) {
10115                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10116                    logIt = false;
10117                    // TODO: sub-sample into EventLog for these, with
10118                    // the info.durationMillis?  Then we'd get
10119                    // the relative pain numbers, without logging all
10120                    // the stack traces repeatedly.  We'd want to do
10121                    // likewise in the client code, which also does
10122                    // dup suppression, before the Binder call.
10123                } else {
10124                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10125                        mAlreadyLoggedViolatedStacks.clear();
10126                    }
10127                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10128                }
10129            }
10130            if (logIt) {
10131                logStrictModeViolationToDropBox(r, info);
10132            }
10133        }
10134
10135        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10136            AppErrorResult result = new AppErrorResult();
10137            synchronized (this) {
10138                final long origId = Binder.clearCallingIdentity();
10139
10140                Message msg = Message.obtain();
10141                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10142                HashMap<String, Object> data = new HashMap<String, Object>();
10143                data.put("result", result);
10144                data.put("app", r);
10145                data.put("violationMask", violationMask);
10146                data.put("info", info);
10147                msg.obj = data;
10148                mHandler.sendMessage(msg);
10149
10150                Binder.restoreCallingIdentity(origId);
10151            }
10152            int res = result.get();
10153            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10154        }
10155    }
10156
10157    // Depending on the policy in effect, there could be a bunch of
10158    // these in quick succession so we try to batch these together to
10159    // minimize disk writes, number of dropbox entries, and maximize
10160    // compression, by having more fewer, larger records.
10161    private void logStrictModeViolationToDropBox(
10162            ProcessRecord process,
10163            StrictMode.ViolationInfo info) {
10164        if (info == null) {
10165            return;
10166        }
10167        final boolean isSystemApp = process == null ||
10168                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10169                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10170        final String processName = process == null ? "unknown" : process.processName;
10171        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10172        final DropBoxManager dbox = (DropBoxManager)
10173                mContext.getSystemService(Context.DROPBOX_SERVICE);
10174
10175        // Exit early if the dropbox isn't configured to accept this report type.
10176        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10177
10178        boolean bufferWasEmpty;
10179        boolean needsFlush;
10180        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10181        synchronized (sb) {
10182            bufferWasEmpty = sb.length() == 0;
10183            appendDropBoxProcessHeaders(process, processName, sb);
10184            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10185            sb.append("System-App: ").append(isSystemApp).append("\n");
10186            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10187            if (info.violationNumThisLoop != 0) {
10188                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10189            }
10190            if (info.numAnimationsRunning != 0) {
10191                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10192            }
10193            if (info.broadcastIntentAction != null) {
10194                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10195            }
10196            if (info.durationMillis != -1) {
10197                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10198            }
10199            if (info.numInstances != -1) {
10200                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10201            }
10202            if (info.tags != null) {
10203                for (String tag : info.tags) {
10204                    sb.append("Span-Tag: ").append(tag).append("\n");
10205                }
10206            }
10207            sb.append("\n");
10208            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10209                sb.append(info.crashInfo.stackTrace);
10210            }
10211            sb.append("\n");
10212
10213            // Only buffer up to ~64k.  Various logging bits truncate
10214            // things at 128k.
10215            needsFlush = (sb.length() > 64 * 1024);
10216        }
10217
10218        // Flush immediately if the buffer's grown too large, or this
10219        // is a non-system app.  Non-system apps are isolated with a
10220        // different tag & policy and not batched.
10221        //
10222        // Batching is useful during internal testing with
10223        // StrictMode settings turned up high.  Without batching,
10224        // thousands of separate files could be created on boot.
10225        if (!isSystemApp || needsFlush) {
10226            new Thread("Error dump: " + dropboxTag) {
10227                @Override
10228                public void run() {
10229                    String report;
10230                    synchronized (sb) {
10231                        report = sb.toString();
10232                        sb.delete(0, sb.length());
10233                        sb.trimToSize();
10234                    }
10235                    if (report.length() != 0) {
10236                        dbox.addText(dropboxTag, report);
10237                    }
10238                }
10239            }.start();
10240            return;
10241        }
10242
10243        // System app batching:
10244        if (!bufferWasEmpty) {
10245            // An existing dropbox-writing thread is outstanding, so
10246            // we don't need to start it up.  The existing thread will
10247            // catch the buffer appends we just did.
10248            return;
10249        }
10250
10251        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10252        // (After this point, we shouldn't access AMS internal data structures.)
10253        new Thread("Error dump: " + dropboxTag) {
10254            @Override
10255            public void run() {
10256                // 5 second sleep to let stacks arrive and be batched together
10257                try {
10258                    Thread.sleep(5000);  // 5 seconds
10259                } catch (InterruptedException e) {}
10260
10261                String errorReport;
10262                synchronized (mStrictModeBuffer) {
10263                    errorReport = mStrictModeBuffer.toString();
10264                    if (errorReport.length() == 0) {
10265                        return;
10266                    }
10267                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10268                    mStrictModeBuffer.trimToSize();
10269                }
10270                dbox.addText(dropboxTag, errorReport);
10271            }
10272        }.start();
10273    }
10274
10275    /**
10276     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10277     * @param app object of the crashing app, null for the system server
10278     * @param tag reported by the caller
10279     * @param crashInfo describing the context of the error
10280     * @return true if the process should exit immediately (WTF is fatal)
10281     */
10282    public boolean handleApplicationWtf(IBinder app, String tag,
10283            ApplicationErrorReport.CrashInfo crashInfo) {
10284        ProcessRecord r = findAppProcess(app, "WTF");
10285        final String processName = app == null ? "system_server"
10286                : (r == null ? "unknown" : r.processName);
10287
10288        EventLog.writeEvent(EventLogTags.AM_WTF,
10289                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10290                processName,
10291                r == null ? -1 : r.info.flags,
10292                tag, crashInfo.exceptionMessage);
10293
10294        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10295
10296        if (r != null && r.pid != Process.myPid() &&
10297                Settings.Global.getInt(mContext.getContentResolver(),
10298                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10299            crashApplication(r, crashInfo);
10300            return true;
10301        } else {
10302            return false;
10303        }
10304    }
10305
10306    /**
10307     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10308     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10309     */
10310    private ProcessRecord findAppProcess(IBinder app, String reason) {
10311        if (app == null) {
10312            return null;
10313        }
10314
10315        synchronized (this) {
10316            final int NP = mProcessNames.getMap().size();
10317            for (int ip=0; ip<NP; ip++) {
10318                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10319                final int NA = apps.size();
10320                for (int ia=0; ia<NA; ia++) {
10321                    ProcessRecord p = apps.valueAt(ia);
10322                    if (p.thread != null && p.thread.asBinder() == app) {
10323                        return p;
10324                    }
10325                }
10326            }
10327
10328            Slog.w(TAG, "Can't find mystery application for " + reason
10329                    + " from pid=" + Binder.getCallingPid()
10330                    + " uid=" + Binder.getCallingUid() + ": " + app);
10331            return null;
10332        }
10333    }
10334
10335    /**
10336     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10337     * to append various headers to the dropbox log text.
10338     */
10339    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10340            StringBuilder sb) {
10341        // Watchdog thread ends up invoking this function (with
10342        // a null ProcessRecord) to add the stack file to dropbox.
10343        // Do not acquire a lock on this (am) in such cases, as it
10344        // could cause a potential deadlock, if and when watchdog
10345        // is invoked due to unavailability of lock on am and it
10346        // would prevent watchdog from killing system_server.
10347        if (process == null) {
10348            sb.append("Process: ").append(processName).append("\n");
10349            return;
10350        }
10351        // Note: ProcessRecord 'process' is guarded by the service
10352        // instance.  (notably process.pkgList, which could otherwise change
10353        // concurrently during execution of this method)
10354        synchronized (this) {
10355            sb.append("Process: ").append(processName).append("\n");
10356            int flags = process.info.flags;
10357            IPackageManager pm = AppGlobals.getPackageManager();
10358            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10359            for (int ip=0; ip<process.pkgList.size(); ip++) {
10360                String pkg = process.pkgList.keyAt(ip);
10361                sb.append("Package: ").append(pkg);
10362                try {
10363                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10364                    if (pi != null) {
10365                        sb.append(" v").append(pi.versionCode);
10366                        if (pi.versionName != null) {
10367                            sb.append(" (").append(pi.versionName).append(")");
10368                        }
10369                    }
10370                } catch (RemoteException e) {
10371                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10372                }
10373                sb.append("\n");
10374            }
10375        }
10376    }
10377
10378    private static String processClass(ProcessRecord process) {
10379        if (process == null || process.pid == MY_PID) {
10380            return "system_server";
10381        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10382            return "system_app";
10383        } else {
10384            return "data_app";
10385        }
10386    }
10387
10388    /**
10389     * Write a description of an error (crash, WTF, ANR) to the drop box.
10390     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10391     * @param process which caused the error, null means the system server
10392     * @param activity which triggered the error, null if unknown
10393     * @param parent activity related to the error, null if unknown
10394     * @param subject line related to the error, null if absent
10395     * @param report in long form describing the error, null if absent
10396     * @param logFile to include in the report, null if none
10397     * @param crashInfo giving an application stack trace, null if absent
10398     */
10399    public void addErrorToDropBox(String eventType,
10400            ProcessRecord process, String processName, ActivityRecord activity,
10401            ActivityRecord parent, String subject,
10402            final String report, final File logFile,
10403            final ApplicationErrorReport.CrashInfo crashInfo) {
10404        // NOTE -- this must never acquire the ActivityManagerService lock,
10405        // otherwise the watchdog may be prevented from resetting the system.
10406
10407        final String dropboxTag = processClass(process) + "_" + eventType;
10408        final DropBoxManager dbox = (DropBoxManager)
10409                mContext.getSystemService(Context.DROPBOX_SERVICE);
10410
10411        // Exit early if the dropbox isn't configured to accept this report type.
10412        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10413
10414        final StringBuilder sb = new StringBuilder(1024);
10415        appendDropBoxProcessHeaders(process, processName, sb);
10416        if (activity != null) {
10417            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10418        }
10419        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10420            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10421        }
10422        if (parent != null && parent != activity) {
10423            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10424        }
10425        if (subject != null) {
10426            sb.append("Subject: ").append(subject).append("\n");
10427        }
10428        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10429        if (Debug.isDebuggerConnected()) {
10430            sb.append("Debugger: Connected\n");
10431        }
10432        sb.append("\n");
10433
10434        // Do the rest in a worker thread to avoid blocking the caller on I/O
10435        // (After this point, we shouldn't access AMS internal data structures.)
10436        Thread worker = new Thread("Error dump: " + dropboxTag) {
10437            @Override
10438            public void run() {
10439                if (report != null) {
10440                    sb.append(report);
10441                }
10442                if (logFile != null) {
10443                    try {
10444                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10445                                    "\n\n[[TRUNCATED]]"));
10446                    } catch (IOException e) {
10447                        Slog.e(TAG, "Error reading " + logFile, e);
10448                    }
10449                }
10450                if (crashInfo != null && crashInfo.stackTrace != null) {
10451                    sb.append(crashInfo.stackTrace);
10452                }
10453
10454                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10455                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10456                if (lines > 0) {
10457                    sb.append("\n");
10458
10459                    // Merge several logcat streams, and take the last N lines
10460                    InputStreamReader input = null;
10461                    try {
10462                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10463                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10464                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10465
10466                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10467                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10468                        input = new InputStreamReader(logcat.getInputStream());
10469
10470                        int num;
10471                        char[] buf = new char[8192];
10472                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10473                    } catch (IOException e) {
10474                        Slog.e(TAG, "Error running logcat", e);
10475                    } finally {
10476                        if (input != null) try { input.close(); } catch (IOException e) {}
10477                    }
10478                }
10479
10480                dbox.addText(dropboxTag, sb.toString());
10481            }
10482        };
10483
10484        if (process == null) {
10485            // If process is null, we are being called from some internal code
10486            // and may be about to die -- run this synchronously.
10487            worker.run();
10488        } else {
10489            worker.start();
10490        }
10491    }
10492
10493    /**
10494     * Bring up the "unexpected error" dialog box for a crashing app.
10495     * Deal with edge cases (intercepts from instrumented applications,
10496     * ActivityController, error intent receivers, that sort of thing).
10497     * @param r the application crashing
10498     * @param crashInfo describing the failure
10499     */
10500    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10501        long timeMillis = System.currentTimeMillis();
10502        String shortMsg = crashInfo.exceptionClassName;
10503        String longMsg = crashInfo.exceptionMessage;
10504        String stackTrace = crashInfo.stackTrace;
10505        if (shortMsg != null && longMsg != null) {
10506            longMsg = shortMsg + ": " + longMsg;
10507        } else if (shortMsg != null) {
10508            longMsg = shortMsg;
10509        }
10510
10511        AppErrorResult result = new AppErrorResult();
10512        synchronized (this) {
10513            if (mController != null) {
10514                try {
10515                    String name = r != null ? r.processName : null;
10516                    int pid = r != null ? r.pid : Binder.getCallingPid();
10517                    if (!mController.appCrashed(name, pid,
10518                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10519                        Slog.w(TAG, "Force-killing crashed app " + name
10520                                + " at watcher's request");
10521                        Process.killProcess(pid);
10522                        return;
10523                    }
10524                } catch (RemoteException e) {
10525                    mController = null;
10526                    Watchdog.getInstance().setActivityController(null);
10527                }
10528            }
10529
10530            final long origId = Binder.clearCallingIdentity();
10531
10532            // If this process is running instrumentation, finish it.
10533            if (r != null && r.instrumentationClass != null) {
10534                Slog.w(TAG, "Error in app " + r.processName
10535                      + " running instrumentation " + r.instrumentationClass + ":");
10536                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10537                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10538                Bundle info = new Bundle();
10539                info.putString("shortMsg", shortMsg);
10540                info.putString("longMsg", longMsg);
10541                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10542                Binder.restoreCallingIdentity(origId);
10543                return;
10544            }
10545
10546            // If we can't identify the process or it's already exceeded its crash quota,
10547            // quit right away without showing a crash dialog.
10548            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10549                Binder.restoreCallingIdentity(origId);
10550                return;
10551            }
10552
10553            Message msg = Message.obtain();
10554            msg.what = SHOW_ERROR_MSG;
10555            HashMap data = new HashMap();
10556            data.put("result", result);
10557            data.put("app", r);
10558            msg.obj = data;
10559            mHandler.sendMessage(msg);
10560
10561            Binder.restoreCallingIdentity(origId);
10562        }
10563
10564        int res = result.get();
10565
10566        Intent appErrorIntent = null;
10567        synchronized (this) {
10568            if (r != null && !r.isolated) {
10569                // XXX Can't keep track of crash time for isolated processes,
10570                // since they don't have a persistent identity.
10571                mProcessCrashTimes.put(r.info.processName, r.uid,
10572                        SystemClock.uptimeMillis());
10573            }
10574            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10575                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10576            }
10577        }
10578
10579        if (appErrorIntent != null) {
10580            try {
10581                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10582            } catch (ActivityNotFoundException e) {
10583                Slog.w(TAG, "bug report receiver dissappeared", e);
10584            }
10585        }
10586    }
10587
10588    Intent createAppErrorIntentLocked(ProcessRecord r,
10589            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10590        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10591        if (report == null) {
10592            return null;
10593        }
10594        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10595        result.setComponent(r.errorReportReceiver);
10596        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10597        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10598        return result;
10599    }
10600
10601    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10602            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10603        if (r.errorReportReceiver == null) {
10604            return null;
10605        }
10606
10607        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10608            return null;
10609        }
10610
10611        ApplicationErrorReport report = new ApplicationErrorReport();
10612        report.packageName = r.info.packageName;
10613        report.installerPackageName = r.errorReportReceiver.getPackageName();
10614        report.processName = r.processName;
10615        report.time = timeMillis;
10616        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10617
10618        if (r.crashing || r.forceCrashReport) {
10619            report.type = ApplicationErrorReport.TYPE_CRASH;
10620            report.crashInfo = crashInfo;
10621        } else if (r.notResponding) {
10622            report.type = ApplicationErrorReport.TYPE_ANR;
10623            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10624
10625            report.anrInfo.activity = r.notRespondingReport.tag;
10626            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10627            report.anrInfo.info = r.notRespondingReport.longMsg;
10628        }
10629
10630        return report;
10631    }
10632
10633    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10634        enforceNotIsolatedCaller("getProcessesInErrorState");
10635        // assume our apps are happy - lazy create the list
10636        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10637
10638        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10639                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10640        int userId = UserHandle.getUserId(Binder.getCallingUid());
10641
10642        synchronized (this) {
10643
10644            // iterate across all processes
10645            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10646                ProcessRecord app = mLruProcesses.get(i);
10647                if (!allUsers && app.userId != userId) {
10648                    continue;
10649                }
10650                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10651                    // This one's in trouble, so we'll generate a report for it
10652                    // crashes are higher priority (in case there's a crash *and* an anr)
10653                    ActivityManager.ProcessErrorStateInfo report = null;
10654                    if (app.crashing) {
10655                        report = app.crashingReport;
10656                    } else if (app.notResponding) {
10657                        report = app.notRespondingReport;
10658                    }
10659
10660                    if (report != null) {
10661                        if (errList == null) {
10662                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10663                        }
10664                        errList.add(report);
10665                    } else {
10666                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10667                                " crashing = " + app.crashing +
10668                                " notResponding = " + app.notResponding);
10669                    }
10670                }
10671            }
10672        }
10673
10674        return errList;
10675    }
10676
10677    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10678        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10679            if (currApp != null) {
10680                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10681            }
10682            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10683        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10684            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10685        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10686            if (currApp != null) {
10687                currApp.lru = 0;
10688            }
10689            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10690        } else if (adj >= ProcessList.SERVICE_ADJ) {
10691            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10692        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10693            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10694        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10695            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10696        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10697            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10698        } else {
10699            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10700        }
10701    }
10702
10703    private void fillInProcMemInfo(ProcessRecord app,
10704            ActivityManager.RunningAppProcessInfo outInfo) {
10705        outInfo.pid = app.pid;
10706        outInfo.uid = app.info.uid;
10707        if (mHeavyWeightProcess == app) {
10708            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10709        }
10710        if (app.persistent) {
10711            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10712        }
10713        if (app.activities.size() > 0) {
10714            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10715        }
10716        outInfo.lastTrimLevel = app.trimMemoryLevel;
10717        int adj = app.curAdj;
10718        outInfo.importance = oomAdjToImportance(adj, outInfo);
10719        outInfo.importanceReasonCode = app.adjTypeCode;
10720        outInfo.processState = app.curProcState;
10721    }
10722
10723    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10724        enforceNotIsolatedCaller("getRunningAppProcesses");
10725        // Lazy instantiation of list
10726        List<ActivityManager.RunningAppProcessInfo> runList = null;
10727        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10728                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10729        int userId = UserHandle.getUserId(Binder.getCallingUid());
10730        synchronized (this) {
10731            // Iterate across all processes
10732            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10733                ProcessRecord app = mLruProcesses.get(i);
10734                if (!allUsers && app.userId != userId) {
10735                    continue;
10736                }
10737                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10738                    // Generate process state info for running application
10739                    ActivityManager.RunningAppProcessInfo currApp =
10740                        new ActivityManager.RunningAppProcessInfo(app.processName,
10741                                app.pid, app.getPackageList());
10742                    fillInProcMemInfo(app, currApp);
10743                    if (app.adjSource instanceof ProcessRecord) {
10744                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10745                        currApp.importanceReasonImportance = oomAdjToImportance(
10746                                app.adjSourceOom, null);
10747                    } else if (app.adjSource instanceof ActivityRecord) {
10748                        ActivityRecord r = (ActivityRecord)app.adjSource;
10749                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10750                    }
10751                    if (app.adjTarget instanceof ComponentName) {
10752                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10753                    }
10754                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10755                    //        + " lru=" + currApp.lru);
10756                    if (runList == null) {
10757                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10758                    }
10759                    runList.add(currApp);
10760                }
10761            }
10762        }
10763        return runList;
10764    }
10765
10766    public List<ApplicationInfo> getRunningExternalApplications() {
10767        enforceNotIsolatedCaller("getRunningExternalApplications");
10768        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10769        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10770        if (runningApps != null && runningApps.size() > 0) {
10771            Set<String> extList = new HashSet<String>();
10772            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10773                if (app.pkgList != null) {
10774                    for (String pkg : app.pkgList) {
10775                        extList.add(pkg);
10776                    }
10777                }
10778            }
10779            IPackageManager pm = AppGlobals.getPackageManager();
10780            for (String pkg : extList) {
10781                try {
10782                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10783                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10784                        retList.add(info);
10785                    }
10786                } catch (RemoteException e) {
10787                }
10788            }
10789        }
10790        return retList;
10791    }
10792
10793    @Override
10794    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10795        enforceNotIsolatedCaller("getMyMemoryState");
10796        synchronized (this) {
10797            ProcessRecord proc;
10798            synchronized (mPidsSelfLocked) {
10799                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10800            }
10801            fillInProcMemInfo(proc, outInfo);
10802        }
10803    }
10804
10805    @Override
10806    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10807        if (checkCallingPermission(android.Manifest.permission.DUMP)
10808                != PackageManager.PERMISSION_GRANTED) {
10809            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10810                    + Binder.getCallingPid()
10811                    + ", uid=" + Binder.getCallingUid()
10812                    + " without permission "
10813                    + android.Manifest.permission.DUMP);
10814            return;
10815        }
10816
10817        boolean dumpAll = false;
10818        boolean dumpClient = false;
10819        String dumpPackage = null;
10820
10821        int opti = 0;
10822        while (opti < args.length) {
10823            String opt = args[opti];
10824            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10825                break;
10826            }
10827            opti++;
10828            if ("-a".equals(opt)) {
10829                dumpAll = true;
10830            } else if ("-c".equals(opt)) {
10831                dumpClient = true;
10832            } else if ("-h".equals(opt)) {
10833                pw.println("Activity manager dump options:");
10834                pw.println("  [-a] [-c] [-h] [cmd] ...");
10835                pw.println("  cmd may be one of:");
10836                pw.println("    a[ctivities]: activity stack state");
10837                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10838                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10839                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10840                pw.println("    o[om]: out of memory management");
10841                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10842                pw.println("    provider [COMP_SPEC]: provider client-side state");
10843                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10844                pw.println("    service [COMP_SPEC]: service client-side state");
10845                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10846                pw.println("    all: dump all activities");
10847                pw.println("    top: dump the top activity");
10848                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10849                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10850                pw.println("    a partial substring in a component name, a");
10851                pw.println("    hex object identifier.");
10852                pw.println("  -a: include all available server state.");
10853                pw.println("  -c: include client state.");
10854                return;
10855            } else {
10856                pw.println("Unknown argument: " + opt + "; use -h for help");
10857            }
10858        }
10859
10860        long origId = Binder.clearCallingIdentity();
10861        boolean more = false;
10862        // Is the caller requesting to dump a particular piece of data?
10863        if (opti < args.length) {
10864            String cmd = args[opti];
10865            opti++;
10866            if ("activities".equals(cmd) || "a".equals(cmd)) {
10867                synchronized (this) {
10868                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10869                }
10870            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10871                String[] newArgs;
10872                String name;
10873                if (opti >= args.length) {
10874                    name = null;
10875                    newArgs = EMPTY_STRING_ARRAY;
10876                } else {
10877                    name = args[opti];
10878                    opti++;
10879                    newArgs = new String[args.length - opti];
10880                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10881                            args.length - opti);
10882                }
10883                synchronized (this) {
10884                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10885                }
10886            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10887                String[] newArgs;
10888                String name;
10889                if (opti >= args.length) {
10890                    name = null;
10891                    newArgs = EMPTY_STRING_ARRAY;
10892                } else {
10893                    name = args[opti];
10894                    opti++;
10895                    newArgs = new String[args.length - opti];
10896                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10897                            args.length - opti);
10898                }
10899                synchronized (this) {
10900                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10901                }
10902            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10903                String[] newArgs;
10904                String name;
10905                if (opti >= args.length) {
10906                    name = null;
10907                    newArgs = EMPTY_STRING_ARRAY;
10908                } else {
10909                    name = args[opti];
10910                    opti++;
10911                    newArgs = new String[args.length - opti];
10912                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10913                            args.length - opti);
10914                }
10915                synchronized (this) {
10916                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10917                }
10918            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10919                synchronized (this) {
10920                    dumpOomLocked(fd, pw, args, opti, true);
10921                }
10922            } else if ("provider".equals(cmd)) {
10923                String[] newArgs;
10924                String name;
10925                if (opti >= args.length) {
10926                    name = null;
10927                    newArgs = EMPTY_STRING_ARRAY;
10928                } else {
10929                    name = args[opti];
10930                    opti++;
10931                    newArgs = new String[args.length - opti];
10932                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10933                }
10934                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10935                    pw.println("No providers match: " + name);
10936                    pw.println("Use -h for help.");
10937                }
10938            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10939                synchronized (this) {
10940                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10941                }
10942            } else if ("service".equals(cmd)) {
10943                String[] newArgs;
10944                String name;
10945                if (opti >= args.length) {
10946                    name = null;
10947                    newArgs = EMPTY_STRING_ARRAY;
10948                } else {
10949                    name = args[opti];
10950                    opti++;
10951                    newArgs = new String[args.length - opti];
10952                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10953                            args.length - opti);
10954                }
10955                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10956                    pw.println("No services match: " + name);
10957                    pw.println("Use -h for help.");
10958                }
10959            } else if ("package".equals(cmd)) {
10960                String[] newArgs;
10961                if (opti >= args.length) {
10962                    pw.println("package: no package name specified");
10963                    pw.println("Use -h for help.");
10964                } else {
10965                    dumpPackage = args[opti];
10966                    opti++;
10967                    newArgs = new String[args.length - opti];
10968                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10969                            args.length - opti);
10970                    args = newArgs;
10971                    opti = 0;
10972                    more = true;
10973                }
10974            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10975                synchronized (this) {
10976                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10977                }
10978            } else {
10979                // Dumping a single activity?
10980                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10981                    pw.println("Bad activity command, or no activities match: " + cmd);
10982                    pw.println("Use -h for help.");
10983                }
10984            }
10985            if (!more) {
10986                Binder.restoreCallingIdentity(origId);
10987                return;
10988            }
10989        }
10990
10991        // No piece of data specified, dump everything.
10992        synchronized (this) {
10993            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10994            pw.println();
10995            if (dumpAll) {
10996                pw.println("-------------------------------------------------------------------------------");
10997            }
10998            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10999            pw.println();
11000            if (dumpAll) {
11001                pw.println("-------------------------------------------------------------------------------");
11002            }
11003            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11004            pw.println();
11005            if (dumpAll) {
11006                pw.println("-------------------------------------------------------------------------------");
11007            }
11008            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11009            pw.println();
11010            if (dumpAll) {
11011                pw.println("-------------------------------------------------------------------------------");
11012            }
11013            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11014            pw.println();
11015            if (dumpAll) {
11016                pw.println("-------------------------------------------------------------------------------");
11017            }
11018            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11019        }
11020        Binder.restoreCallingIdentity(origId);
11021    }
11022
11023    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11024            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11025        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11026
11027        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11028                dumpPackage);
11029        boolean needSep = printedAnything;
11030
11031        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11032                dumpPackage, needSep, "  mFocusedActivity: ");
11033        if (printed) {
11034            printedAnything = true;
11035            needSep = false;
11036        }
11037
11038        if (dumpPackage == null) {
11039            if (needSep) {
11040                pw.println();
11041            }
11042            needSep = true;
11043            printedAnything = true;
11044            mStackSupervisor.dump(pw, "  ");
11045        }
11046
11047        if (mRecentTasks.size() > 0) {
11048            boolean printedHeader = false;
11049
11050            final int N = mRecentTasks.size();
11051            for (int i=0; i<N; i++) {
11052                TaskRecord tr = mRecentTasks.get(i);
11053                if (dumpPackage != null) {
11054                    if (tr.realActivity == null ||
11055                            !dumpPackage.equals(tr.realActivity)) {
11056                        continue;
11057                    }
11058                }
11059                if (!printedHeader) {
11060                    if (needSep) {
11061                        pw.println();
11062                    }
11063                    pw.println("  Recent tasks:");
11064                    printedHeader = true;
11065                    printedAnything = true;
11066                }
11067                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11068                        pw.println(tr);
11069                if (dumpAll) {
11070                    mRecentTasks.get(i).dump(pw, "    ");
11071                }
11072            }
11073        }
11074
11075        if (!printedAnything) {
11076            pw.println("  (nothing)");
11077        }
11078    }
11079
11080    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11081            int opti, boolean dumpAll, String dumpPackage) {
11082        boolean needSep = false;
11083        boolean printedAnything = false;
11084        int numPers = 0;
11085
11086        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11087
11088        if (dumpAll) {
11089            final int NP = mProcessNames.getMap().size();
11090            for (int ip=0; ip<NP; ip++) {
11091                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11092                final int NA = procs.size();
11093                for (int ia=0; ia<NA; ia++) {
11094                    ProcessRecord r = procs.valueAt(ia);
11095                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11096                        continue;
11097                    }
11098                    if (!needSep) {
11099                        pw.println("  All known processes:");
11100                        needSep = true;
11101                        printedAnything = true;
11102                    }
11103                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11104                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11105                        pw.print(" "); pw.println(r);
11106                    r.dump(pw, "    ");
11107                    if (r.persistent) {
11108                        numPers++;
11109                    }
11110                }
11111            }
11112        }
11113
11114        if (mIsolatedProcesses.size() > 0) {
11115            boolean printed = false;
11116            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11117                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11118                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11119                    continue;
11120                }
11121                if (!printed) {
11122                    if (needSep) {
11123                        pw.println();
11124                    }
11125                    pw.println("  Isolated process list (sorted by uid):");
11126                    printedAnything = true;
11127                    printed = true;
11128                    needSep = true;
11129                }
11130                pw.println(String.format("%sIsolated #%2d: %s",
11131                        "    ", i, r.toString()));
11132            }
11133        }
11134
11135        if (mLruProcesses.size() > 0) {
11136            if (needSep) {
11137                pw.println();
11138            }
11139            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11140                    pw.print(" total, non-act at ");
11141                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11142                    pw.print(", non-svc at ");
11143                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11144                    pw.println("):");
11145            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11146            needSep = true;
11147            printedAnything = true;
11148        }
11149
11150        if (dumpAll || dumpPackage != null) {
11151            synchronized (mPidsSelfLocked) {
11152                boolean printed = false;
11153                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11154                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11155                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11156                        continue;
11157                    }
11158                    if (!printed) {
11159                        if (needSep) pw.println();
11160                        needSep = true;
11161                        pw.println("  PID mappings:");
11162                        printed = true;
11163                        printedAnything = true;
11164                    }
11165                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11166                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11167                }
11168            }
11169        }
11170
11171        if (mForegroundProcesses.size() > 0) {
11172            synchronized (mPidsSelfLocked) {
11173                boolean printed = false;
11174                for (int i=0; i<mForegroundProcesses.size(); i++) {
11175                    ProcessRecord r = mPidsSelfLocked.get(
11176                            mForegroundProcesses.valueAt(i).pid);
11177                    if (dumpPackage != null && (r == null
11178                            || !r.pkgList.containsKey(dumpPackage))) {
11179                        continue;
11180                    }
11181                    if (!printed) {
11182                        if (needSep) pw.println();
11183                        needSep = true;
11184                        pw.println("  Foreground Processes:");
11185                        printed = true;
11186                        printedAnything = true;
11187                    }
11188                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11189                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11190                }
11191            }
11192        }
11193
11194        if (mPersistentStartingProcesses.size() > 0) {
11195            if (needSep) pw.println();
11196            needSep = true;
11197            printedAnything = true;
11198            pw.println("  Persisent processes that are starting:");
11199            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11200                    "Starting Norm", "Restarting PERS", dumpPackage);
11201        }
11202
11203        if (mRemovedProcesses.size() > 0) {
11204            if (needSep) pw.println();
11205            needSep = true;
11206            printedAnything = true;
11207            pw.println("  Processes that are being removed:");
11208            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11209                    "Removed Norm", "Removed PERS", dumpPackage);
11210        }
11211
11212        if (mProcessesOnHold.size() > 0) {
11213            if (needSep) pw.println();
11214            needSep = true;
11215            printedAnything = true;
11216            pw.println("  Processes that are on old until the system is ready:");
11217            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11218                    "OnHold Norm", "OnHold PERS", dumpPackage);
11219        }
11220
11221        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11222
11223        if (mProcessCrashTimes.getMap().size() > 0) {
11224            boolean printed = false;
11225            long now = SystemClock.uptimeMillis();
11226            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11227            final int NP = pmap.size();
11228            for (int ip=0; ip<NP; ip++) {
11229                String pname = pmap.keyAt(ip);
11230                SparseArray<Long> uids = pmap.valueAt(ip);
11231                final int N = uids.size();
11232                for (int i=0; i<N; i++) {
11233                    int puid = uids.keyAt(i);
11234                    ProcessRecord r = mProcessNames.get(pname, puid);
11235                    if (dumpPackage != null && (r == null
11236                            || !r.pkgList.containsKey(dumpPackage))) {
11237                        continue;
11238                    }
11239                    if (!printed) {
11240                        if (needSep) pw.println();
11241                        needSep = true;
11242                        pw.println("  Time since processes crashed:");
11243                        printed = true;
11244                        printedAnything = true;
11245                    }
11246                    pw.print("    Process "); pw.print(pname);
11247                            pw.print(" uid "); pw.print(puid);
11248                            pw.print(": last crashed ");
11249                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11250                            pw.println(" ago");
11251                }
11252            }
11253        }
11254
11255        if (mBadProcesses.getMap().size() > 0) {
11256            boolean printed = false;
11257            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11258            final int NP = pmap.size();
11259            for (int ip=0; ip<NP; ip++) {
11260                String pname = pmap.keyAt(ip);
11261                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11262                final int N = uids.size();
11263                for (int i=0; i<N; i++) {
11264                    int puid = uids.keyAt(i);
11265                    ProcessRecord r = mProcessNames.get(pname, puid);
11266                    if (dumpPackage != null && (r == null
11267                            || !r.pkgList.containsKey(dumpPackage))) {
11268                        continue;
11269                    }
11270                    if (!printed) {
11271                        if (needSep) pw.println();
11272                        needSep = true;
11273                        pw.println("  Bad processes:");
11274                        printedAnything = true;
11275                    }
11276                    BadProcessInfo info = uids.valueAt(i);
11277                    pw.print("    Bad process "); pw.print(pname);
11278                            pw.print(" uid "); pw.print(puid);
11279                            pw.print(": crashed at time "); pw.println(info.time);
11280                    if (info.shortMsg != null) {
11281                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11282                    }
11283                    if (info.longMsg != null) {
11284                        pw.print("      Long msg: "); pw.println(info.longMsg);
11285                    }
11286                    if (info.stack != null) {
11287                        pw.println("      Stack:");
11288                        int lastPos = 0;
11289                        for (int pos=0; pos<info.stack.length(); pos++) {
11290                            if (info.stack.charAt(pos) == '\n') {
11291                                pw.print("        ");
11292                                pw.write(info.stack, lastPos, pos-lastPos);
11293                                pw.println();
11294                                lastPos = pos+1;
11295                            }
11296                        }
11297                        if (lastPos < info.stack.length()) {
11298                            pw.print("        ");
11299                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11300                            pw.println();
11301                        }
11302                    }
11303                }
11304            }
11305        }
11306
11307        if (dumpPackage == null) {
11308            pw.println();
11309            needSep = false;
11310            pw.println("  mStartedUsers:");
11311            for (int i=0; i<mStartedUsers.size(); i++) {
11312                UserStartedState uss = mStartedUsers.valueAt(i);
11313                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11314                        pw.print(": "); uss.dump("", pw);
11315            }
11316            pw.print("  mStartedUserArray: [");
11317            for (int i=0; i<mStartedUserArray.length; i++) {
11318                if (i > 0) pw.print(", ");
11319                pw.print(mStartedUserArray[i]);
11320            }
11321            pw.println("]");
11322            pw.print("  mUserLru: [");
11323            for (int i=0; i<mUserLru.size(); i++) {
11324                if (i > 0) pw.print(", ");
11325                pw.print(mUserLru.get(i));
11326            }
11327            pw.println("]");
11328            if (dumpAll) {
11329                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11330            }
11331        }
11332        if (mHomeProcess != null && (dumpPackage == null
11333                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11334            if (needSep) {
11335                pw.println();
11336                needSep = false;
11337            }
11338            pw.println("  mHomeProcess: " + mHomeProcess);
11339        }
11340        if (mPreviousProcess != null && (dumpPackage == null
11341                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11342            if (needSep) {
11343                pw.println();
11344                needSep = false;
11345            }
11346            pw.println("  mPreviousProcess: " + mPreviousProcess);
11347        }
11348        if (dumpAll) {
11349            StringBuilder sb = new StringBuilder(128);
11350            sb.append("  mPreviousProcessVisibleTime: ");
11351            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11352            pw.println(sb);
11353        }
11354        if (mHeavyWeightProcess != null && (dumpPackage == null
11355                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11356            if (needSep) {
11357                pw.println();
11358                needSep = false;
11359            }
11360            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11361        }
11362        if (dumpPackage == null) {
11363            pw.println("  mConfiguration: " + mConfiguration);
11364        }
11365        if (dumpAll) {
11366            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11367            if (mCompatModePackages.getPackages().size() > 0) {
11368                boolean printed = false;
11369                for (Map.Entry<String, Integer> entry
11370                        : mCompatModePackages.getPackages().entrySet()) {
11371                    String pkg = entry.getKey();
11372                    int mode = entry.getValue();
11373                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11374                        continue;
11375                    }
11376                    if (!printed) {
11377                        pw.println("  mScreenCompatPackages:");
11378                        printed = true;
11379                    }
11380                    pw.print("    "); pw.print(pkg); pw.print(": ");
11381                            pw.print(mode); pw.println();
11382                }
11383            }
11384        }
11385        if (dumpPackage == null) {
11386            if (mSleeping || mWentToSleep || mLockScreenShown) {
11387                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11388                        + " mLockScreenShown " + mLockScreenShown);
11389            }
11390            if (mShuttingDown || mRunningVoice) {
11391                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11392            }
11393        }
11394        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11395                || mOrigWaitForDebugger) {
11396            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11397                    || dumpPackage.equals(mOrigDebugApp)) {
11398                if (needSep) {
11399                    pw.println();
11400                    needSep = false;
11401                }
11402                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11403                        + " mDebugTransient=" + mDebugTransient
11404                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11405            }
11406        }
11407        if (mOpenGlTraceApp != null) {
11408            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11409                if (needSep) {
11410                    pw.println();
11411                    needSep = false;
11412                }
11413                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11414            }
11415        }
11416        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11417                || mProfileFd != null) {
11418            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11419                if (needSep) {
11420                    pw.println();
11421                    needSep = false;
11422                }
11423                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11424                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11425                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11426                        + mAutoStopProfiler);
11427            }
11428        }
11429        if (dumpPackage == null) {
11430            if (mAlwaysFinishActivities || mController != null) {
11431                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11432                        + " mController=" + mController);
11433            }
11434            if (dumpAll) {
11435                pw.println("  Total persistent processes: " + numPers);
11436                pw.println("  mProcessesReady=" + mProcessesReady
11437                        + " mSystemReady=" + mSystemReady);
11438                pw.println("  mBooting=" + mBooting
11439                        + " mBooted=" + mBooted
11440                        + " mFactoryTest=" + mFactoryTest);
11441                pw.print("  mLastPowerCheckRealtime=");
11442                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11443                        pw.println("");
11444                pw.print("  mLastPowerCheckUptime=");
11445                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11446                        pw.println("");
11447                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11448                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11449                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11450                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11451                        + " (" + mLruProcesses.size() + " total)"
11452                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11453                        + " mNumServiceProcs=" + mNumServiceProcs
11454                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11455                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11456                        + " mLastMemoryLevel" + mLastMemoryLevel
11457                        + " mLastNumProcesses" + mLastNumProcesses);
11458                long now = SystemClock.uptimeMillis();
11459                pw.print("  mLastIdleTime=");
11460                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11461                        pw.print(" mLowRamSinceLastIdle=");
11462                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11463                        pw.println();
11464            }
11465        }
11466
11467        if (!printedAnything) {
11468            pw.println("  (nothing)");
11469        }
11470    }
11471
11472    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11473            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11474        if (mProcessesToGc.size() > 0) {
11475            boolean printed = false;
11476            long now = SystemClock.uptimeMillis();
11477            for (int i=0; i<mProcessesToGc.size(); i++) {
11478                ProcessRecord proc = mProcessesToGc.get(i);
11479                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11480                    continue;
11481                }
11482                if (!printed) {
11483                    if (needSep) pw.println();
11484                    needSep = true;
11485                    pw.println("  Processes that are waiting to GC:");
11486                    printed = true;
11487                }
11488                pw.print("    Process "); pw.println(proc);
11489                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11490                        pw.print(", last gced=");
11491                        pw.print(now-proc.lastRequestedGc);
11492                        pw.print(" ms ago, last lowMem=");
11493                        pw.print(now-proc.lastLowMemory);
11494                        pw.println(" ms ago");
11495
11496            }
11497        }
11498        return needSep;
11499    }
11500
11501    void printOomLevel(PrintWriter pw, String name, int adj) {
11502        pw.print("    ");
11503        if (adj >= 0) {
11504            pw.print(' ');
11505            if (adj < 10) pw.print(' ');
11506        } else {
11507            if (adj > -10) pw.print(' ');
11508        }
11509        pw.print(adj);
11510        pw.print(": ");
11511        pw.print(name);
11512        pw.print(" (");
11513        pw.print(mProcessList.getMemLevel(adj)/1024);
11514        pw.println(" kB)");
11515    }
11516
11517    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11518            int opti, boolean dumpAll) {
11519        boolean needSep = false;
11520
11521        if (mLruProcesses.size() > 0) {
11522            if (needSep) pw.println();
11523            needSep = true;
11524            pw.println("  OOM levels:");
11525            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11526            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11527            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11528            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11529            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11530            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11531            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11532            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11533            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11534            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11535            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11536            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11537            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11538
11539            if (needSep) pw.println();
11540            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11541                    pw.print(" total, non-act at ");
11542                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11543                    pw.print(", non-svc at ");
11544                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11545                    pw.println("):");
11546            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11547            needSep = true;
11548        }
11549
11550        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11551
11552        pw.println();
11553        pw.println("  mHomeProcess: " + mHomeProcess);
11554        pw.println("  mPreviousProcess: " + mPreviousProcess);
11555        if (mHeavyWeightProcess != null) {
11556            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11557        }
11558
11559        return true;
11560    }
11561
11562    /**
11563     * There are three ways to call this:
11564     *  - no provider specified: dump all the providers
11565     *  - a flattened component name that matched an existing provider was specified as the
11566     *    first arg: dump that one provider
11567     *  - the first arg isn't the flattened component name of an existing provider:
11568     *    dump all providers whose component contains the first arg as a substring
11569     */
11570    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11571            int opti, boolean dumpAll) {
11572        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11573    }
11574
11575    static class ItemMatcher {
11576        ArrayList<ComponentName> components;
11577        ArrayList<String> strings;
11578        ArrayList<Integer> objects;
11579        boolean all;
11580
11581        ItemMatcher() {
11582            all = true;
11583        }
11584
11585        void build(String name) {
11586            ComponentName componentName = ComponentName.unflattenFromString(name);
11587            if (componentName != null) {
11588                if (components == null) {
11589                    components = new ArrayList<ComponentName>();
11590                }
11591                components.add(componentName);
11592                all = false;
11593            } else {
11594                int objectId = 0;
11595                // Not a '/' separated full component name; maybe an object ID?
11596                try {
11597                    objectId = Integer.parseInt(name, 16);
11598                    if (objects == null) {
11599                        objects = new ArrayList<Integer>();
11600                    }
11601                    objects.add(objectId);
11602                    all = false;
11603                } catch (RuntimeException e) {
11604                    // Not an integer; just do string match.
11605                    if (strings == null) {
11606                        strings = new ArrayList<String>();
11607                    }
11608                    strings.add(name);
11609                    all = false;
11610                }
11611            }
11612        }
11613
11614        int build(String[] args, int opti) {
11615            for (; opti<args.length; opti++) {
11616                String name = args[opti];
11617                if ("--".equals(name)) {
11618                    return opti+1;
11619                }
11620                build(name);
11621            }
11622            return opti;
11623        }
11624
11625        boolean match(Object object, ComponentName comp) {
11626            if (all) {
11627                return true;
11628            }
11629            if (components != null) {
11630                for (int i=0; i<components.size(); i++) {
11631                    if (components.get(i).equals(comp)) {
11632                        return true;
11633                    }
11634                }
11635            }
11636            if (objects != null) {
11637                for (int i=0; i<objects.size(); i++) {
11638                    if (System.identityHashCode(object) == objects.get(i)) {
11639                        return true;
11640                    }
11641                }
11642            }
11643            if (strings != null) {
11644                String flat = comp.flattenToString();
11645                for (int i=0; i<strings.size(); i++) {
11646                    if (flat.contains(strings.get(i))) {
11647                        return true;
11648                    }
11649                }
11650            }
11651            return false;
11652        }
11653    }
11654
11655    /**
11656     * There are three things that cmd can be:
11657     *  - a flattened component name that matches an existing activity
11658     *  - the cmd arg isn't the flattened component name of an existing activity:
11659     *    dump all activity whose component contains the cmd as a substring
11660     *  - A hex number of the ActivityRecord object instance.
11661     */
11662    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11663            int opti, boolean dumpAll) {
11664        ArrayList<ActivityRecord> activities;
11665
11666        synchronized (this) {
11667            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11668        }
11669
11670        if (activities.size() <= 0) {
11671            return false;
11672        }
11673
11674        String[] newArgs = new String[args.length - opti];
11675        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11676
11677        TaskRecord lastTask = null;
11678        boolean needSep = false;
11679        for (int i=activities.size()-1; i>=0; i--) {
11680            ActivityRecord r = activities.get(i);
11681            if (needSep) {
11682                pw.println();
11683            }
11684            needSep = true;
11685            synchronized (this) {
11686                if (lastTask != r.task) {
11687                    lastTask = r.task;
11688                    pw.print("TASK "); pw.print(lastTask.affinity);
11689                            pw.print(" id="); pw.println(lastTask.taskId);
11690                    if (dumpAll) {
11691                        lastTask.dump(pw, "  ");
11692                    }
11693                }
11694            }
11695            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11696        }
11697        return true;
11698    }
11699
11700    /**
11701     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11702     * there is a thread associated with the activity.
11703     */
11704    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11705            final ActivityRecord r, String[] args, boolean dumpAll) {
11706        String innerPrefix = prefix + "  ";
11707        synchronized (this) {
11708            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11709                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11710                    pw.print(" pid=");
11711                    if (r.app != null) pw.println(r.app.pid);
11712                    else pw.println("(not running)");
11713            if (dumpAll) {
11714                r.dump(pw, innerPrefix);
11715            }
11716        }
11717        if (r.app != null && r.app.thread != null) {
11718            // flush anything that is already in the PrintWriter since the thread is going
11719            // to write to the file descriptor directly
11720            pw.flush();
11721            try {
11722                TransferPipe tp = new TransferPipe();
11723                try {
11724                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11725                            r.appToken, innerPrefix, args);
11726                    tp.go(fd);
11727                } finally {
11728                    tp.kill();
11729                }
11730            } catch (IOException e) {
11731                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11732            } catch (RemoteException e) {
11733                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11734            }
11735        }
11736    }
11737
11738    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11739            int opti, boolean dumpAll, String dumpPackage) {
11740        boolean needSep = false;
11741        boolean onlyHistory = false;
11742        boolean printedAnything = false;
11743
11744        if ("history".equals(dumpPackage)) {
11745            if (opti < args.length && "-s".equals(args[opti])) {
11746                dumpAll = false;
11747            }
11748            onlyHistory = true;
11749            dumpPackage = null;
11750        }
11751
11752        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11753        if (!onlyHistory && dumpAll) {
11754            if (mRegisteredReceivers.size() > 0) {
11755                boolean printed = false;
11756                Iterator it = mRegisteredReceivers.values().iterator();
11757                while (it.hasNext()) {
11758                    ReceiverList r = (ReceiverList)it.next();
11759                    if (dumpPackage != null && (r.app == null ||
11760                            !dumpPackage.equals(r.app.info.packageName))) {
11761                        continue;
11762                    }
11763                    if (!printed) {
11764                        pw.println("  Registered Receivers:");
11765                        needSep = true;
11766                        printed = true;
11767                        printedAnything = true;
11768                    }
11769                    pw.print("  * "); pw.println(r);
11770                    r.dump(pw, "    ");
11771                }
11772            }
11773
11774            if (mReceiverResolver.dump(pw, needSep ?
11775                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11776                    "    ", dumpPackage, false)) {
11777                needSep = true;
11778                printedAnything = true;
11779            }
11780        }
11781
11782        for (BroadcastQueue q : mBroadcastQueues) {
11783            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11784            printedAnything |= needSep;
11785        }
11786
11787        needSep = true;
11788
11789        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11790            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11791                if (needSep) {
11792                    pw.println();
11793                }
11794                needSep = true;
11795                printedAnything = true;
11796                pw.print("  Sticky broadcasts for user ");
11797                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11798                StringBuilder sb = new StringBuilder(128);
11799                for (Map.Entry<String, ArrayList<Intent>> ent
11800                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11801                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11802                    if (dumpAll) {
11803                        pw.println(":");
11804                        ArrayList<Intent> intents = ent.getValue();
11805                        final int N = intents.size();
11806                        for (int i=0; i<N; i++) {
11807                            sb.setLength(0);
11808                            sb.append("    Intent: ");
11809                            intents.get(i).toShortString(sb, false, true, false, false);
11810                            pw.println(sb.toString());
11811                            Bundle bundle = intents.get(i).getExtras();
11812                            if (bundle != null) {
11813                                pw.print("      ");
11814                                pw.println(bundle.toString());
11815                            }
11816                        }
11817                    } else {
11818                        pw.println("");
11819                    }
11820                }
11821            }
11822        }
11823
11824        if (!onlyHistory && dumpAll) {
11825            pw.println();
11826            for (BroadcastQueue queue : mBroadcastQueues) {
11827                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11828                        + queue.mBroadcastsScheduled);
11829            }
11830            pw.println("  mHandler:");
11831            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11832            needSep = true;
11833            printedAnything = true;
11834        }
11835
11836        if (!printedAnything) {
11837            pw.println("  (nothing)");
11838        }
11839    }
11840
11841    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11842            int opti, boolean dumpAll, String dumpPackage) {
11843        boolean needSep;
11844        boolean printedAnything = false;
11845
11846        ItemMatcher matcher = new ItemMatcher();
11847        matcher.build(args, opti);
11848
11849        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11850
11851        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11852        printedAnything |= needSep;
11853
11854        if (mLaunchingProviders.size() > 0) {
11855            boolean printed = false;
11856            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11857                ContentProviderRecord r = mLaunchingProviders.get(i);
11858                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11859                    continue;
11860                }
11861                if (!printed) {
11862                    if (needSep) pw.println();
11863                    needSep = true;
11864                    pw.println("  Launching content providers:");
11865                    printed = true;
11866                    printedAnything = true;
11867                }
11868                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11869                        pw.println(r);
11870            }
11871        }
11872
11873        if (mGrantedUriPermissions.size() > 0) {
11874            boolean printed = false;
11875            int dumpUid = -2;
11876            if (dumpPackage != null) {
11877                try {
11878                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11879                } catch (NameNotFoundException e) {
11880                    dumpUid = -1;
11881                }
11882            }
11883            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11884                int uid = mGrantedUriPermissions.keyAt(i);
11885                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11886                    continue;
11887                }
11888                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11889                if (!printed) {
11890                    if (needSep) pw.println();
11891                    needSep = true;
11892                    pw.println("  Granted Uri Permissions:");
11893                    printed = true;
11894                    printedAnything = true;
11895                }
11896                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11897                for (UriPermission perm : perms.values()) {
11898                    pw.print("    "); pw.println(perm);
11899                    if (dumpAll) {
11900                        perm.dump(pw, "      ");
11901                    }
11902                }
11903            }
11904        }
11905
11906        if (!printedAnything) {
11907            pw.println("  (nothing)");
11908        }
11909    }
11910
11911    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11912            int opti, boolean dumpAll, String dumpPackage) {
11913        boolean printed = false;
11914
11915        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11916
11917        if (mIntentSenderRecords.size() > 0) {
11918            Iterator<WeakReference<PendingIntentRecord>> it
11919                    = mIntentSenderRecords.values().iterator();
11920            while (it.hasNext()) {
11921                WeakReference<PendingIntentRecord> ref = it.next();
11922                PendingIntentRecord rec = ref != null ? ref.get(): null;
11923                if (dumpPackage != null && (rec == null
11924                        || !dumpPackage.equals(rec.key.packageName))) {
11925                    continue;
11926                }
11927                printed = true;
11928                if (rec != null) {
11929                    pw.print("  * "); pw.println(rec);
11930                    if (dumpAll) {
11931                        rec.dump(pw, "    ");
11932                    }
11933                } else {
11934                    pw.print("  * "); pw.println(ref);
11935                }
11936            }
11937        }
11938
11939        if (!printed) {
11940            pw.println("  (nothing)");
11941        }
11942    }
11943
11944    private static final int dumpProcessList(PrintWriter pw,
11945            ActivityManagerService service, List list,
11946            String prefix, String normalLabel, String persistentLabel,
11947            String dumpPackage) {
11948        int numPers = 0;
11949        final int N = list.size()-1;
11950        for (int i=N; i>=0; i--) {
11951            ProcessRecord r = (ProcessRecord)list.get(i);
11952            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11953                continue;
11954            }
11955            pw.println(String.format("%s%s #%2d: %s",
11956                    prefix, (r.persistent ? persistentLabel : normalLabel),
11957                    i, r.toString()));
11958            if (r.persistent) {
11959                numPers++;
11960            }
11961        }
11962        return numPers;
11963    }
11964
11965    private static final boolean dumpProcessOomList(PrintWriter pw,
11966            ActivityManagerService service, List<ProcessRecord> origList,
11967            String prefix, String normalLabel, String persistentLabel,
11968            boolean inclDetails, String dumpPackage) {
11969
11970        ArrayList<Pair<ProcessRecord, Integer>> list
11971                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11972        for (int i=0; i<origList.size(); i++) {
11973            ProcessRecord r = origList.get(i);
11974            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11975                continue;
11976            }
11977            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11978        }
11979
11980        if (list.size() <= 0) {
11981            return false;
11982        }
11983
11984        Comparator<Pair<ProcessRecord, Integer>> comparator
11985                = new Comparator<Pair<ProcessRecord, Integer>>() {
11986            @Override
11987            public int compare(Pair<ProcessRecord, Integer> object1,
11988                    Pair<ProcessRecord, Integer> object2) {
11989                if (object1.first.setAdj != object2.first.setAdj) {
11990                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11991                }
11992                if (object1.second.intValue() != object2.second.intValue()) {
11993                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11994                }
11995                return 0;
11996            }
11997        };
11998
11999        Collections.sort(list, comparator);
12000
12001        final long curRealtime = SystemClock.elapsedRealtime();
12002        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12003        final long curUptime = SystemClock.uptimeMillis();
12004        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12005
12006        for (int i=list.size()-1; i>=0; i--) {
12007            ProcessRecord r = list.get(i).first;
12008            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12009            char schedGroup;
12010            switch (r.setSchedGroup) {
12011                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12012                    schedGroup = 'B';
12013                    break;
12014                case Process.THREAD_GROUP_DEFAULT:
12015                    schedGroup = 'F';
12016                    break;
12017                default:
12018                    schedGroup = '?';
12019                    break;
12020            }
12021            char foreground;
12022            if (r.foregroundActivities) {
12023                foreground = 'A';
12024            } else if (r.foregroundServices) {
12025                foreground = 'S';
12026            } else {
12027                foreground = ' ';
12028            }
12029            String procState = ProcessList.makeProcStateString(r.curProcState);
12030            pw.print(prefix);
12031            pw.print(r.persistent ? persistentLabel : normalLabel);
12032            pw.print(" #");
12033            int num = (origList.size()-1)-list.get(i).second;
12034            if (num < 10) pw.print(' ');
12035            pw.print(num);
12036            pw.print(": ");
12037            pw.print(oomAdj);
12038            pw.print(' ');
12039            pw.print(schedGroup);
12040            pw.print('/');
12041            pw.print(foreground);
12042            pw.print('/');
12043            pw.print(procState);
12044            pw.print(" trm:");
12045            if (r.trimMemoryLevel < 10) pw.print(' ');
12046            pw.print(r.trimMemoryLevel);
12047            pw.print(' ');
12048            pw.print(r.toShortString());
12049            pw.print(" (");
12050            pw.print(r.adjType);
12051            pw.println(')');
12052            if (r.adjSource != null || r.adjTarget != null) {
12053                pw.print(prefix);
12054                pw.print("    ");
12055                if (r.adjTarget instanceof ComponentName) {
12056                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12057                } else if (r.adjTarget != null) {
12058                    pw.print(r.adjTarget.toString());
12059                } else {
12060                    pw.print("{null}");
12061                }
12062                pw.print("<=");
12063                if (r.adjSource instanceof ProcessRecord) {
12064                    pw.print("Proc{");
12065                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12066                    pw.println("}");
12067                } else if (r.adjSource != null) {
12068                    pw.println(r.adjSource.toString());
12069                } else {
12070                    pw.println("{null}");
12071                }
12072            }
12073            if (inclDetails) {
12074                pw.print(prefix);
12075                pw.print("    ");
12076                pw.print("oom: max="); pw.print(r.maxAdj);
12077                pw.print(" curRaw="); pw.print(r.curRawAdj);
12078                pw.print(" setRaw="); pw.print(r.setRawAdj);
12079                pw.print(" cur="); pw.print(r.curAdj);
12080                pw.print(" set="); pw.println(r.setAdj);
12081                pw.print(prefix);
12082                pw.print("    ");
12083                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12084                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12085                pw.print(" lastPss="); pw.print(r.lastPss);
12086                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12087                pw.print(prefix);
12088                pw.print("    ");
12089                pw.print("keeping="); pw.print(r.keeping);
12090                pw.print(" cached="); pw.print(r.cached);
12091                pw.print(" empty="); pw.print(r.empty);
12092                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12093
12094                if (!r.keeping) {
12095                    if (r.lastWakeTime != 0) {
12096                        long wtime;
12097                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12098                        synchronized (stats) {
12099                            wtime = stats.getProcessWakeTime(r.info.uid,
12100                                    r.pid, curRealtime);
12101                        }
12102                        long timeUsed = wtime - r.lastWakeTime;
12103                        pw.print(prefix);
12104                        pw.print("    ");
12105                        pw.print("keep awake over ");
12106                        TimeUtils.formatDuration(realtimeSince, pw);
12107                        pw.print(" used ");
12108                        TimeUtils.formatDuration(timeUsed, pw);
12109                        pw.print(" (");
12110                        pw.print((timeUsed*100)/realtimeSince);
12111                        pw.println("%)");
12112                    }
12113                    if (r.lastCpuTime != 0) {
12114                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12115                        pw.print(prefix);
12116                        pw.print("    ");
12117                        pw.print("run cpu over ");
12118                        TimeUtils.formatDuration(uptimeSince, pw);
12119                        pw.print(" used ");
12120                        TimeUtils.formatDuration(timeUsed, pw);
12121                        pw.print(" (");
12122                        pw.print((timeUsed*100)/uptimeSince);
12123                        pw.println("%)");
12124                    }
12125                }
12126            }
12127        }
12128        return true;
12129    }
12130
12131    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12132        ArrayList<ProcessRecord> procs;
12133        synchronized (this) {
12134            if (args != null && args.length > start
12135                    && args[start].charAt(0) != '-') {
12136                procs = new ArrayList<ProcessRecord>();
12137                int pid = -1;
12138                try {
12139                    pid = Integer.parseInt(args[start]);
12140                } catch (NumberFormatException e) {
12141                }
12142                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12143                    ProcessRecord proc = mLruProcesses.get(i);
12144                    if (proc.pid == pid) {
12145                        procs.add(proc);
12146                    } else if (proc.processName.equals(args[start])) {
12147                        procs.add(proc);
12148                    }
12149                }
12150                if (procs.size() <= 0) {
12151                    return null;
12152                }
12153            } else {
12154                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12155            }
12156        }
12157        return procs;
12158    }
12159
12160    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12161            PrintWriter pw, String[] args) {
12162        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12163        if (procs == null) {
12164            pw.println("No process found for: " + args[0]);
12165            return;
12166        }
12167
12168        long uptime = SystemClock.uptimeMillis();
12169        long realtime = SystemClock.elapsedRealtime();
12170        pw.println("Applications Graphics Acceleration Info:");
12171        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12172
12173        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12174            ProcessRecord r = procs.get(i);
12175            if (r.thread != null) {
12176                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12177                pw.flush();
12178                try {
12179                    TransferPipe tp = new TransferPipe();
12180                    try {
12181                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12182                        tp.go(fd);
12183                    } finally {
12184                        tp.kill();
12185                    }
12186                } catch (IOException e) {
12187                    pw.println("Failure while dumping the app: " + r);
12188                    pw.flush();
12189                } catch (RemoteException e) {
12190                    pw.println("Got a RemoteException while dumping the app " + r);
12191                    pw.flush();
12192                }
12193            }
12194        }
12195    }
12196
12197    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12198        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12199        if (procs == null) {
12200            pw.println("No process found for: " + args[0]);
12201            return;
12202        }
12203
12204        pw.println("Applications Database Info:");
12205
12206        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12207            ProcessRecord r = procs.get(i);
12208            if (r.thread != null) {
12209                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12210                pw.flush();
12211                try {
12212                    TransferPipe tp = new TransferPipe();
12213                    try {
12214                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12215                        tp.go(fd);
12216                    } finally {
12217                        tp.kill();
12218                    }
12219                } catch (IOException e) {
12220                    pw.println("Failure while dumping the app: " + r);
12221                    pw.flush();
12222                } catch (RemoteException e) {
12223                    pw.println("Got a RemoteException while dumping the app " + r);
12224                    pw.flush();
12225                }
12226            }
12227        }
12228    }
12229
12230    final static class MemItem {
12231        final boolean isProc;
12232        final String label;
12233        final String shortLabel;
12234        final long pss;
12235        final int id;
12236        final boolean hasActivities;
12237        ArrayList<MemItem> subitems;
12238
12239        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12240                boolean _hasActivities) {
12241            isProc = true;
12242            label = _label;
12243            shortLabel = _shortLabel;
12244            pss = _pss;
12245            id = _id;
12246            hasActivities = _hasActivities;
12247        }
12248
12249        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12250            isProc = false;
12251            label = _label;
12252            shortLabel = _shortLabel;
12253            pss = _pss;
12254            id = _id;
12255            hasActivities = false;
12256        }
12257    }
12258
12259    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12260            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12261        if (sort && !isCompact) {
12262            Collections.sort(items, new Comparator<MemItem>() {
12263                @Override
12264                public int compare(MemItem lhs, MemItem rhs) {
12265                    if (lhs.pss < rhs.pss) {
12266                        return 1;
12267                    } else if (lhs.pss > rhs.pss) {
12268                        return -1;
12269                    }
12270                    return 0;
12271                }
12272            });
12273        }
12274
12275        for (int i=0; i<items.size(); i++) {
12276            MemItem mi = items.get(i);
12277            if (!isCompact) {
12278                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12279            } else if (mi.isProc) {
12280                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12281                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12282                pw.println(mi.hasActivities ? ",a" : ",e");
12283            } else {
12284                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12285                pw.println(mi.pss);
12286            }
12287            if (mi.subitems != null) {
12288                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12289                        true, isCompact);
12290            }
12291        }
12292    }
12293
12294    // These are in KB.
12295    static final long[] DUMP_MEM_BUCKETS = new long[] {
12296        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12297        120*1024, 160*1024, 200*1024,
12298        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12299        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12300    };
12301
12302    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12303            boolean stackLike) {
12304        int start = label.lastIndexOf('.');
12305        if (start >= 0) start++;
12306        else start = 0;
12307        int end = label.length();
12308        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12309            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12310                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12311                out.append(bucket);
12312                out.append(stackLike ? "MB." : "MB ");
12313                out.append(label, start, end);
12314                return;
12315            }
12316        }
12317        out.append(memKB/1024);
12318        out.append(stackLike ? "MB." : "MB ");
12319        out.append(label, start, end);
12320    }
12321
12322    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12323            ProcessList.NATIVE_ADJ,
12324            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12325            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12326            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12327            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12328            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12329    };
12330    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12331            "Native",
12332            "System", "Persistent", "Foreground",
12333            "Visible", "Perceptible",
12334            "Heavy Weight", "Backup",
12335            "A Services", "Home",
12336            "Previous", "B Services", "Cached"
12337    };
12338    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12339            "native",
12340            "sys", "pers", "fore",
12341            "vis", "percept",
12342            "heavy", "backup",
12343            "servicea", "home",
12344            "prev", "serviceb", "cached"
12345    };
12346
12347    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12348            long realtime, boolean isCheckinRequest, boolean isCompact) {
12349        if (isCheckinRequest || isCompact) {
12350            // short checkin version
12351            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12352        } else {
12353            pw.println("Applications Memory Usage (kB):");
12354            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12355        }
12356    }
12357
12358    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12359            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12360        boolean dumpDetails = false;
12361        boolean dumpFullDetails = false;
12362        boolean dumpDalvik = false;
12363        boolean oomOnly = false;
12364        boolean isCompact = false;
12365        boolean localOnly = false;
12366
12367        int opti = 0;
12368        while (opti < args.length) {
12369            String opt = args[opti];
12370            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12371                break;
12372            }
12373            opti++;
12374            if ("-a".equals(opt)) {
12375                dumpDetails = true;
12376                dumpFullDetails = true;
12377                dumpDalvik = true;
12378            } else if ("-d".equals(opt)) {
12379                dumpDalvik = true;
12380            } else if ("-c".equals(opt)) {
12381                isCompact = true;
12382            } else if ("--oom".equals(opt)) {
12383                oomOnly = true;
12384            } else if ("--local".equals(opt)) {
12385                localOnly = true;
12386            } else if ("-h".equals(opt)) {
12387                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12388                pw.println("  -a: include all available information for each process.");
12389                pw.println("  -d: include dalvik details when dumping process details.");
12390                pw.println("  -c: dump in a compact machine-parseable representation.");
12391                pw.println("  --oom: only show processes organized by oom adj.");
12392                pw.println("  --local: only collect details locally, don't call process.");
12393                pw.println("If [process] is specified it can be the name or ");
12394                pw.println("pid of a specific process to dump.");
12395                return;
12396            } else {
12397                pw.println("Unknown argument: " + opt + "; use -h for help");
12398            }
12399        }
12400
12401        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12402        long uptime = SystemClock.uptimeMillis();
12403        long realtime = SystemClock.elapsedRealtime();
12404        final long[] tmpLong = new long[1];
12405
12406        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12407        if (procs == null) {
12408            // No Java processes.  Maybe they want to print a native process.
12409            if (args != null && args.length > opti
12410                    && args[opti].charAt(0) != '-') {
12411                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12412                        = new ArrayList<ProcessCpuTracker.Stats>();
12413                updateCpuStatsNow();
12414                int findPid = -1;
12415                try {
12416                    findPid = Integer.parseInt(args[opti]);
12417                } catch (NumberFormatException e) {
12418                }
12419                synchronized (mProcessCpuThread) {
12420                    final int N = mProcessCpuTracker.countStats();
12421                    for (int i=0; i<N; i++) {
12422                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12423                        if (st.pid == findPid || (st.baseName != null
12424                                && st.baseName.equals(args[opti]))) {
12425                            nativeProcs.add(st);
12426                        }
12427                    }
12428                }
12429                if (nativeProcs.size() > 0) {
12430                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12431                            isCompact);
12432                    Debug.MemoryInfo mi = null;
12433                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12434                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12435                        final int pid = r.pid;
12436                        if (!isCheckinRequest && dumpDetails) {
12437                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12438                        }
12439                        if (mi == null) {
12440                            mi = new Debug.MemoryInfo();
12441                        }
12442                        if (dumpDetails || (!brief && !oomOnly)) {
12443                            Debug.getMemoryInfo(pid, mi);
12444                        } else {
12445                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12446                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12447                        }
12448                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12449                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12450                        if (isCheckinRequest) {
12451                            pw.println();
12452                        }
12453                    }
12454                    return;
12455                }
12456            }
12457            pw.println("No process found for: " + args[opti]);
12458            return;
12459        }
12460
12461        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12462            dumpDetails = true;
12463        }
12464
12465        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12466
12467        String[] innerArgs = new String[args.length-opti];
12468        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12469
12470        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12471        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12472        long nativePss=0, dalvikPss=0, otherPss=0;
12473        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12474
12475        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12476        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12477                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12478
12479        long totalPss = 0;
12480        long cachedPss = 0;
12481
12482        Debug.MemoryInfo mi = null;
12483        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12484            final ProcessRecord r = procs.get(i);
12485            final IApplicationThread thread;
12486            final int pid;
12487            final int oomAdj;
12488            final boolean hasActivities;
12489            synchronized (this) {
12490                thread = r.thread;
12491                pid = r.pid;
12492                oomAdj = r.getSetAdjWithServices();
12493                hasActivities = r.activities.size() > 0;
12494            }
12495            if (thread != null) {
12496                if (!isCheckinRequest && dumpDetails) {
12497                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12498                }
12499                if (mi == null) {
12500                    mi = new Debug.MemoryInfo();
12501                }
12502                if (dumpDetails || (!brief && !oomOnly)) {
12503                    Debug.getMemoryInfo(pid, mi);
12504                } else {
12505                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12506                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12507                }
12508                if (dumpDetails) {
12509                    if (localOnly) {
12510                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12511                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12512                        if (isCheckinRequest) {
12513                            pw.println();
12514                        }
12515                    } else {
12516                        try {
12517                            pw.flush();
12518                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12519                                    dumpDalvik, innerArgs);
12520                        } catch (RemoteException e) {
12521                            if (!isCheckinRequest) {
12522                                pw.println("Got RemoteException!");
12523                                pw.flush();
12524                            }
12525                        }
12526                    }
12527                }
12528
12529                final long myTotalPss = mi.getTotalPss();
12530                final long myTotalUss = mi.getTotalUss();
12531
12532                synchronized (this) {
12533                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12534                        // Record this for posterity if the process has been stable.
12535                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12536                    }
12537                }
12538
12539                if (!isCheckinRequest && mi != null) {
12540                    totalPss += myTotalPss;
12541                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12542                            (hasActivities ? " / activities)" : ")"),
12543                            r.processName, myTotalPss, pid, hasActivities);
12544                    procMems.add(pssItem);
12545                    procMemsMap.put(pid, pssItem);
12546
12547                    nativePss += mi.nativePss;
12548                    dalvikPss += mi.dalvikPss;
12549                    otherPss += mi.otherPss;
12550                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12551                        long mem = mi.getOtherPss(j);
12552                        miscPss[j] += mem;
12553                        otherPss -= mem;
12554                    }
12555
12556                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12557                        cachedPss += myTotalPss;
12558                    }
12559
12560                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12561                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12562                                || oomIndex == (oomPss.length-1)) {
12563                            oomPss[oomIndex] += myTotalPss;
12564                            if (oomProcs[oomIndex] == null) {
12565                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12566                            }
12567                            oomProcs[oomIndex].add(pssItem);
12568                            break;
12569                        }
12570                    }
12571                }
12572            }
12573        }
12574
12575        if (!isCheckinRequest && procs.size() > 1) {
12576            // If we are showing aggregations, also look for native processes to
12577            // include so that our aggregations are more accurate.
12578            updateCpuStatsNow();
12579            synchronized (mProcessCpuThread) {
12580                final int N = mProcessCpuTracker.countStats();
12581                for (int i=0; i<N; i++) {
12582                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12583                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12584                        if (mi == null) {
12585                            mi = new Debug.MemoryInfo();
12586                        }
12587                        if (!brief && !oomOnly) {
12588                            Debug.getMemoryInfo(st.pid, mi);
12589                        } else {
12590                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12591                            mi.nativePrivateDirty = (int)tmpLong[0];
12592                        }
12593
12594                        final long myTotalPss = mi.getTotalPss();
12595                        totalPss += myTotalPss;
12596
12597                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12598                                st.name, myTotalPss, st.pid, false);
12599                        procMems.add(pssItem);
12600
12601                        nativePss += mi.nativePss;
12602                        dalvikPss += mi.dalvikPss;
12603                        otherPss += mi.otherPss;
12604                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12605                            long mem = mi.getOtherPss(j);
12606                            miscPss[j] += mem;
12607                            otherPss -= mem;
12608                        }
12609                        oomPss[0] += myTotalPss;
12610                        if (oomProcs[0] == null) {
12611                            oomProcs[0] = new ArrayList<MemItem>();
12612                        }
12613                        oomProcs[0].add(pssItem);
12614                    }
12615                }
12616            }
12617
12618            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12619
12620            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12621            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12622            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12623            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12624                String label = Debug.MemoryInfo.getOtherLabel(j);
12625                catMems.add(new MemItem(label, label, miscPss[j], j));
12626            }
12627
12628            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12629            for (int j=0; j<oomPss.length; j++) {
12630                if (oomPss[j] != 0) {
12631                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12632                            : DUMP_MEM_OOM_LABEL[j];
12633                    MemItem item = new MemItem(label, label, oomPss[j],
12634                            DUMP_MEM_OOM_ADJ[j]);
12635                    item.subitems = oomProcs[j];
12636                    oomMems.add(item);
12637                }
12638            }
12639
12640            if (!brief && !oomOnly && !isCompact) {
12641                pw.println();
12642                pw.println("Total PSS by process:");
12643                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12644                pw.println();
12645            }
12646            if (!isCompact) {
12647                pw.println("Total PSS by OOM adjustment:");
12648            }
12649            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12650            if (!brief && !oomOnly) {
12651                PrintWriter out = categoryPw != null ? categoryPw : pw;
12652                if (!isCompact) {
12653                    out.println();
12654                    out.println("Total PSS by category:");
12655                }
12656                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12657            }
12658            if (!isCompact) {
12659                pw.println();
12660            }
12661            MemInfoReader memInfo = new MemInfoReader();
12662            memInfo.readMemInfo();
12663            if (!brief) {
12664                if (!isCompact) {
12665                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12666                    pw.print(" kB (status ");
12667                    switch (mLastMemoryLevel) {
12668                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12669                            pw.println("normal)");
12670                            break;
12671                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12672                            pw.println("moderate)");
12673                            break;
12674                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12675                            pw.println("low)");
12676                            break;
12677                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12678                            pw.println("critical)");
12679                            break;
12680                        default:
12681                            pw.print(mLastMemoryLevel);
12682                            pw.println(")");
12683                            break;
12684                    }
12685                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12686                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12687                            pw.print(cachedPss); pw.print(" cached pss + ");
12688                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12689                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12690                } else {
12691                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12692                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12693                            + memInfo.getFreeSizeKb()); pw.print(",");
12694                    pw.println(totalPss - cachedPss);
12695                }
12696            }
12697            if (!isCompact) {
12698                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12699                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12700                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12701                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12702                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12703                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12704                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12705                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12706                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12707                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12708                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12709            }
12710            if (!brief) {
12711                if (memInfo.getZramTotalSizeKb() != 0) {
12712                    if (!isCompact) {
12713                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12714                                pw.print(" kB physical used for ");
12715                                pw.print(memInfo.getSwapTotalSizeKb()
12716                                        - memInfo.getSwapFreeSizeKb());
12717                                pw.print(" kB in swap (");
12718                                pw.print(memInfo.getSwapTotalSizeKb());
12719                                pw.println(" kB total swap)");
12720                    } else {
12721                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12722                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12723                                pw.println(memInfo.getSwapFreeSizeKb());
12724                    }
12725                }
12726                final int[] SINGLE_LONG_FORMAT = new int[] {
12727                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12728                };
12729                long[] longOut = new long[1];
12730                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12731                        SINGLE_LONG_FORMAT, null, longOut, null);
12732                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12733                longOut[0] = 0;
12734                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12735                        SINGLE_LONG_FORMAT, null, longOut, null);
12736                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12737                longOut[0] = 0;
12738                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12739                        SINGLE_LONG_FORMAT, null, longOut, null);
12740                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12741                longOut[0] = 0;
12742                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12743                        SINGLE_LONG_FORMAT, null, longOut, null);
12744                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12745                if (!isCompact) {
12746                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12747                        pw.print("      KSM: "); pw.print(sharing);
12748                                pw.print(" kB saved from shared ");
12749                                pw.print(shared); pw.println(" kB");
12750                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12751                                pw.print(voltile); pw.println(" kB volatile");
12752                    }
12753                    pw.print("   Tuning: ");
12754                    pw.print(ActivityManager.staticGetMemoryClass());
12755                    pw.print(" (large ");
12756                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12757                    pw.print("), oom ");
12758                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12759                    pw.print(" kB");
12760                    pw.print(", restore limit ");
12761                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12762                    pw.print(" kB");
12763                    if (ActivityManager.isLowRamDeviceStatic()) {
12764                        pw.print(" (low-ram)");
12765                    }
12766                    if (ActivityManager.isHighEndGfx()) {
12767                        pw.print(" (high-end-gfx)");
12768                    }
12769                    pw.println();
12770                } else {
12771                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12772                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12773                    pw.println(voltile);
12774                    pw.print("tuning,");
12775                    pw.print(ActivityManager.staticGetMemoryClass());
12776                    pw.print(',');
12777                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12778                    pw.print(',');
12779                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12780                    if (ActivityManager.isLowRamDeviceStatic()) {
12781                        pw.print(",low-ram");
12782                    }
12783                    if (ActivityManager.isHighEndGfx()) {
12784                        pw.print(",high-end-gfx");
12785                    }
12786                    pw.println();
12787                }
12788            }
12789        }
12790    }
12791
12792    /**
12793     * Searches array of arguments for the specified string
12794     * @param args array of argument strings
12795     * @param value value to search for
12796     * @return true if the value is contained in the array
12797     */
12798    private static boolean scanArgs(String[] args, String value) {
12799        if (args != null) {
12800            for (String arg : args) {
12801                if (value.equals(arg)) {
12802                    return true;
12803                }
12804            }
12805        }
12806        return false;
12807    }
12808
12809    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12810            ContentProviderRecord cpr, boolean always) {
12811        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12812
12813        if (!inLaunching || always) {
12814            synchronized (cpr) {
12815                cpr.launchingApp = null;
12816                cpr.notifyAll();
12817            }
12818            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12819            String names[] = cpr.info.authority.split(";");
12820            for (int j = 0; j < names.length; j++) {
12821                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12822            }
12823        }
12824
12825        for (int i=0; i<cpr.connections.size(); i++) {
12826            ContentProviderConnection conn = cpr.connections.get(i);
12827            if (conn.waiting) {
12828                // If this connection is waiting for the provider, then we don't
12829                // need to mess with its process unless we are always removing
12830                // or for some reason the provider is not currently launching.
12831                if (inLaunching && !always) {
12832                    continue;
12833                }
12834            }
12835            ProcessRecord capp = conn.client;
12836            conn.dead = true;
12837            if (conn.stableCount > 0) {
12838                if (!capp.persistent && capp.thread != null
12839                        && capp.pid != 0
12840                        && capp.pid != MY_PID) {
12841                    killUnneededProcessLocked(capp, "depends on provider "
12842                            + cpr.name.flattenToShortString()
12843                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12844                }
12845            } else if (capp.thread != null && conn.provider.provider != null) {
12846                try {
12847                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12848                } catch (RemoteException e) {
12849                }
12850                // In the protocol here, we don't expect the client to correctly
12851                // clean up this connection, we'll just remove it.
12852                cpr.connections.remove(i);
12853                conn.client.conProviders.remove(conn);
12854            }
12855        }
12856
12857        if (inLaunching && always) {
12858            mLaunchingProviders.remove(cpr);
12859        }
12860        return inLaunching;
12861    }
12862
12863    /**
12864     * Main code for cleaning up a process when it has gone away.  This is
12865     * called both as a result of the process dying, or directly when stopping
12866     * a process when running in single process mode.
12867     */
12868    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12869            boolean restarting, boolean allowRestart, int index) {
12870        if (index >= 0) {
12871            removeLruProcessLocked(app);
12872            ProcessList.remove(app.pid);
12873        }
12874
12875        mProcessesToGc.remove(app);
12876        mPendingPssProcesses.remove(app);
12877
12878        // Dismiss any open dialogs.
12879        if (app.crashDialog != null && !app.forceCrashReport) {
12880            app.crashDialog.dismiss();
12881            app.crashDialog = null;
12882        }
12883        if (app.anrDialog != null) {
12884            app.anrDialog.dismiss();
12885            app.anrDialog = null;
12886        }
12887        if (app.waitDialog != null) {
12888            app.waitDialog.dismiss();
12889            app.waitDialog = null;
12890        }
12891
12892        app.crashing = false;
12893        app.notResponding = false;
12894
12895        app.resetPackageList(mProcessStats);
12896        app.unlinkDeathRecipient();
12897        app.makeInactive(mProcessStats);
12898        app.forcingToForeground = null;
12899        updateProcessForegroundLocked(app, false, false);
12900        app.foregroundActivities = false;
12901        app.hasShownUi = false;
12902        app.treatLikeActivity = false;
12903        app.hasAboveClient = false;
12904        app.hasClientActivities = false;
12905
12906        mServices.killServicesLocked(app, allowRestart);
12907
12908        boolean restart = false;
12909
12910        // Remove published content providers.
12911        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12912            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12913            final boolean always = app.bad || !allowRestart;
12914            if (removeDyingProviderLocked(app, cpr, always) || always) {
12915                // We left the provider in the launching list, need to
12916                // restart it.
12917                restart = true;
12918            }
12919
12920            cpr.provider = null;
12921            cpr.proc = null;
12922        }
12923        app.pubProviders.clear();
12924
12925        // Take care of any launching providers waiting for this process.
12926        if (checkAppInLaunchingProvidersLocked(app, false)) {
12927            restart = true;
12928        }
12929
12930        // Unregister from connected content providers.
12931        if (!app.conProviders.isEmpty()) {
12932            for (int i=0; i<app.conProviders.size(); i++) {
12933                ContentProviderConnection conn = app.conProviders.get(i);
12934                conn.provider.connections.remove(conn);
12935            }
12936            app.conProviders.clear();
12937        }
12938
12939        // At this point there may be remaining entries in mLaunchingProviders
12940        // where we were the only one waiting, so they are no longer of use.
12941        // Look for these and clean up if found.
12942        // XXX Commented out for now.  Trying to figure out a way to reproduce
12943        // the actual situation to identify what is actually going on.
12944        if (false) {
12945            for (int i=0; i<mLaunchingProviders.size(); i++) {
12946                ContentProviderRecord cpr = (ContentProviderRecord)
12947                        mLaunchingProviders.get(i);
12948                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12949                    synchronized (cpr) {
12950                        cpr.launchingApp = null;
12951                        cpr.notifyAll();
12952                    }
12953                }
12954            }
12955        }
12956
12957        skipCurrentReceiverLocked(app);
12958
12959        // Unregister any receivers.
12960        for (int i=app.receivers.size()-1; i>=0; i--) {
12961            removeReceiverLocked(app.receivers.valueAt(i));
12962        }
12963        app.receivers.clear();
12964
12965        // If the app is undergoing backup, tell the backup manager about it
12966        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12967            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12968                    + mBackupTarget.appInfo + " died during backup");
12969            try {
12970                IBackupManager bm = IBackupManager.Stub.asInterface(
12971                        ServiceManager.getService(Context.BACKUP_SERVICE));
12972                bm.agentDisconnected(app.info.packageName);
12973            } catch (RemoteException e) {
12974                // can't happen; backup manager is local
12975            }
12976        }
12977
12978        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12979            ProcessChangeItem item = mPendingProcessChanges.get(i);
12980            if (item.pid == app.pid) {
12981                mPendingProcessChanges.remove(i);
12982                mAvailProcessChanges.add(item);
12983            }
12984        }
12985        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12986
12987        // If the caller is restarting this app, then leave it in its
12988        // current lists and let the caller take care of it.
12989        if (restarting) {
12990            return;
12991        }
12992
12993        if (!app.persistent || app.isolated) {
12994            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12995                    "Removing non-persistent process during cleanup: " + app);
12996            mProcessNames.remove(app.processName, app.uid);
12997            mIsolatedProcesses.remove(app.uid);
12998            if (mHeavyWeightProcess == app) {
12999                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13000                        mHeavyWeightProcess.userId, 0));
13001                mHeavyWeightProcess = null;
13002            }
13003        } else if (!app.removed) {
13004            // This app is persistent, so we need to keep its record around.
13005            // If it is not already on the pending app list, add it there
13006            // and start a new process for it.
13007            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13008                mPersistentStartingProcesses.add(app);
13009                restart = true;
13010            }
13011        }
13012        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13013                "Clean-up removing on hold: " + app);
13014        mProcessesOnHold.remove(app);
13015
13016        if (app == mHomeProcess) {
13017            mHomeProcess = null;
13018        }
13019        if (app == mPreviousProcess) {
13020            mPreviousProcess = null;
13021        }
13022
13023        if (restart && !app.isolated) {
13024            // We have components that still need to be running in the
13025            // process, so re-launch it.
13026            mProcessNames.put(app.processName, app.uid, app);
13027            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13028        } else if (app.pid > 0 && app.pid != MY_PID) {
13029            // Goodbye!
13030            boolean removed;
13031            synchronized (mPidsSelfLocked) {
13032                mPidsSelfLocked.remove(app.pid);
13033                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13034            }
13035            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13036                    app.processName, app.info.uid);
13037            if (app.isolated) {
13038                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13039            }
13040            app.setPid(0);
13041        }
13042    }
13043
13044    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13045        // Look through the content providers we are waiting to have launched,
13046        // and if any run in this process then either schedule a restart of
13047        // the process or kill the client waiting for it if this process has
13048        // gone bad.
13049        int NL = mLaunchingProviders.size();
13050        boolean restart = false;
13051        for (int i=0; i<NL; i++) {
13052            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13053            if (cpr.launchingApp == app) {
13054                if (!alwaysBad && !app.bad) {
13055                    restart = true;
13056                } else {
13057                    removeDyingProviderLocked(app, cpr, true);
13058                    // cpr should have been removed from mLaunchingProviders
13059                    NL = mLaunchingProviders.size();
13060                    i--;
13061                }
13062            }
13063        }
13064        return restart;
13065    }
13066
13067    // =========================================================
13068    // SERVICES
13069    // =========================================================
13070
13071    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13072            int flags) {
13073        enforceNotIsolatedCaller("getServices");
13074        synchronized (this) {
13075            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13076        }
13077    }
13078
13079    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13080        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13081        synchronized (this) {
13082            return mServices.getRunningServiceControlPanelLocked(name);
13083        }
13084    }
13085
13086    public ComponentName startService(IApplicationThread caller, Intent service,
13087            String resolvedType, int userId) {
13088        enforceNotIsolatedCaller("startService");
13089        // Refuse possible leaked file descriptors
13090        if (service != null && service.hasFileDescriptors() == true) {
13091            throw new IllegalArgumentException("File descriptors passed in Intent");
13092        }
13093
13094        if (DEBUG_SERVICE)
13095            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13096        synchronized(this) {
13097            final int callingPid = Binder.getCallingPid();
13098            final int callingUid = Binder.getCallingUid();
13099            final long origId = Binder.clearCallingIdentity();
13100            ComponentName res = mServices.startServiceLocked(caller, service,
13101                    resolvedType, callingPid, callingUid, userId);
13102            Binder.restoreCallingIdentity(origId);
13103            return res;
13104        }
13105    }
13106
13107    ComponentName startServiceInPackage(int uid,
13108            Intent service, String resolvedType, int userId) {
13109        synchronized(this) {
13110            if (DEBUG_SERVICE)
13111                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13112            final long origId = Binder.clearCallingIdentity();
13113            ComponentName res = mServices.startServiceLocked(null, service,
13114                    resolvedType, -1, uid, userId);
13115            Binder.restoreCallingIdentity(origId);
13116            return res;
13117        }
13118    }
13119
13120    public int stopService(IApplicationThread caller, Intent service,
13121            String resolvedType, int userId) {
13122        enforceNotIsolatedCaller("stopService");
13123        // Refuse possible leaked file descriptors
13124        if (service != null && service.hasFileDescriptors() == true) {
13125            throw new IllegalArgumentException("File descriptors passed in Intent");
13126        }
13127
13128        synchronized(this) {
13129            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13130        }
13131    }
13132
13133    public IBinder peekService(Intent service, String resolvedType) {
13134        enforceNotIsolatedCaller("peekService");
13135        // Refuse possible leaked file descriptors
13136        if (service != null && service.hasFileDescriptors() == true) {
13137            throw new IllegalArgumentException("File descriptors passed in Intent");
13138        }
13139        synchronized(this) {
13140            return mServices.peekServiceLocked(service, resolvedType);
13141        }
13142    }
13143
13144    public boolean stopServiceToken(ComponentName className, IBinder token,
13145            int startId) {
13146        synchronized(this) {
13147            return mServices.stopServiceTokenLocked(className, token, startId);
13148        }
13149    }
13150
13151    public void setServiceForeground(ComponentName className, IBinder token,
13152            int id, Notification notification, boolean removeNotification) {
13153        synchronized(this) {
13154            mServices.setServiceForegroundLocked(className, token, id, notification,
13155                    removeNotification);
13156        }
13157    }
13158
13159    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13160            boolean requireFull, String name, String callerPackage) {
13161        final int callingUserId = UserHandle.getUserId(callingUid);
13162        if (callingUserId != userId) {
13163            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13164                if ((requireFull || checkComponentPermission(
13165                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13166                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13167                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13168                                callingPid, callingUid, -1, true)
13169                                != PackageManager.PERMISSION_GRANTED) {
13170                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13171                        // In this case, they would like to just execute as their
13172                        // owner user instead of failing.
13173                        userId = callingUserId;
13174                    } else {
13175                        StringBuilder builder = new StringBuilder(128);
13176                        builder.append("Permission Denial: ");
13177                        builder.append(name);
13178                        if (callerPackage != null) {
13179                            builder.append(" from ");
13180                            builder.append(callerPackage);
13181                        }
13182                        builder.append(" asks to run as user ");
13183                        builder.append(userId);
13184                        builder.append(" but is calling from user ");
13185                        builder.append(UserHandle.getUserId(callingUid));
13186                        builder.append("; this requires ");
13187                        builder.append(INTERACT_ACROSS_USERS_FULL);
13188                        if (!requireFull) {
13189                            builder.append(" or ");
13190                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13191                        }
13192                        String msg = builder.toString();
13193                        Slog.w(TAG, msg);
13194                        throw new SecurityException(msg);
13195                    }
13196                }
13197            }
13198            if (userId == UserHandle.USER_CURRENT
13199                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13200                // Note that we may be accessing this outside of a lock...
13201                // shouldn't be a big deal, if this is being called outside
13202                // of a locked context there is intrinsically a race with
13203                // the value the caller will receive and someone else changing it.
13204                userId = mCurrentUserId;
13205            }
13206            if (!allowAll && userId < 0) {
13207                throw new IllegalArgumentException(
13208                        "Call does not support special user #" + userId);
13209            }
13210        }
13211        return userId;
13212    }
13213
13214    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13215            String className, int flags) {
13216        boolean result = false;
13217        // For apps that don't have pre-defined UIDs, check for permission
13218        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13219            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13220                if (ActivityManager.checkUidPermission(
13221                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13222                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13223                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13224                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13225                            + " requests FLAG_SINGLE_USER, but app does not hold "
13226                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13227                    Slog.w(TAG, msg);
13228                    throw new SecurityException(msg);
13229                }
13230                // Permission passed
13231                result = true;
13232            }
13233        } else if ("system".equals(componentProcessName)) {
13234            result = true;
13235        } else {
13236            // App with pre-defined UID, check if it's a persistent app
13237            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13238        }
13239        if (DEBUG_MU) {
13240            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13241                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13242        }
13243        return result;
13244    }
13245
13246    /**
13247     * Checks to see if the caller is in the same app as the singleton
13248     * component, or the component is in a special app. It allows special apps
13249     * to export singleton components but prevents exporting singleton
13250     * components for regular apps.
13251     */
13252    boolean isValidSingletonCall(int callingUid, int componentUid) {
13253        int componentAppId = UserHandle.getAppId(componentUid);
13254        return UserHandle.isSameApp(callingUid, componentUid)
13255                || componentAppId == Process.SYSTEM_UID
13256                || componentAppId == Process.PHONE_UID
13257                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13258                        == PackageManager.PERMISSION_GRANTED;
13259    }
13260
13261    public int bindService(IApplicationThread caller, IBinder token,
13262            Intent service, String resolvedType,
13263            IServiceConnection connection, int flags, int userId) {
13264        enforceNotIsolatedCaller("bindService");
13265        // Refuse possible leaked file descriptors
13266        if (service != null && service.hasFileDescriptors() == true) {
13267            throw new IllegalArgumentException("File descriptors passed in Intent");
13268        }
13269
13270        synchronized(this) {
13271            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13272                    connection, flags, userId);
13273        }
13274    }
13275
13276    public boolean unbindService(IServiceConnection connection) {
13277        synchronized (this) {
13278            return mServices.unbindServiceLocked(connection);
13279        }
13280    }
13281
13282    public void publishService(IBinder token, Intent intent, IBinder service) {
13283        // Refuse possible leaked file descriptors
13284        if (intent != null && intent.hasFileDescriptors() == true) {
13285            throw new IllegalArgumentException("File descriptors passed in Intent");
13286        }
13287
13288        synchronized(this) {
13289            if (!(token instanceof ServiceRecord)) {
13290                throw new IllegalArgumentException("Invalid service token");
13291            }
13292            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13293        }
13294    }
13295
13296    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13297        // Refuse possible leaked file descriptors
13298        if (intent != null && intent.hasFileDescriptors() == true) {
13299            throw new IllegalArgumentException("File descriptors passed in Intent");
13300        }
13301
13302        synchronized(this) {
13303            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13304        }
13305    }
13306
13307    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13308        synchronized(this) {
13309            if (!(token instanceof ServiceRecord)) {
13310                throw new IllegalArgumentException("Invalid service token");
13311            }
13312            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13313        }
13314    }
13315
13316    // =========================================================
13317    // BACKUP AND RESTORE
13318    // =========================================================
13319
13320    // Cause the target app to be launched if necessary and its backup agent
13321    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13322    // activity manager to announce its creation.
13323    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13324        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13325        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13326
13327        synchronized(this) {
13328            // !!! TODO: currently no check here that we're already bound
13329            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13330            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13331            synchronized (stats) {
13332                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13333            }
13334
13335            // Backup agent is now in use, its package can't be stopped.
13336            try {
13337                AppGlobals.getPackageManager().setPackageStoppedState(
13338                        app.packageName, false, UserHandle.getUserId(app.uid));
13339            } catch (RemoteException e) {
13340            } catch (IllegalArgumentException e) {
13341                Slog.w(TAG, "Failed trying to unstop package "
13342                        + app.packageName + ": " + e);
13343            }
13344
13345            BackupRecord r = new BackupRecord(ss, app, backupMode);
13346            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13347                    ? new ComponentName(app.packageName, app.backupAgentName)
13348                    : new ComponentName("android", "FullBackupAgent");
13349            // startProcessLocked() returns existing proc's record if it's already running
13350            ProcessRecord proc = startProcessLocked(app.processName, app,
13351                    false, 0, "backup", hostingName, false, false, false);
13352            if (proc == null) {
13353                Slog.e(TAG, "Unable to start backup agent process " + r);
13354                return false;
13355            }
13356
13357            r.app = proc;
13358            mBackupTarget = r;
13359            mBackupAppName = app.packageName;
13360
13361            // Try not to kill the process during backup
13362            updateOomAdjLocked(proc);
13363
13364            // If the process is already attached, schedule the creation of the backup agent now.
13365            // If it is not yet live, this will be done when it attaches to the framework.
13366            if (proc.thread != null) {
13367                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13368                try {
13369                    proc.thread.scheduleCreateBackupAgent(app,
13370                            compatibilityInfoForPackageLocked(app), backupMode);
13371                } catch (RemoteException e) {
13372                    // Will time out on the backup manager side
13373                }
13374            } else {
13375                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13376            }
13377            // Invariants: at this point, the target app process exists and the application
13378            // is either already running or in the process of coming up.  mBackupTarget and
13379            // mBackupAppName describe the app, so that when it binds back to the AM we
13380            // know that it's scheduled for a backup-agent operation.
13381        }
13382
13383        return true;
13384    }
13385
13386    @Override
13387    public void clearPendingBackup() {
13388        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13389        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13390
13391        synchronized (this) {
13392            mBackupTarget = null;
13393            mBackupAppName = null;
13394        }
13395    }
13396
13397    // A backup agent has just come up
13398    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13399        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13400                + " = " + agent);
13401
13402        synchronized(this) {
13403            if (!agentPackageName.equals(mBackupAppName)) {
13404                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13405                return;
13406            }
13407        }
13408
13409        long oldIdent = Binder.clearCallingIdentity();
13410        try {
13411            IBackupManager bm = IBackupManager.Stub.asInterface(
13412                    ServiceManager.getService(Context.BACKUP_SERVICE));
13413            bm.agentConnected(agentPackageName, agent);
13414        } catch (RemoteException e) {
13415            // can't happen; the backup manager service is local
13416        } catch (Exception e) {
13417            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13418            e.printStackTrace();
13419        } finally {
13420            Binder.restoreCallingIdentity(oldIdent);
13421        }
13422    }
13423
13424    // done with this agent
13425    public void unbindBackupAgent(ApplicationInfo appInfo) {
13426        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13427        if (appInfo == null) {
13428            Slog.w(TAG, "unbind backup agent for null app");
13429            return;
13430        }
13431
13432        synchronized(this) {
13433            try {
13434                if (mBackupAppName == null) {
13435                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13436                    return;
13437                }
13438
13439                if (!mBackupAppName.equals(appInfo.packageName)) {
13440                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13441                    return;
13442                }
13443
13444                // Not backing this app up any more; reset its OOM adjustment
13445                final ProcessRecord proc = mBackupTarget.app;
13446                updateOomAdjLocked(proc);
13447
13448                // If the app crashed during backup, 'thread' will be null here
13449                if (proc.thread != null) {
13450                    try {
13451                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13452                                compatibilityInfoForPackageLocked(appInfo));
13453                    } catch (Exception e) {
13454                        Slog.e(TAG, "Exception when unbinding backup agent:");
13455                        e.printStackTrace();
13456                    }
13457                }
13458            } finally {
13459                mBackupTarget = null;
13460                mBackupAppName = null;
13461            }
13462        }
13463    }
13464    // =========================================================
13465    // BROADCASTS
13466    // =========================================================
13467
13468    private final List getStickiesLocked(String action, IntentFilter filter,
13469            List cur, int userId) {
13470        final ContentResolver resolver = mContext.getContentResolver();
13471        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13472        if (stickies == null) {
13473            return cur;
13474        }
13475        final ArrayList<Intent> list = stickies.get(action);
13476        if (list == null) {
13477            return cur;
13478        }
13479        int N = list.size();
13480        for (int i=0; i<N; i++) {
13481            Intent intent = list.get(i);
13482            if (filter.match(resolver, intent, true, TAG) >= 0) {
13483                if (cur == null) {
13484                    cur = new ArrayList<Intent>();
13485                }
13486                cur.add(intent);
13487            }
13488        }
13489        return cur;
13490    }
13491
13492    boolean isPendingBroadcastProcessLocked(int pid) {
13493        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13494                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13495    }
13496
13497    void skipPendingBroadcastLocked(int pid) {
13498            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13499            for (BroadcastQueue queue : mBroadcastQueues) {
13500                queue.skipPendingBroadcastLocked(pid);
13501            }
13502    }
13503
13504    // The app just attached; send any pending broadcasts that it should receive
13505    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13506        boolean didSomething = false;
13507        for (BroadcastQueue queue : mBroadcastQueues) {
13508            didSomething |= queue.sendPendingBroadcastsLocked(app);
13509        }
13510        return didSomething;
13511    }
13512
13513    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13514            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13515        enforceNotIsolatedCaller("registerReceiver");
13516        int callingUid;
13517        int callingPid;
13518        synchronized(this) {
13519            ProcessRecord callerApp = null;
13520            if (caller != null) {
13521                callerApp = getRecordForAppLocked(caller);
13522                if (callerApp == null) {
13523                    throw new SecurityException(
13524                            "Unable to find app for caller " + caller
13525                            + " (pid=" + Binder.getCallingPid()
13526                            + ") when registering receiver " + receiver);
13527                }
13528                if (callerApp.info.uid != Process.SYSTEM_UID &&
13529                        !callerApp.pkgList.containsKey(callerPackage) &&
13530                        !"android".equals(callerPackage)) {
13531                    throw new SecurityException("Given caller package " + callerPackage
13532                            + " is not running in process " + callerApp);
13533                }
13534                callingUid = callerApp.info.uid;
13535                callingPid = callerApp.pid;
13536            } else {
13537                callerPackage = null;
13538                callingUid = Binder.getCallingUid();
13539                callingPid = Binder.getCallingPid();
13540            }
13541
13542            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13543                    true, true, "registerReceiver", callerPackage);
13544
13545            List allSticky = null;
13546
13547            // Look for any matching sticky broadcasts...
13548            Iterator actions = filter.actionsIterator();
13549            if (actions != null) {
13550                while (actions.hasNext()) {
13551                    String action = (String)actions.next();
13552                    allSticky = getStickiesLocked(action, filter, allSticky,
13553                            UserHandle.USER_ALL);
13554                    allSticky = getStickiesLocked(action, filter, allSticky,
13555                            UserHandle.getUserId(callingUid));
13556                }
13557            } else {
13558                allSticky = getStickiesLocked(null, filter, allSticky,
13559                        UserHandle.USER_ALL);
13560                allSticky = getStickiesLocked(null, filter, allSticky,
13561                        UserHandle.getUserId(callingUid));
13562            }
13563
13564            // The first sticky in the list is returned directly back to
13565            // the client.
13566            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13567
13568            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13569                    + ": " + sticky);
13570
13571            if (receiver == null) {
13572                return sticky;
13573            }
13574
13575            ReceiverList rl
13576                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13577            if (rl == null) {
13578                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13579                        userId, receiver);
13580                if (rl.app != null) {
13581                    rl.app.receivers.add(rl);
13582                } else {
13583                    try {
13584                        receiver.asBinder().linkToDeath(rl, 0);
13585                    } catch (RemoteException e) {
13586                        return sticky;
13587                    }
13588                    rl.linkedToDeath = true;
13589                }
13590                mRegisteredReceivers.put(receiver.asBinder(), rl);
13591            } else if (rl.uid != callingUid) {
13592                throw new IllegalArgumentException(
13593                        "Receiver requested to register for uid " + callingUid
13594                        + " was previously registered for uid " + rl.uid);
13595            } else if (rl.pid != callingPid) {
13596                throw new IllegalArgumentException(
13597                        "Receiver requested to register for pid " + callingPid
13598                        + " was previously registered for pid " + rl.pid);
13599            } else if (rl.userId != userId) {
13600                throw new IllegalArgumentException(
13601                        "Receiver requested to register for user " + userId
13602                        + " was previously registered for user " + rl.userId);
13603            }
13604            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13605                    permission, callingUid, userId);
13606            rl.add(bf);
13607            if (!bf.debugCheck()) {
13608                Slog.w(TAG, "==> For Dynamic broadast");
13609            }
13610            mReceiverResolver.addFilter(bf);
13611
13612            // Enqueue broadcasts for all existing stickies that match
13613            // this filter.
13614            if (allSticky != null) {
13615                ArrayList receivers = new ArrayList();
13616                receivers.add(bf);
13617
13618                int N = allSticky.size();
13619                for (int i=0; i<N; i++) {
13620                    Intent intent = (Intent)allSticky.get(i);
13621                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13622                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13623                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13624                            null, null, false, true, true, -1);
13625                    queue.enqueueParallelBroadcastLocked(r);
13626                    queue.scheduleBroadcastsLocked();
13627                }
13628            }
13629
13630            return sticky;
13631        }
13632    }
13633
13634    public void unregisterReceiver(IIntentReceiver receiver) {
13635        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13636
13637        final long origId = Binder.clearCallingIdentity();
13638        try {
13639            boolean doTrim = false;
13640
13641            synchronized(this) {
13642                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13643                if (rl != null) {
13644                    if (rl.curBroadcast != null) {
13645                        BroadcastRecord r = rl.curBroadcast;
13646                        final boolean doNext = finishReceiverLocked(
13647                                receiver.asBinder(), r.resultCode, r.resultData,
13648                                r.resultExtras, r.resultAbort);
13649                        if (doNext) {
13650                            doTrim = true;
13651                            r.queue.processNextBroadcast(false);
13652                        }
13653                    }
13654
13655                    if (rl.app != null) {
13656                        rl.app.receivers.remove(rl);
13657                    }
13658                    removeReceiverLocked(rl);
13659                    if (rl.linkedToDeath) {
13660                        rl.linkedToDeath = false;
13661                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13662                    }
13663                }
13664            }
13665
13666            // If we actually concluded any broadcasts, we might now be able
13667            // to trim the recipients' apps from our working set
13668            if (doTrim) {
13669                trimApplications();
13670                return;
13671            }
13672
13673        } finally {
13674            Binder.restoreCallingIdentity(origId);
13675        }
13676    }
13677
13678    void removeReceiverLocked(ReceiverList rl) {
13679        mRegisteredReceivers.remove(rl.receiver.asBinder());
13680        int N = rl.size();
13681        for (int i=0; i<N; i++) {
13682            mReceiverResolver.removeFilter(rl.get(i));
13683        }
13684    }
13685
13686    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13687        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13688            ProcessRecord r = mLruProcesses.get(i);
13689            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13690                try {
13691                    r.thread.dispatchPackageBroadcast(cmd, packages);
13692                } catch (RemoteException ex) {
13693                }
13694            }
13695        }
13696    }
13697
13698    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13699            int[] users) {
13700        List<ResolveInfo> receivers = null;
13701        try {
13702            HashSet<ComponentName> singleUserReceivers = null;
13703            boolean scannedFirstReceivers = false;
13704            for (int user : users) {
13705                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13706                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13707                if (user != 0 && newReceivers != null) {
13708                    // If this is not the primary user, we need to check for
13709                    // any receivers that should be filtered out.
13710                    for (int i=0; i<newReceivers.size(); i++) {
13711                        ResolveInfo ri = newReceivers.get(i);
13712                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13713                            newReceivers.remove(i);
13714                            i--;
13715                        }
13716                    }
13717                }
13718                if (newReceivers != null && newReceivers.size() == 0) {
13719                    newReceivers = null;
13720                }
13721                if (receivers == null) {
13722                    receivers = newReceivers;
13723                } else if (newReceivers != null) {
13724                    // We need to concatenate the additional receivers
13725                    // found with what we have do far.  This would be easy,
13726                    // but we also need to de-dup any receivers that are
13727                    // singleUser.
13728                    if (!scannedFirstReceivers) {
13729                        // Collect any single user receivers we had already retrieved.
13730                        scannedFirstReceivers = true;
13731                        for (int i=0; i<receivers.size(); i++) {
13732                            ResolveInfo ri = receivers.get(i);
13733                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13734                                ComponentName cn = new ComponentName(
13735                                        ri.activityInfo.packageName, ri.activityInfo.name);
13736                                if (singleUserReceivers == null) {
13737                                    singleUserReceivers = new HashSet<ComponentName>();
13738                                }
13739                                singleUserReceivers.add(cn);
13740                            }
13741                        }
13742                    }
13743                    // Add the new results to the existing results, tracking
13744                    // and de-dupping single user receivers.
13745                    for (int i=0; i<newReceivers.size(); i++) {
13746                        ResolveInfo ri = newReceivers.get(i);
13747                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13748                            ComponentName cn = new ComponentName(
13749                                    ri.activityInfo.packageName, ri.activityInfo.name);
13750                            if (singleUserReceivers == null) {
13751                                singleUserReceivers = new HashSet<ComponentName>();
13752                            }
13753                            if (!singleUserReceivers.contains(cn)) {
13754                                singleUserReceivers.add(cn);
13755                                receivers.add(ri);
13756                            }
13757                        } else {
13758                            receivers.add(ri);
13759                        }
13760                    }
13761                }
13762            }
13763        } catch (RemoteException ex) {
13764            // pm is in same process, this will never happen.
13765        }
13766        return receivers;
13767    }
13768
13769    private final int broadcastIntentLocked(ProcessRecord callerApp,
13770            String callerPackage, Intent intent, String resolvedType,
13771            IIntentReceiver resultTo, int resultCode, String resultData,
13772            Bundle map, String requiredPermission, int appOp,
13773            boolean ordered, boolean sticky, int callingPid, int callingUid,
13774            int userId) {
13775        intent = new Intent(intent);
13776
13777        // By default broadcasts do not go to stopped apps.
13778        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13779
13780        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13781            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13782            + " ordered=" + ordered + " userid=" + userId);
13783        if ((resultTo != null) && !ordered) {
13784            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13785        }
13786
13787        userId = handleIncomingUser(callingPid, callingUid, userId,
13788                true, false, "broadcast", callerPackage);
13789
13790        // Make sure that the user who is receiving this broadcast is started.
13791        // If not, we will just skip it.
13792        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13793            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13794                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13795                Slog.w(TAG, "Skipping broadcast of " + intent
13796                        + ": user " + userId + " is stopped");
13797                return ActivityManager.BROADCAST_SUCCESS;
13798            }
13799        }
13800
13801        /*
13802         * Prevent non-system code (defined here to be non-persistent
13803         * processes) from sending protected broadcasts.
13804         */
13805        int callingAppId = UserHandle.getAppId(callingUid);
13806        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13807                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13808                || callingUid == 0) {
13809            // Always okay.
13810        } else if (callerApp == null || !callerApp.persistent) {
13811            try {
13812                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13813                        intent.getAction())) {
13814                    String msg = "Permission Denial: not allowed to send broadcast "
13815                            + intent.getAction() + " from pid="
13816                            + callingPid + ", uid=" + callingUid;
13817                    Slog.w(TAG, msg);
13818                    throw new SecurityException(msg);
13819                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13820                    // Special case for compatibility: we don't want apps to send this,
13821                    // but historically it has not been protected and apps may be using it
13822                    // to poke their own app widget.  So, instead of making it protected,
13823                    // just limit it to the caller.
13824                    if (callerApp == null) {
13825                        String msg = "Permission Denial: not allowed to send broadcast "
13826                                + intent.getAction() + " from unknown caller.";
13827                        Slog.w(TAG, msg);
13828                        throw new SecurityException(msg);
13829                    } else if (intent.getComponent() != null) {
13830                        // They are good enough to send to an explicit component...  verify
13831                        // it is being sent to the calling app.
13832                        if (!intent.getComponent().getPackageName().equals(
13833                                callerApp.info.packageName)) {
13834                            String msg = "Permission Denial: not allowed to send broadcast "
13835                                    + intent.getAction() + " to "
13836                                    + intent.getComponent().getPackageName() + " from "
13837                                    + callerApp.info.packageName;
13838                            Slog.w(TAG, msg);
13839                            throw new SecurityException(msg);
13840                        }
13841                    } else {
13842                        // Limit broadcast to their own package.
13843                        intent.setPackage(callerApp.info.packageName);
13844                    }
13845                }
13846            } catch (RemoteException e) {
13847                Slog.w(TAG, "Remote exception", e);
13848                return ActivityManager.BROADCAST_SUCCESS;
13849            }
13850        }
13851
13852        // Handle special intents: if this broadcast is from the package
13853        // manager about a package being removed, we need to remove all of
13854        // its activities from the history stack.
13855        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13856                intent.getAction());
13857        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13858                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13859                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13860                || uidRemoved) {
13861            if (checkComponentPermission(
13862                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13863                    callingPid, callingUid, -1, true)
13864                    == PackageManager.PERMISSION_GRANTED) {
13865                if (uidRemoved) {
13866                    final Bundle intentExtras = intent.getExtras();
13867                    final int uid = intentExtras != null
13868                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13869                    if (uid >= 0) {
13870                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13871                        synchronized (bs) {
13872                            bs.removeUidStatsLocked(uid);
13873                        }
13874                        mAppOpsService.uidRemoved(uid);
13875                    }
13876                } else {
13877                    // If resources are unavailable just force stop all
13878                    // those packages and flush the attribute cache as well.
13879                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13880                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13881                        if (list != null && (list.length > 0)) {
13882                            for (String pkg : list) {
13883                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13884                                        "storage unmount");
13885                            }
13886                            sendPackageBroadcastLocked(
13887                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13888                        }
13889                    } else {
13890                        Uri data = intent.getData();
13891                        String ssp;
13892                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13893                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13894                                    intent.getAction());
13895                            boolean fullUninstall = removed &&
13896                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13897                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13898                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13899                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13900                                        false, fullUninstall, userId,
13901                                        removed ? "pkg removed" : "pkg changed");
13902                            }
13903                            if (removed) {
13904                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13905                                        new String[] {ssp}, userId);
13906                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13907                                    mAppOpsService.packageRemoved(
13908                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13909
13910                                    // Remove all permissions granted from/to this package
13911                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13912                                }
13913                            }
13914                        }
13915                    }
13916                }
13917            } else {
13918                String msg = "Permission Denial: " + intent.getAction()
13919                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13920                        + ", uid=" + callingUid + ")"
13921                        + " requires "
13922                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13923                Slog.w(TAG, msg);
13924                throw new SecurityException(msg);
13925            }
13926
13927        // Special case for adding a package: by default turn on compatibility
13928        // mode.
13929        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13930            Uri data = intent.getData();
13931            String ssp;
13932            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13933                mCompatModePackages.handlePackageAddedLocked(ssp,
13934                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13935            }
13936        }
13937
13938        /*
13939         * If this is the time zone changed action, queue up a message that will reset the timezone
13940         * of all currently running processes. This message will get queued up before the broadcast
13941         * happens.
13942         */
13943        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13944            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13945        }
13946
13947        /*
13948         * If the user set the time, let all running processes know.
13949         */
13950        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13951            final int is24Hour = intent.getBooleanExtra(
13952                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13953            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13954        }
13955
13956        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13957            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13958        }
13959
13960        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13961            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13962            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13963        }
13964
13965        // Add to the sticky list if requested.
13966        if (sticky) {
13967            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13968                    callingPid, callingUid)
13969                    != PackageManager.PERMISSION_GRANTED) {
13970                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13971                        + callingPid + ", uid=" + callingUid
13972                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13973                Slog.w(TAG, msg);
13974                throw new SecurityException(msg);
13975            }
13976            if (requiredPermission != null) {
13977                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13978                        + " and enforce permission " + requiredPermission);
13979                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13980            }
13981            if (intent.getComponent() != null) {
13982                throw new SecurityException(
13983                        "Sticky broadcasts can't target a specific component");
13984            }
13985            // We use userId directly here, since the "all" target is maintained
13986            // as a separate set of sticky broadcasts.
13987            if (userId != UserHandle.USER_ALL) {
13988                // But first, if this is not a broadcast to all users, then
13989                // make sure it doesn't conflict with an existing broadcast to
13990                // all users.
13991                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13992                        UserHandle.USER_ALL);
13993                if (stickies != null) {
13994                    ArrayList<Intent> list = stickies.get(intent.getAction());
13995                    if (list != null) {
13996                        int N = list.size();
13997                        int i;
13998                        for (i=0; i<N; i++) {
13999                            if (intent.filterEquals(list.get(i))) {
14000                                throw new IllegalArgumentException(
14001                                        "Sticky broadcast " + intent + " for user "
14002                                        + userId + " conflicts with existing global broadcast");
14003                            }
14004                        }
14005                    }
14006                }
14007            }
14008            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14009            if (stickies == null) {
14010                stickies = new ArrayMap<String, ArrayList<Intent>>();
14011                mStickyBroadcasts.put(userId, stickies);
14012            }
14013            ArrayList<Intent> list = stickies.get(intent.getAction());
14014            if (list == null) {
14015                list = new ArrayList<Intent>();
14016                stickies.put(intent.getAction(), list);
14017            }
14018            int N = list.size();
14019            int i;
14020            for (i=0; i<N; i++) {
14021                if (intent.filterEquals(list.get(i))) {
14022                    // This sticky already exists, replace it.
14023                    list.set(i, new Intent(intent));
14024                    break;
14025                }
14026            }
14027            if (i >= N) {
14028                list.add(new Intent(intent));
14029            }
14030        }
14031
14032        int[] users;
14033        if (userId == UserHandle.USER_ALL) {
14034            // Caller wants broadcast to go to all started users.
14035            users = mStartedUserArray;
14036        } else {
14037            // Caller wants broadcast to go to one specific user.
14038            users = new int[] {userId};
14039        }
14040
14041        // Figure out who all will receive this broadcast.
14042        List receivers = null;
14043        List<BroadcastFilter> registeredReceivers = null;
14044        // Need to resolve the intent to interested receivers...
14045        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14046                 == 0) {
14047            receivers = collectReceiverComponents(intent, resolvedType, users);
14048        }
14049        if (intent.getComponent() == null) {
14050            registeredReceivers = mReceiverResolver.queryIntent(intent,
14051                    resolvedType, false, userId);
14052        }
14053
14054        final boolean replacePending =
14055                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14056
14057        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14058                + " replacePending=" + replacePending);
14059
14060        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14061        if (!ordered && NR > 0) {
14062            // If we are not serializing this broadcast, then send the
14063            // registered receivers separately so they don't wait for the
14064            // components to be launched.
14065            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14066            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14067                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14068                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14069                    ordered, sticky, false, userId);
14070            if (DEBUG_BROADCAST) Slog.v(
14071                    TAG, "Enqueueing parallel broadcast " + r);
14072            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14073            if (!replaced) {
14074                queue.enqueueParallelBroadcastLocked(r);
14075                queue.scheduleBroadcastsLocked();
14076            }
14077            registeredReceivers = null;
14078            NR = 0;
14079        }
14080
14081        // Merge into one list.
14082        int ir = 0;
14083        if (receivers != null) {
14084            // A special case for PACKAGE_ADDED: do not allow the package
14085            // being added to see this broadcast.  This prevents them from
14086            // using this as a back door to get run as soon as they are
14087            // installed.  Maybe in the future we want to have a special install
14088            // broadcast or such for apps, but we'd like to deliberately make
14089            // this decision.
14090            String skipPackages[] = null;
14091            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14092                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14093                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14094                Uri data = intent.getData();
14095                if (data != null) {
14096                    String pkgName = data.getSchemeSpecificPart();
14097                    if (pkgName != null) {
14098                        skipPackages = new String[] { pkgName };
14099                    }
14100                }
14101            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14102                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14103            }
14104            if (skipPackages != null && (skipPackages.length > 0)) {
14105                for (String skipPackage : skipPackages) {
14106                    if (skipPackage != null) {
14107                        int NT = receivers.size();
14108                        for (int it=0; it<NT; it++) {
14109                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14110                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14111                                receivers.remove(it);
14112                                it--;
14113                                NT--;
14114                            }
14115                        }
14116                    }
14117                }
14118            }
14119
14120            int NT = receivers != null ? receivers.size() : 0;
14121            int it = 0;
14122            ResolveInfo curt = null;
14123            BroadcastFilter curr = null;
14124            while (it < NT && ir < NR) {
14125                if (curt == null) {
14126                    curt = (ResolveInfo)receivers.get(it);
14127                }
14128                if (curr == null) {
14129                    curr = registeredReceivers.get(ir);
14130                }
14131                if (curr.getPriority() >= curt.priority) {
14132                    // Insert this broadcast record into the final list.
14133                    receivers.add(it, curr);
14134                    ir++;
14135                    curr = null;
14136                    it++;
14137                    NT++;
14138                } else {
14139                    // Skip to the next ResolveInfo in the final list.
14140                    it++;
14141                    curt = null;
14142                }
14143            }
14144        }
14145        while (ir < NR) {
14146            if (receivers == null) {
14147                receivers = new ArrayList();
14148            }
14149            receivers.add(registeredReceivers.get(ir));
14150            ir++;
14151        }
14152
14153        if ((receivers != null && receivers.size() > 0)
14154                || resultTo != null) {
14155            BroadcastQueue queue = broadcastQueueForIntent(intent);
14156            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14157                    callerPackage, callingPid, callingUid, resolvedType,
14158                    requiredPermission, appOp, receivers, resultTo, resultCode,
14159                    resultData, map, ordered, sticky, false, userId);
14160            if (DEBUG_BROADCAST) Slog.v(
14161                    TAG, "Enqueueing ordered broadcast " + r
14162                    + ": prev had " + queue.mOrderedBroadcasts.size());
14163            if (DEBUG_BROADCAST) {
14164                int seq = r.intent.getIntExtra("seq", -1);
14165                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14166            }
14167            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14168            if (!replaced) {
14169                queue.enqueueOrderedBroadcastLocked(r);
14170                queue.scheduleBroadcastsLocked();
14171            }
14172        }
14173
14174        return ActivityManager.BROADCAST_SUCCESS;
14175    }
14176
14177    final Intent verifyBroadcastLocked(Intent intent) {
14178        // Refuse possible leaked file descriptors
14179        if (intent != null && intent.hasFileDescriptors() == true) {
14180            throw new IllegalArgumentException("File descriptors passed in Intent");
14181        }
14182
14183        int flags = intent.getFlags();
14184
14185        if (!mProcessesReady) {
14186            // if the caller really truly claims to know what they're doing, go
14187            // ahead and allow the broadcast without launching any receivers
14188            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14189                intent = new Intent(intent);
14190                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14191            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14192                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14193                        + " before boot completion");
14194                throw new IllegalStateException("Cannot broadcast before boot completed");
14195            }
14196        }
14197
14198        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14199            throw new IllegalArgumentException(
14200                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14201        }
14202
14203        return intent;
14204    }
14205
14206    public final int broadcastIntent(IApplicationThread caller,
14207            Intent intent, String resolvedType, IIntentReceiver resultTo,
14208            int resultCode, String resultData, Bundle map,
14209            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14210        enforceNotIsolatedCaller("broadcastIntent");
14211        synchronized(this) {
14212            intent = verifyBroadcastLocked(intent);
14213
14214            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14215            final int callingPid = Binder.getCallingPid();
14216            final int callingUid = Binder.getCallingUid();
14217            final long origId = Binder.clearCallingIdentity();
14218            int res = broadcastIntentLocked(callerApp,
14219                    callerApp != null ? callerApp.info.packageName : null,
14220                    intent, resolvedType, resultTo,
14221                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14222                    callingPid, callingUid, userId);
14223            Binder.restoreCallingIdentity(origId);
14224            return res;
14225        }
14226    }
14227
14228    int broadcastIntentInPackage(String packageName, int uid,
14229            Intent intent, String resolvedType, IIntentReceiver resultTo,
14230            int resultCode, String resultData, Bundle map,
14231            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14232        synchronized(this) {
14233            intent = verifyBroadcastLocked(intent);
14234
14235            final long origId = Binder.clearCallingIdentity();
14236            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14237                    resultTo, resultCode, resultData, map, requiredPermission,
14238                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14239            Binder.restoreCallingIdentity(origId);
14240            return res;
14241        }
14242    }
14243
14244    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14245        // Refuse possible leaked file descriptors
14246        if (intent != null && intent.hasFileDescriptors() == true) {
14247            throw new IllegalArgumentException("File descriptors passed in Intent");
14248        }
14249
14250        userId = handleIncomingUser(Binder.getCallingPid(),
14251                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14252
14253        synchronized(this) {
14254            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14255                    != PackageManager.PERMISSION_GRANTED) {
14256                String msg = "Permission Denial: unbroadcastIntent() from pid="
14257                        + Binder.getCallingPid()
14258                        + ", uid=" + Binder.getCallingUid()
14259                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14260                Slog.w(TAG, msg);
14261                throw new SecurityException(msg);
14262            }
14263            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14264            if (stickies != null) {
14265                ArrayList<Intent> list = stickies.get(intent.getAction());
14266                if (list != null) {
14267                    int N = list.size();
14268                    int i;
14269                    for (i=0; i<N; i++) {
14270                        if (intent.filterEquals(list.get(i))) {
14271                            list.remove(i);
14272                            break;
14273                        }
14274                    }
14275                    if (list.size() <= 0) {
14276                        stickies.remove(intent.getAction());
14277                    }
14278                }
14279                if (stickies.size() <= 0) {
14280                    mStickyBroadcasts.remove(userId);
14281                }
14282            }
14283        }
14284    }
14285
14286    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14287            String resultData, Bundle resultExtras, boolean resultAbort) {
14288        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14289        if (r == null) {
14290            Slog.w(TAG, "finishReceiver called but not found on queue");
14291            return false;
14292        }
14293
14294        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14295    }
14296
14297    void backgroundServicesFinishedLocked(int userId) {
14298        for (BroadcastQueue queue : mBroadcastQueues) {
14299            queue.backgroundServicesFinishedLocked(userId);
14300        }
14301    }
14302
14303    public void finishReceiver(IBinder who, int resultCode, String resultData,
14304            Bundle resultExtras, boolean resultAbort) {
14305        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14306
14307        // Refuse possible leaked file descriptors
14308        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14309            throw new IllegalArgumentException("File descriptors passed in Bundle");
14310        }
14311
14312        final long origId = Binder.clearCallingIdentity();
14313        try {
14314            boolean doNext = false;
14315            BroadcastRecord r;
14316
14317            synchronized(this) {
14318                r = broadcastRecordForReceiverLocked(who);
14319                if (r != null) {
14320                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14321                        resultData, resultExtras, resultAbort, true);
14322                }
14323            }
14324
14325            if (doNext) {
14326                r.queue.processNextBroadcast(false);
14327            }
14328            trimApplications();
14329        } finally {
14330            Binder.restoreCallingIdentity(origId);
14331        }
14332    }
14333
14334    // =========================================================
14335    // INSTRUMENTATION
14336    // =========================================================
14337
14338    public boolean startInstrumentation(ComponentName className,
14339            String profileFile, int flags, Bundle arguments,
14340            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14341            int userId, String abiOverride) {
14342        enforceNotIsolatedCaller("startInstrumentation");
14343        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14344                userId, false, true, "startInstrumentation", null);
14345        // Refuse possible leaked file descriptors
14346        if (arguments != null && arguments.hasFileDescriptors()) {
14347            throw new IllegalArgumentException("File descriptors passed in Bundle");
14348        }
14349
14350        synchronized(this) {
14351            InstrumentationInfo ii = null;
14352            ApplicationInfo ai = null;
14353            try {
14354                ii = mContext.getPackageManager().getInstrumentationInfo(
14355                    className, STOCK_PM_FLAGS);
14356                ai = AppGlobals.getPackageManager().getApplicationInfo(
14357                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14358            } catch (PackageManager.NameNotFoundException e) {
14359            } catch (RemoteException e) {
14360            }
14361            if (ii == null) {
14362                reportStartInstrumentationFailure(watcher, className,
14363                        "Unable to find instrumentation info for: " + className);
14364                return false;
14365            }
14366            if (ai == null) {
14367                reportStartInstrumentationFailure(watcher, className,
14368                        "Unable to find instrumentation target package: " + ii.targetPackage);
14369                return false;
14370            }
14371
14372            int match = mContext.getPackageManager().checkSignatures(
14373                    ii.targetPackage, ii.packageName);
14374            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14375                String msg = "Permission Denial: starting instrumentation "
14376                        + className + " from pid="
14377                        + Binder.getCallingPid()
14378                        + ", uid=" + Binder.getCallingPid()
14379                        + " not allowed because package " + ii.packageName
14380                        + " does not have a signature matching the target "
14381                        + ii.targetPackage;
14382                reportStartInstrumentationFailure(watcher, className, msg);
14383                throw new SecurityException(msg);
14384            }
14385
14386            final long origId = Binder.clearCallingIdentity();
14387            // Instrumentation can kill and relaunch even persistent processes
14388            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14389                    "start instr");
14390            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14391            app.instrumentationClass = className;
14392            app.instrumentationInfo = ai;
14393            app.instrumentationProfileFile = profileFile;
14394            app.instrumentationArguments = arguments;
14395            app.instrumentationWatcher = watcher;
14396            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14397            app.instrumentationResultClass = className;
14398            Binder.restoreCallingIdentity(origId);
14399        }
14400
14401        return true;
14402    }
14403
14404    /**
14405     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14406     * error to the logs, but if somebody is watching, send the report there too.  This enables
14407     * the "am" command to report errors with more information.
14408     *
14409     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14410     * @param cn The component name of the instrumentation.
14411     * @param report The error report.
14412     */
14413    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14414            ComponentName cn, String report) {
14415        Slog.w(TAG, report);
14416        try {
14417            if (watcher != null) {
14418                Bundle results = new Bundle();
14419                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14420                results.putString("Error", report);
14421                watcher.instrumentationStatus(cn, -1, results);
14422            }
14423        } catch (RemoteException e) {
14424            Slog.w(TAG, e);
14425        }
14426    }
14427
14428    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14429        if (app.instrumentationWatcher != null) {
14430            try {
14431                // NOTE:  IInstrumentationWatcher *must* be oneway here
14432                app.instrumentationWatcher.instrumentationFinished(
14433                    app.instrumentationClass,
14434                    resultCode,
14435                    results);
14436            } catch (RemoteException e) {
14437            }
14438        }
14439        if (app.instrumentationUiAutomationConnection != null) {
14440            try {
14441                app.instrumentationUiAutomationConnection.shutdown();
14442            } catch (RemoteException re) {
14443                /* ignore */
14444            }
14445            // Only a UiAutomation can set this flag and now that
14446            // it is finished we make sure it is reset to its default.
14447            mUserIsMonkey = false;
14448        }
14449        app.instrumentationWatcher = null;
14450        app.instrumentationUiAutomationConnection = null;
14451        app.instrumentationClass = null;
14452        app.instrumentationInfo = null;
14453        app.instrumentationProfileFile = null;
14454        app.instrumentationArguments = null;
14455
14456        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14457                "finished inst");
14458    }
14459
14460    public void finishInstrumentation(IApplicationThread target,
14461            int resultCode, Bundle results) {
14462        int userId = UserHandle.getCallingUserId();
14463        // Refuse possible leaked file descriptors
14464        if (results != null && results.hasFileDescriptors()) {
14465            throw new IllegalArgumentException("File descriptors passed in Intent");
14466        }
14467
14468        synchronized(this) {
14469            ProcessRecord app = getRecordForAppLocked(target);
14470            if (app == null) {
14471                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14472                return;
14473            }
14474            final long origId = Binder.clearCallingIdentity();
14475            finishInstrumentationLocked(app, resultCode, results);
14476            Binder.restoreCallingIdentity(origId);
14477        }
14478    }
14479
14480    // =========================================================
14481    // CONFIGURATION
14482    // =========================================================
14483
14484    public ConfigurationInfo getDeviceConfigurationInfo() {
14485        ConfigurationInfo config = new ConfigurationInfo();
14486        synchronized (this) {
14487            config.reqTouchScreen = mConfiguration.touchscreen;
14488            config.reqKeyboardType = mConfiguration.keyboard;
14489            config.reqNavigation = mConfiguration.navigation;
14490            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14491                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14492                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14493            }
14494            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14495                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14496                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14497            }
14498            config.reqGlEsVersion = GL_ES_VERSION;
14499        }
14500        return config;
14501    }
14502
14503    ActivityStack getFocusedStack() {
14504        return mStackSupervisor.getFocusedStack();
14505    }
14506
14507    public Configuration getConfiguration() {
14508        Configuration ci;
14509        synchronized(this) {
14510            ci = new Configuration(mConfiguration);
14511        }
14512        return ci;
14513    }
14514
14515    public void updatePersistentConfiguration(Configuration values) {
14516        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14517                "updateConfiguration()");
14518        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14519                "updateConfiguration()");
14520        if (values == null) {
14521            throw new NullPointerException("Configuration must not be null");
14522        }
14523
14524        synchronized(this) {
14525            final long origId = Binder.clearCallingIdentity();
14526            updateConfigurationLocked(values, null, true, false);
14527            Binder.restoreCallingIdentity(origId);
14528        }
14529    }
14530
14531    public void updateConfiguration(Configuration values) {
14532        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14533                "updateConfiguration()");
14534
14535        synchronized(this) {
14536            if (values == null && mWindowManager != null) {
14537                // sentinel: fetch the current configuration from the window manager
14538                values = mWindowManager.computeNewConfiguration();
14539            }
14540
14541            if (mWindowManager != null) {
14542                mProcessList.applyDisplaySize(mWindowManager);
14543            }
14544
14545            final long origId = Binder.clearCallingIdentity();
14546            if (values != null) {
14547                Settings.System.clearConfiguration(values);
14548            }
14549            updateConfigurationLocked(values, null, false, false);
14550            Binder.restoreCallingIdentity(origId);
14551        }
14552    }
14553
14554    /**
14555     * Do either or both things: (1) change the current configuration, and (2)
14556     * make sure the given activity is running with the (now) current
14557     * configuration.  Returns true if the activity has been left running, or
14558     * false if <var>starting</var> is being destroyed to match the new
14559     * configuration.
14560     * @param persistent TODO
14561     */
14562    boolean updateConfigurationLocked(Configuration values,
14563            ActivityRecord starting, boolean persistent, boolean initLocale) {
14564        int changes = 0;
14565
14566        if (values != null) {
14567            Configuration newConfig = new Configuration(mConfiguration);
14568            changes = newConfig.updateFrom(values);
14569            if (changes != 0) {
14570                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14571                    Slog.i(TAG, "Updating configuration to: " + values);
14572                }
14573
14574                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14575
14576                if (values.locale != null && !initLocale) {
14577                    saveLocaleLocked(values.locale,
14578                                     !values.locale.equals(mConfiguration.locale),
14579                                     values.userSetLocale);
14580                }
14581
14582                mConfigurationSeq++;
14583                if (mConfigurationSeq <= 0) {
14584                    mConfigurationSeq = 1;
14585                }
14586                newConfig.seq = mConfigurationSeq;
14587                mConfiguration = newConfig;
14588                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14589                mUsageStatsService.noteStartConfig(newConfig);
14590
14591                final Configuration configCopy = new Configuration(mConfiguration);
14592
14593                // TODO: If our config changes, should we auto dismiss any currently
14594                // showing dialogs?
14595                mShowDialogs = shouldShowDialogs(newConfig);
14596
14597                AttributeCache ac = AttributeCache.instance();
14598                if (ac != null) {
14599                    ac.updateConfiguration(configCopy);
14600                }
14601
14602                // Make sure all resources in our process are updated
14603                // right now, so that anyone who is going to retrieve
14604                // resource values after we return will be sure to get
14605                // the new ones.  This is especially important during
14606                // boot, where the first config change needs to guarantee
14607                // all resources have that config before following boot
14608                // code is executed.
14609                mSystemThread.applyConfigurationToResources(configCopy);
14610
14611                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14612                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14613                    msg.obj = new Configuration(configCopy);
14614                    mHandler.sendMessage(msg);
14615                }
14616
14617                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14618                    ProcessRecord app = mLruProcesses.get(i);
14619                    try {
14620                        if (app.thread != null) {
14621                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14622                                    + app.processName + " new config " + mConfiguration);
14623                            app.thread.scheduleConfigurationChanged(configCopy);
14624                        }
14625                    } catch (Exception e) {
14626                    }
14627                }
14628                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14629                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14630                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14631                        | Intent.FLAG_RECEIVER_FOREGROUND);
14632                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14633                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14634                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14635                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14636                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14637                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14638                    broadcastIntentLocked(null, null, intent,
14639                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14640                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14641                }
14642            }
14643        }
14644
14645        boolean kept = true;
14646        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14647        // mainStack is null during startup.
14648        if (mainStack != null) {
14649            if (changes != 0 && starting == null) {
14650                // If the configuration changed, and the caller is not already
14651                // in the process of starting an activity, then find the top
14652                // activity to check if its configuration needs to change.
14653                starting = mainStack.topRunningActivityLocked(null);
14654            }
14655
14656            if (starting != null) {
14657                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14658                // And we need to make sure at this point that all other activities
14659                // are made visible with the correct configuration.
14660                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14661            }
14662        }
14663
14664        if (values != null && mWindowManager != null) {
14665            mWindowManager.setNewConfiguration(mConfiguration);
14666        }
14667
14668        return kept;
14669    }
14670
14671    /**
14672     * Decide based on the configuration whether we should shouw the ANR,
14673     * crash, etc dialogs.  The idea is that if there is no affordnace to
14674     * press the on-screen buttons, we shouldn't show the dialog.
14675     *
14676     * A thought: SystemUI might also want to get told about this, the Power
14677     * dialog / global actions also might want different behaviors.
14678     */
14679    private static final boolean shouldShowDialogs(Configuration config) {
14680        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14681                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14682    }
14683
14684    /**
14685     * Save the locale.  You must be inside a synchronized (this) block.
14686     */
14687    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14688        if(isDiff) {
14689            SystemProperties.set("user.language", l.getLanguage());
14690            SystemProperties.set("user.region", l.getCountry());
14691        }
14692
14693        if(isPersist) {
14694            SystemProperties.set("persist.sys.language", l.getLanguage());
14695            SystemProperties.set("persist.sys.country", l.getCountry());
14696            SystemProperties.set("persist.sys.localevar", l.getVariant());
14697        }
14698    }
14699
14700    @Override
14701    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14702        ActivityRecord srec = ActivityRecord.forToken(token);
14703        return srec != null && srec.task.affinity != null &&
14704                srec.task.affinity.equals(destAffinity);
14705    }
14706
14707    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14708            Intent resultData) {
14709
14710        synchronized (this) {
14711            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14712            if (stack != null) {
14713                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14714            }
14715            return false;
14716        }
14717    }
14718
14719    public int getLaunchedFromUid(IBinder activityToken) {
14720        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14721        if (srec == null) {
14722            return -1;
14723        }
14724        return srec.launchedFromUid;
14725    }
14726
14727    public String getLaunchedFromPackage(IBinder activityToken) {
14728        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14729        if (srec == null) {
14730            return null;
14731        }
14732        return srec.launchedFromPackage;
14733    }
14734
14735    // =========================================================
14736    // LIFETIME MANAGEMENT
14737    // =========================================================
14738
14739    // Returns which broadcast queue the app is the current [or imminent] receiver
14740    // on, or 'null' if the app is not an active broadcast recipient.
14741    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14742        BroadcastRecord r = app.curReceiver;
14743        if (r != null) {
14744            return r.queue;
14745        }
14746
14747        // It's not the current receiver, but it might be starting up to become one
14748        synchronized (this) {
14749            for (BroadcastQueue queue : mBroadcastQueues) {
14750                r = queue.mPendingBroadcast;
14751                if (r != null && r.curApp == app) {
14752                    // found it; report which queue it's in
14753                    return queue;
14754                }
14755            }
14756        }
14757
14758        return null;
14759    }
14760
14761    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14762            boolean doingAll, long now) {
14763        if (mAdjSeq == app.adjSeq) {
14764            // This adjustment has already been computed.
14765            return app.curRawAdj;
14766        }
14767
14768        if (app.thread == null) {
14769            app.adjSeq = mAdjSeq;
14770            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14771            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14772            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14773        }
14774
14775        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14776        app.adjSource = null;
14777        app.adjTarget = null;
14778        app.empty = false;
14779        app.cached = false;
14780
14781        final int activitiesSize = app.activities.size();
14782
14783        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14784            // The max adjustment doesn't allow this app to be anything
14785            // below foreground, so it is not worth doing work for it.
14786            app.adjType = "fixed";
14787            app.adjSeq = mAdjSeq;
14788            app.curRawAdj = app.maxAdj;
14789            app.foregroundActivities = false;
14790            app.keeping = true;
14791            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14792            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14793            // System processes can do UI, and when they do we want to have
14794            // them trim their memory after the user leaves the UI.  To
14795            // facilitate this, here we need to determine whether or not it
14796            // is currently showing UI.
14797            app.systemNoUi = true;
14798            if (app == TOP_APP) {
14799                app.systemNoUi = false;
14800            } else if (activitiesSize > 0) {
14801                for (int j = 0; j < activitiesSize; j++) {
14802                    final ActivityRecord r = app.activities.get(j);
14803                    if (r.visible) {
14804                        app.systemNoUi = false;
14805                    }
14806                }
14807            }
14808            if (!app.systemNoUi) {
14809                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14810            }
14811            return (app.curAdj=app.maxAdj);
14812        }
14813
14814        app.keeping = false;
14815        app.systemNoUi = false;
14816
14817        // Determine the importance of the process, starting with most
14818        // important to least, and assign an appropriate OOM adjustment.
14819        int adj;
14820        int schedGroup;
14821        int procState;
14822        boolean foregroundActivities = false;
14823        boolean interesting = false;
14824        BroadcastQueue queue;
14825        if (app == TOP_APP) {
14826            // The last app on the list is the foreground app.
14827            adj = ProcessList.FOREGROUND_APP_ADJ;
14828            schedGroup = Process.THREAD_GROUP_DEFAULT;
14829            app.adjType = "top-activity";
14830            foregroundActivities = true;
14831            interesting = true;
14832            procState = ActivityManager.PROCESS_STATE_TOP;
14833        } else if (app.instrumentationClass != null) {
14834            // Don't want to kill running instrumentation.
14835            adj = ProcessList.FOREGROUND_APP_ADJ;
14836            schedGroup = Process.THREAD_GROUP_DEFAULT;
14837            app.adjType = "instrumentation";
14838            interesting = true;
14839            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14840        } else if ((queue = isReceivingBroadcast(app)) != null) {
14841            // An app that is currently receiving a broadcast also
14842            // counts as being in the foreground for OOM killer purposes.
14843            // It's placed in a sched group based on the nature of the
14844            // broadcast as reflected by which queue it's active in.
14845            adj = ProcessList.FOREGROUND_APP_ADJ;
14846            schedGroup = (queue == mFgBroadcastQueue)
14847                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14848            app.adjType = "broadcast";
14849            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14850        } else if (app.executingServices.size() > 0) {
14851            // An app that is currently executing a service callback also
14852            // counts as being in the foreground.
14853            adj = ProcessList.FOREGROUND_APP_ADJ;
14854            schedGroup = app.execServicesFg ?
14855                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14856            app.adjType = "exec-service";
14857            procState = ActivityManager.PROCESS_STATE_SERVICE;
14858            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14859        } else {
14860            // As far as we know the process is empty.  We may change our mind later.
14861            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14862            // At this point we don't actually know the adjustment.  Use the cached adj
14863            // value that the caller wants us to.
14864            adj = cachedAdj;
14865            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14866            app.cached = true;
14867            app.empty = true;
14868            app.adjType = "cch-empty";
14869        }
14870
14871        // Examine all activities if not already foreground.
14872        if (!foregroundActivities && activitiesSize > 0) {
14873            for (int j = 0; j < activitiesSize; j++) {
14874                final ActivityRecord r = app.activities.get(j);
14875                if (r.app != app) {
14876                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14877                            + app + "?!?");
14878                    continue;
14879                }
14880                if (r.visible) {
14881                    // App has a visible activity; only upgrade adjustment.
14882                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14883                        adj = ProcessList.VISIBLE_APP_ADJ;
14884                        app.adjType = "visible";
14885                    }
14886                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14887                        procState = ActivityManager.PROCESS_STATE_TOP;
14888                    }
14889                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14890                    app.cached = false;
14891                    app.empty = false;
14892                    foregroundActivities = true;
14893                    break;
14894                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14895                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14896                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14897                        app.adjType = "pausing";
14898                    }
14899                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14900                        procState = ActivityManager.PROCESS_STATE_TOP;
14901                    }
14902                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14903                    app.cached = false;
14904                    app.empty = false;
14905                    foregroundActivities = true;
14906                } else if (r.state == ActivityState.STOPPING) {
14907                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14908                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14909                        app.adjType = "stopping";
14910                    }
14911                    // For the process state, we will at this point consider the
14912                    // process to be cached.  It will be cached either as an activity
14913                    // or empty depending on whether the activity is finishing.  We do
14914                    // this so that we can treat the process as cached for purposes of
14915                    // memory trimming (determing current memory level, trim command to
14916                    // send to process) since there can be an arbitrary number of stopping
14917                    // processes and they should soon all go into the cached state.
14918                    if (!r.finishing) {
14919                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14920                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14921                        }
14922                    }
14923                    app.cached = false;
14924                    app.empty = false;
14925                    foregroundActivities = true;
14926                } else {
14927                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14928                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14929                        app.adjType = "cch-act";
14930                    }
14931                }
14932            }
14933        }
14934
14935        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14936            if (app.foregroundServices) {
14937                // The user is aware of this app, so make it visible.
14938                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14939                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14940                app.cached = false;
14941                app.adjType = "fg-service";
14942                schedGroup = Process.THREAD_GROUP_DEFAULT;
14943            } else if (app.forcingToForeground != null) {
14944                // The user is aware of this app, so make it visible.
14945                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14946                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14947                app.cached = false;
14948                app.adjType = "force-fg";
14949                app.adjSource = app.forcingToForeground;
14950                schedGroup = Process.THREAD_GROUP_DEFAULT;
14951            }
14952        }
14953
14954        if (app.foregroundServices) {
14955            interesting = true;
14956        }
14957
14958        if (app == mHeavyWeightProcess) {
14959            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14960                // We don't want to kill the current heavy-weight process.
14961                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14962                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14963                app.cached = false;
14964                app.adjType = "heavy";
14965            }
14966            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14967                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14968            }
14969        }
14970
14971        if (app == mHomeProcess) {
14972            if (adj > ProcessList.HOME_APP_ADJ) {
14973                // This process is hosting what we currently consider to be the
14974                // home app, so we don't want to let it go into the background.
14975                adj = ProcessList.HOME_APP_ADJ;
14976                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14977                app.cached = false;
14978                app.adjType = "home";
14979            }
14980            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14981                procState = ActivityManager.PROCESS_STATE_HOME;
14982            }
14983        }
14984
14985        if (app == mPreviousProcess && app.activities.size() > 0) {
14986            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14987                // This was the previous process that showed UI to the user.
14988                // We want to try to keep it around more aggressively, to give
14989                // a good experience around switching between two apps.
14990                adj = ProcessList.PREVIOUS_APP_ADJ;
14991                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14992                app.cached = false;
14993                app.adjType = "previous";
14994            }
14995            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14996                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14997            }
14998        }
14999
15000        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15001                + " reason=" + app.adjType);
15002
15003        // By default, we use the computed adjustment.  It may be changed if
15004        // there are applications dependent on our services or providers, but
15005        // this gives us a baseline and makes sure we don't get into an
15006        // infinite recursion.
15007        app.adjSeq = mAdjSeq;
15008        app.curRawAdj = adj;
15009        app.hasStartedServices = false;
15010
15011        if (mBackupTarget != null && app == mBackupTarget.app) {
15012            // If possible we want to avoid killing apps while they're being backed up
15013            if (adj > ProcessList.BACKUP_APP_ADJ) {
15014                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15015                adj = ProcessList.BACKUP_APP_ADJ;
15016                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15017                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15018                }
15019                app.adjType = "backup";
15020                app.cached = false;
15021            }
15022            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15023                procState = ActivityManager.PROCESS_STATE_BACKUP;
15024            }
15025        }
15026
15027        boolean mayBeTop = false;
15028
15029        for (int is = app.services.size()-1;
15030                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15031                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15032                        || procState > ActivityManager.PROCESS_STATE_TOP);
15033                is--) {
15034            ServiceRecord s = app.services.valueAt(is);
15035            if (s.startRequested) {
15036                app.hasStartedServices = true;
15037                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15038                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15039                }
15040                if (app.hasShownUi && app != mHomeProcess) {
15041                    // If this process has shown some UI, let it immediately
15042                    // go to the LRU list because it may be pretty heavy with
15043                    // UI stuff.  We'll tag it with a label just to help
15044                    // debug and understand what is going on.
15045                    if (adj > ProcessList.SERVICE_ADJ) {
15046                        app.adjType = "cch-started-ui-services";
15047                    }
15048                } else {
15049                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15050                        // This service has seen some activity within
15051                        // recent memory, so we will keep its process ahead
15052                        // of the background processes.
15053                        if (adj > ProcessList.SERVICE_ADJ) {
15054                            adj = ProcessList.SERVICE_ADJ;
15055                            app.adjType = "started-services";
15056                            app.cached = false;
15057                        }
15058                    }
15059                    // If we have let the service slide into the background
15060                    // state, still have some text describing what it is doing
15061                    // even though the service no longer has an impact.
15062                    if (adj > ProcessList.SERVICE_ADJ) {
15063                        app.adjType = "cch-started-services";
15064                    }
15065                }
15066                // Don't kill this process because it is doing work; it
15067                // has said it is doing work.
15068                app.keeping = true;
15069            }
15070            for (int conni = s.connections.size()-1;
15071                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15072                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15073                            || procState > ActivityManager.PROCESS_STATE_TOP);
15074                    conni--) {
15075                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15076                for (int i = 0;
15077                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15078                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15079                                || procState > ActivityManager.PROCESS_STATE_TOP);
15080                        i++) {
15081                    // XXX should compute this based on the max of
15082                    // all connected clients.
15083                    ConnectionRecord cr = clist.get(i);
15084                    if (cr.binding.client == app) {
15085                        // Binding to ourself is not interesting.
15086                        continue;
15087                    }
15088                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15089                        ProcessRecord client = cr.binding.client;
15090                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15091                                TOP_APP, doingAll, now);
15092                        int clientProcState = client.curProcState;
15093                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15094                            // If the other app is cached for any reason, for purposes here
15095                            // we are going to consider it empty.  The specific cached state
15096                            // doesn't propagate except under certain conditions.
15097                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15098                        }
15099                        String adjType = null;
15100                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15101                            // Not doing bind OOM management, so treat
15102                            // this guy more like a started service.
15103                            if (app.hasShownUi && app != mHomeProcess) {
15104                                // If this process has shown some UI, let it immediately
15105                                // go to the LRU list because it may be pretty heavy with
15106                                // UI stuff.  We'll tag it with a label just to help
15107                                // debug and understand what is going on.
15108                                if (adj > clientAdj) {
15109                                    adjType = "cch-bound-ui-services";
15110                                }
15111                                app.cached = false;
15112                                clientAdj = adj;
15113                                clientProcState = procState;
15114                            } else {
15115                                if (now >= (s.lastActivity
15116                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15117                                    // This service has not seen activity within
15118                                    // recent memory, so allow it to drop to the
15119                                    // LRU list if there is no other reason to keep
15120                                    // it around.  We'll also tag it with a label just
15121                                    // to help debug and undertand what is going on.
15122                                    if (adj > clientAdj) {
15123                                        adjType = "cch-bound-services";
15124                                    }
15125                                    clientAdj = adj;
15126                                }
15127                            }
15128                        }
15129                        if (adj > clientAdj) {
15130                            // If this process has recently shown UI, and
15131                            // the process that is binding to it is less
15132                            // important than being visible, then we don't
15133                            // care about the binding as much as we care
15134                            // about letting this process get into the LRU
15135                            // list to be killed and restarted if needed for
15136                            // memory.
15137                            if (app.hasShownUi && app != mHomeProcess
15138                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15139                                adjType = "cch-bound-ui-services";
15140                            } else {
15141                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15142                                        |Context.BIND_IMPORTANT)) != 0) {
15143                                    adj = clientAdj;
15144                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15145                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15146                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15147                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15148                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15149                                    adj = clientAdj;
15150                                } else {
15151                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15152                                        adj = ProcessList.VISIBLE_APP_ADJ;
15153                                    }
15154                                }
15155                                if (!client.cached) {
15156                                    app.cached = false;
15157                                }
15158                                if (client.keeping) {
15159                                    app.keeping = true;
15160                                }
15161                                adjType = "service";
15162                            }
15163                        }
15164                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15165                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15166                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15167                            }
15168                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15169                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15170                                    // Special handling of clients who are in the top state.
15171                                    // We *may* want to consider this process to be in the
15172                                    // top state as well, but only if there is not another
15173                                    // reason for it to be running.  Being on the top is a
15174                                    // special state, meaning you are specifically running
15175                                    // for the current top app.  If the process is already
15176                                    // running in the background for some other reason, it
15177                                    // is more important to continue considering it to be
15178                                    // in the background state.
15179                                    mayBeTop = true;
15180                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15181                                } else {
15182                                    // Special handling for above-top states (persistent
15183                                    // processes).  These should not bring the current process
15184                                    // into the top state, since they are not on top.  Instead
15185                                    // give them the best state after that.
15186                                    clientProcState =
15187                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15188                                }
15189                            }
15190                        } else {
15191                            if (clientProcState <
15192                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15193                                clientProcState =
15194                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15195                            }
15196                        }
15197                        if (procState > clientProcState) {
15198                            procState = clientProcState;
15199                        }
15200                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15201                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15202                            app.pendingUiClean = true;
15203                        }
15204                        if (adjType != null) {
15205                            app.adjType = adjType;
15206                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15207                                    .REASON_SERVICE_IN_USE;
15208                            app.adjSource = cr.binding.client;
15209                            app.adjSourceOom = clientAdj;
15210                            app.adjTarget = s.name;
15211                        }
15212                    }
15213                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15214                        app.treatLikeActivity = true;
15215                    }
15216                    final ActivityRecord a = cr.activity;
15217                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15218                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15219                                (a.visible || a.state == ActivityState.RESUMED
15220                                 || a.state == ActivityState.PAUSING)) {
15221                            adj = ProcessList.FOREGROUND_APP_ADJ;
15222                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15223                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15224                            }
15225                            app.cached = false;
15226                            app.adjType = "service";
15227                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15228                                    .REASON_SERVICE_IN_USE;
15229                            app.adjSource = a;
15230                            app.adjSourceOom = adj;
15231                            app.adjTarget = s.name;
15232                        }
15233                    }
15234                }
15235            }
15236        }
15237
15238        for (int provi = app.pubProviders.size()-1;
15239                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15240                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15241                        || procState > ActivityManager.PROCESS_STATE_TOP);
15242                provi--) {
15243            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15244            for (int i = cpr.connections.size()-1;
15245                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15246                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15247                            || procState > ActivityManager.PROCESS_STATE_TOP);
15248                    i--) {
15249                ContentProviderConnection conn = cpr.connections.get(i);
15250                ProcessRecord client = conn.client;
15251                if (client == app) {
15252                    // Being our own client is not interesting.
15253                    continue;
15254                }
15255                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15256                int clientProcState = client.curProcState;
15257                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15258                    // If the other app is cached for any reason, for purposes here
15259                    // we are going to consider it empty.
15260                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15261                }
15262                if (adj > clientAdj) {
15263                    if (app.hasShownUi && app != mHomeProcess
15264                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15265                        app.adjType = "cch-ui-provider";
15266                    } else {
15267                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15268                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15269                        app.adjType = "provider";
15270                    }
15271                    app.cached &= client.cached;
15272                    app.keeping |= client.keeping;
15273                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15274                            .REASON_PROVIDER_IN_USE;
15275                    app.adjSource = client;
15276                    app.adjSourceOom = clientAdj;
15277                    app.adjTarget = cpr.name;
15278                }
15279                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15280                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15281                        // Special handling of clients who are in the top state.
15282                        // We *may* want to consider this process to be in the
15283                        // top state as well, but only if there is not another
15284                        // reason for it to be running.  Being on the top is a
15285                        // special state, meaning you are specifically running
15286                        // for the current top app.  If the process is already
15287                        // running in the background for some other reason, it
15288                        // is more important to continue considering it to be
15289                        // in the background state.
15290                        mayBeTop = true;
15291                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15292                    } else {
15293                        // Special handling for above-top states (persistent
15294                        // processes).  These should not bring the current process
15295                        // into the top state, since they are not on top.  Instead
15296                        // give them the best state after that.
15297                        clientProcState =
15298                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15299                    }
15300                }
15301                if (procState > clientProcState) {
15302                    procState = clientProcState;
15303                }
15304                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15305                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15306                }
15307            }
15308            // If the provider has external (non-framework) process
15309            // dependencies, ensure that its adjustment is at least
15310            // FOREGROUND_APP_ADJ.
15311            if (cpr.hasExternalProcessHandles()) {
15312                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15313                    adj = ProcessList.FOREGROUND_APP_ADJ;
15314                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15315                    app.cached = false;
15316                    app.keeping = true;
15317                    app.adjType = "provider";
15318                    app.adjTarget = cpr.name;
15319                }
15320                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15321                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15322                }
15323            }
15324        }
15325
15326        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15327            // A client of one of our services or providers is in the top state.  We
15328            // *may* want to be in the top state, but not if we are already running in
15329            // the background for some other reason.  For the decision here, we are going
15330            // to pick out a few specific states that we want to remain in when a client
15331            // is top (states that tend to be longer-term) and otherwise allow it to go
15332            // to the top state.
15333            switch (procState) {
15334                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15335                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15336                case ActivityManager.PROCESS_STATE_SERVICE:
15337                    // These all are longer-term states, so pull them up to the top
15338                    // of the background states, but not all the way to the top state.
15339                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15340                    break;
15341                default:
15342                    // Otherwise, top is a better choice, so take it.
15343                    procState = ActivityManager.PROCESS_STATE_TOP;
15344                    break;
15345            }
15346        }
15347
15348        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15349            if (app.hasClientActivities) {
15350                // This is a cached process, but with client activities.  Mark it so.
15351                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15352                app.adjType = "cch-client-act";
15353            } else if (app.treatLikeActivity) {
15354                // This is a cached process, but somebody wants us to treat it like it has
15355                // an activity, okay!
15356                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15357                app.adjType = "cch-as-act";
15358            }
15359        }
15360
15361        if (adj == ProcessList.SERVICE_ADJ) {
15362            if (doingAll) {
15363                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15364                mNewNumServiceProcs++;
15365                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15366                if (!app.serviceb) {
15367                    // This service isn't far enough down on the LRU list to
15368                    // normally be a B service, but if we are low on RAM and it
15369                    // is large we want to force it down since we would prefer to
15370                    // keep launcher over it.
15371                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15372                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15373                        app.serviceHighRam = true;
15374                        app.serviceb = true;
15375                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15376                    } else {
15377                        mNewNumAServiceProcs++;
15378                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15379                    }
15380                } else {
15381                    app.serviceHighRam = false;
15382                }
15383            }
15384            if (app.serviceb) {
15385                adj = ProcessList.SERVICE_B_ADJ;
15386            }
15387        }
15388
15389        app.curRawAdj = adj;
15390
15391        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15392        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15393        if (adj > app.maxAdj) {
15394            adj = app.maxAdj;
15395            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15396                schedGroup = Process.THREAD_GROUP_DEFAULT;
15397            }
15398        }
15399        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15400            app.keeping = true;
15401        }
15402
15403        // Do final modification to adj.  Everything we do between here and applying
15404        // the final setAdj must be done in this function, because we will also use
15405        // it when computing the final cached adj later.  Note that we don't need to
15406        // worry about this for max adj above, since max adj will always be used to
15407        // keep it out of the cached vaues.
15408        app.curAdj = app.modifyRawOomAdj(adj);
15409        app.curSchedGroup = schedGroup;
15410        app.curProcState = procState;
15411        app.foregroundActivities = foregroundActivities;
15412
15413        return app.curRawAdj;
15414    }
15415
15416    /**
15417     * Schedule PSS collection of a process.
15418     */
15419    void requestPssLocked(ProcessRecord proc, int procState) {
15420        if (mPendingPssProcesses.contains(proc)) {
15421            return;
15422        }
15423        if (mPendingPssProcesses.size() == 0) {
15424            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15425        }
15426        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15427        proc.pssProcState = procState;
15428        mPendingPssProcesses.add(proc);
15429    }
15430
15431    /**
15432     * Schedule PSS collection of all processes.
15433     */
15434    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15435        if (!always) {
15436            if (now < (mLastFullPssTime +
15437                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15438                return;
15439            }
15440        }
15441        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15442        mLastFullPssTime = now;
15443        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15444        mPendingPssProcesses.clear();
15445        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15446            ProcessRecord app = mLruProcesses.get(i);
15447            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15448                app.pssProcState = app.setProcState;
15449                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15450                        isSleeping(), now);
15451                mPendingPssProcesses.add(app);
15452            }
15453        }
15454        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15455    }
15456
15457    /**
15458     * Ask a given process to GC right now.
15459     */
15460    final void performAppGcLocked(ProcessRecord app) {
15461        try {
15462            app.lastRequestedGc = SystemClock.uptimeMillis();
15463            if (app.thread != null) {
15464                if (app.reportLowMemory) {
15465                    app.reportLowMemory = false;
15466                    app.thread.scheduleLowMemory();
15467                } else {
15468                    app.thread.processInBackground();
15469                }
15470            }
15471        } catch (Exception e) {
15472            // whatever.
15473        }
15474    }
15475
15476    /**
15477     * Returns true if things are idle enough to perform GCs.
15478     */
15479    private final boolean canGcNowLocked() {
15480        boolean processingBroadcasts = false;
15481        for (BroadcastQueue q : mBroadcastQueues) {
15482            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15483                processingBroadcasts = true;
15484            }
15485        }
15486        return !processingBroadcasts
15487                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15488    }
15489
15490    /**
15491     * Perform GCs on all processes that are waiting for it, but only
15492     * if things are idle.
15493     */
15494    final void performAppGcsLocked() {
15495        final int N = mProcessesToGc.size();
15496        if (N <= 0) {
15497            return;
15498        }
15499        if (canGcNowLocked()) {
15500            while (mProcessesToGc.size() > 0) {
15501                ProcessRecord proc = mProcessesToGc.remove(0);
15502                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15503                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15504                            <= SystemClock.uptimeMillis()) {
15505                        // To avoid spamming the system, we will GC processes one
15506                        // at a time, waiting a few seconds between each.
15507                        performAppGcLocked(proc);
15508                        scheduleAppGcsLocked();
15509                        return;
15510                    } else {
15511                        // It hasn't been long enough since we last GCed this
15512                        // process...  put it in the list to wait for its time.
15513                        addProcessToGcListLocked(proc);
15514                        break;
15515                    }
15516                }
15517            }
15518
15519            scheduleAppGcsLocked();
15520        }
15521    }
15522
15523    /**
15524     * If all looks good, perform GCs on all processes waiting for them.
15525     */
15526    final void performAppGcsIfAppropriateLocked() {
15527        if (canGcNowLocked()) {
15528            performAppGcsLocked();
15529            return;
15530        }
15531        // Still not idle, wait some more.
15532        scheduleAppGcsLocked();
15533    }
15534
15535    /**
15536     * Schedule the execution of all pending app GCs.
15537     */
15538    final void scheduleAppGcsLocked() {
15539        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15540
15541        if (mProcessesToGc.size() > 0) {
15542            // Schedule a GC for the time to the next process.
15543            ProcessRecord proc = mProcessesToGc.get(0);
15544            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15545
15546            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15547            long now = SystemClock.uptimeMillis();
15548            if (when < (now+GC_TIMEOUT)) {
15549                when = now + GC_TIMEOUT;
15550            }
15551            mHandler.sendMessageAtTime(msg, when);
15552        }
15553    }
15554
15555    /**
15556     * Add a process to the array of processes waiting to be GCed.  Keeps the
15557     * list in sorted order by the last GC time.  The process can't already be
15558     * on the list.
15559     */
15560    final void addProcessToGcListLocked(ProcessRecord proc) {
15561        boolean added = false;
15562        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15563            if (mProcessesToGc.get(i).lastRequestedGc <
15564                    proc.lastRequestedGc) {
15565                added = true;
15566                mProcessesToGc.add(i+1, proc);
15567                break;
15568            }
15569        }
15570        if (!added) {
15571            mProcessesToGc.add(0, proc);
15572        }
15573    }
15574
15575    /**
15576     * Set up to ask a process to GC itself.  This will either do it
15577     * immediately, or put it on the list of processes to gc the next
15578     * time things are idle.
15579     */
15580    final void scheduleAppGcLocked(ProcessRecord app) {
15581        long now = SystemClock.uptimeMillis();
15582        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15583            return;
15584        }
15585        if (!mProcessesToGc.contains(app)) {
15586            addProcessToGcListLocked(app);
15587            scheduleAppGcsLocked();
15588        }
15589    }
15590
15591    final void checkExcessivePowerUsageLocked(boolean doKills) {
15592        updateCpuStatsNow();
15593
15594        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15595        boolean doWakeKills = doKills;
15596        boolean doCpuKills = doKills;
15597        if (mLastPowerCheckRealtime == 0) {
15598            doWakeKills = false;
15599        }
15600        if (mLastPowerCheckUptime == 0) {
15601            doCpuKills = false;
15602        }
15603        if (stats.isScreenOn()) {
15604            doWakeKills = false;
15605        }
15606        final long curRealtime = SystemClock.elapsedRealtime();
15607        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15608        final long curUptime = SystemClock.uptimeMillis();
15609        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15610        mLastPowerCheckRealtime = curRealtime;
15611        mLastPowerCheckUptime = curUptime;
15612        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15613            doWakeKills = false;
15614        }
15615        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15616            doCpuKills = false;
15617        }
15618        int i = mLruProcesses.size();
15619        while (i > 0) {
15620            i--;
15621            ProcessRecord app = mLruProcesses.get(i);
15622            if (!app.keeping) {
15623                long wtime;
15624                synchronized (stats) {
15625                    wtime = stats.getProcessWakeTime(app.info.uid,
15626                            app.pid, curRealtime);
15627                }
15628                long wtimeUsed = wtime - app.lastWakeTime;
15629                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15630                if (DEBUG_POWER) {
15631                    StringBuilder sb = new StringBuilder(128);
15632                    sb.append("Wake for ");
15633                    app.toShortString(sb);
15634                    sb.append(": over ");
15635                    TimeUtils.formatDuration(realtimeSince, sb);
15636                    sb.append(" used ");
15637                    TimeUtils.formatDuration(wtimeUsed, sb);
15638                    sb.append(" (");
15639                    sb.append((wtimeUsed*100)/realtimeSince);
15640                    sb.append("%)");
15641                    Slog.i(TAG, sb.toString());
15642                    sb.setLength(0);
15643                    sb.append("CPU for ");
15644                    app.toShortString(sb);
15645                    sb.append(": over ");
15646                    TimeUtils.formatDuration(uptimeSince, sb);
15647                    sb.append(" used ");
15648                    TimeUtils.formatDuration(cputimeUsed, sb);
15649                    sb.append(" (");
15650                    sb.append((cputimeUsed*100)/uptimeSince);
15651                    sb.append("%)");
15652                    Slog.i(TAG, sb.toString());
15653                }
15654                // If a process has held a wake lock for more
15655                // than 50% of the time during this period,
15656                // that sounds bad.  Kill!
15657                if (doWakeKills && realtimeSince > 0
15658                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15659                    synchronized (stats) {
15660                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15661                                realtimeSince, wtimeUsed);
15662                    }
15663                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15664                            + " during " + realtimeSince);
15665                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15666                } else if (doCpuKills && uptimeSince > 0
15667                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15668                    synchronized (stats) {
15669                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15670                                uptimeSince, cputimeUsed);
15671                    }
15672                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15673                            + " during " + uptimeSince);
15674                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15675                } else {
15676                    app.lastWakeTime = wtime;
15677                    app.lastCpuTime = app.curCpuTime;
15678                }
15679            }
15680        }
15681    }
15682
15683    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15684            ProcessRecord TOP_APP, boolean doingAll, long now) {
15685        boolean success = true;
15686
15687        if (app.curRawAdj != app.setRawAdj) {
15688            if (wasKeeping && !app.keeping) {
15689                // This app is no longer something we want to keep.  Note
15690                // its current wake lock time to later know to kill it if
15691                // it is not behaving well.
15692                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15693                synchronized (stats) {
15694                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15695                            app.pid, SystemClock.elapsedRealtime());
15696                }
15697                app.lastCpuTime = app.curCpuTime;
15698            }
15699
15700            app.setRawAdj = app.curRawAdj;
15701        }
15702
15703        int changes = 0;
15704
15705        if (app.curAdj != app.setAdj) {
15706            ProcessList.setOomAdj(app.pid, app.curAdj);
15707            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15708                TAG, "Set " + app.pid + " " + app.processName +
15709                " adj " + app.curAdj + ": " + app.adjType);
15710            app.setAdj = app.curAdj;
15711        }
15712
15713        if (app.setSchedGroup != app.curSchedGroup) {
15714            app.setSchedGroup = app.curSchedGroup;
15715            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15716                    "Setting process group of " + app.processName
15717                    + " to " + app.curSchedGroup);
15718            if (app.waitingToKill != null &&
15719                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15720                killUnneededProcessLocked(app, app.waitingToKill);
15721                success = false;
15722            } else {
15723                if (true) {
15724                    long oldId = Binder.clearCallingIdentity();
15725                    try {
15726                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15727                    } catch (Exception e) {
15728                        Slog.w(TAG, "Failed setting process group of " + app.pid
15729                                + " to " + app.curSchedGroup);
15730                        e.printStackTrace();
15731                    } finally {
15732                        Binder.restoreCallingIdentity(oldId);
15733                    }
15734                } else {
15735                    if (app.thread != null) {
15736                        try {
15737                            app.thread.setSchedulingGroup(app.curSchedGroup);
15738                        } catch (RemoteException e) {
15739                        }
15740                    }
15741                }
15742                Process.setSwappiness(app.pid,
15743                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15744            }
15745        }
15746        if (app.repForegroundActivities != app.foregroundActivities) {
15747            app.repForegroundActivities = app.foregroundActivities;
15748            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15749        }
15750        if (app.repProcState != app.curProcState) {
15751            app.repProcState = app.curProcState;
15752            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15753            if (app.thread != null) {
15754                try {
15755                    if (false) {
15756                        //RuntimeException h = new RuntimeException("here");
15757                        Slog.i(TAG, "Sending new process state " + app.repProcState
15758                                + " to " + app /*, h*/);
15759                    }
15760                    app.thread.setProcessState(app.repProcState);
15761                } catch (RemoteException e) {
15762                }
15763            }
15764        }
15765        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15766                app.setProcState)) {
15767            app.lastStateTime = now;
15768            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15769                    isSleeping(), now);
15770            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15771                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15772                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15773                    + (app.nextPssTime-now) + ": " + app);
15774        } else {
15775            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15776                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15777                requestPssLocked(app, app.setProcState);
15778                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15779                        isSleeping(), now);
15780            } else if (false && DEBUG_PSS) {
15781                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15782            }
15783        }
15784        if (app.setProcState != app.curProcState) {
15785            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15786                    "Proc state change of " + app.processName
15787                    + " to " + app.curProcState);
15788            app.setProcState = app.curProcState;
15789            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15790                app.notCachedSinceIdle = false;
15791            }
15792            if (!doingAll) {
15793                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15794            } else {
15795                app.procStateChanged = true;
15796            }
15797        }
15798
15799        if (changes != 0) {
15800            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15801            int i = mPendingProcessChanges.size()-1;
15802            ProcessChangeItem item = null;
15803            while (i >= 0) {
15804                item = mPendingProcessChanges.get(i);
15805                if (item.pid == app.pid) {
15806                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15807                    break;
15808                }
15809                i--;
15810            }
15811            if (i < 0) {
15812                // No existing item in pending changes; need a new one.
15813                final int NA = mAvailProcessChanges.size();
15814                if (NA > 0) {
15815                    item = mAvailProcessChanges.remove(NA-1);
15816                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15817                } else {
15818                    item = new ProcessChangeItem();
15819                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15820                }
15821                item.changes = 0;
15822                item.pid = app.pid;
15823                item.uid = app.info.uid;
15824                if (mPendingProcessChanges.size() == 0) {
15825                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15826                            "*** Enqueueing dispatch processes changed!");
15827                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15828                }
15829                mPendingProcessChanges.add(item);
15830            }
15831            item.changes |= changes;
15832            item.processState = app.repProcState;
15833            item.foregroundActivities = app.repForegroundActivities;
15834            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15835                    + Integer.toHexString(System.identityHashCode(item))
15836                    + " " + app.toShortString() + ": changes=" + item.changes
15837                    + " procState=" + item.processState
15838                    + " foreground=" + item.foregroundActivities
15839                    + " type=" + app.adjType + " source=" + app.adjSource
15840                    + " target=" + app.adjTarget);
15841        }
15842
15843        return success;
15844    }
15845
15846    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15847        if (proc.thread != null && proc.baseProcessTracker != null) {
15848            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15849        }
15850    }
15851
15852    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15853            ProcessRecord TOP_APP, boolean doingAll, long now) {
15854        if (app.thread == null) {
15855            return false;
15856        }
15857
15858        final boolean wasKeeping = app.keeping;
15859
15860        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15861
15862        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15863    }
15864
15865    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15866            boolean oomAdj) {
15867        if (isForeground != proc.foregroundServices) {
15868            proc.foregroundServices = isForeground;
15869            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15870                    proc.info.uid);
15871            if (isForeground) {
15872                if (curProcs == null) {
15873                    curProcs = new ArrayList<ProcessRecord>();
15874                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15875                }
15876                if (!curProcs.contains(proc)) {
15877                    curProcs.add(proc);
15878                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15879                            proc.info.packageName, proc.info.uid);
15880                }
15881            } else {
15882                if (curProcs != null) {
15883                    if (curProcs.remove(proc)) {
15884                        mBatteryStatsService.noteEvent(
15885                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15886                                proc.info.packageName, proc.info.uid);
15887                        if (curProcs.size() <= 0) {
15888                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15889                        }
15890                    }
15891                }
15892            }
15893            if (oomAdj) {
15894                updateOomAdjLocked();
15895            }
15896        }
15897    }
15898
15899    private final ActivityRecord resumedAppLocked() {
15900        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15901        String pkg;
15902        int uid;
15903        if (act != null && !act.sleeping) {
15904            pkg = act.packageName;
15905            uid = act.info.applicationInfo.uid;
15906        } else {
15907            pkg = null;
15908            uid = -1;
15909        }
15910        // Has the UID or resumed package name changed?
15911        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15912                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15913            if (mCurResumedPackage != null) {
15914                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15915                        mCurResumedPackage, mCurResumedUid);
15916            }
15917            mCurResumedPackage = pkg;
15918            mCurResumedUid = uid;
15919            if (mCurResumedPackage != null) {
15920                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15921                        mCurResumedPackage, mCurResumedUid);
15922            }
15923        }
15924        return act;
15925    }
15926
15927    final boolean updateOomAdjLocked(ProcessRecord app) {
15928        final ActivityRecord TOP_ACT = resumedAppLocked();
15929        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15930        final boolean wasCached = app.cached;
15931
15932        mAdjSeq++;
15933
15934        // This is the desired cached adjusment we want to tell it to use.
15935        // If our app is currently cached, we know it, and that is it.  Otherwise,
15936        // we don't know it yet, and it needs to now be cached we will then
15937        // need to do a complete oom adj.
15938        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15939                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15940        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15941                SystemClock.uptimeMillis());
15942        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15943            // Changed to/from cached state, so apps after it in the LRU
15944            // list may also be changed.
15945            updateOomAdjLocked();
15946        }
15947        return success;
15948    }
15949
15950    final void updateOomAdjLocked() {
15951        final ActivityRecord TOP_ACT = resumedAppLocked();
15952        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15953        final long now = SystemClock.uptimeMillis();
15954        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15955        final int N = mLruProcesses.size();
15956
15957        if (false) {
15958            RuntimeException e = new RuntimeException();
15959            e.fillInStackTrace();
15960            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15961        }
15962
15963        mAdjSeq++;
15964        mNewNumServiceProcs = 0;
15965        mNewNumAServiceProcs = 0;
15966
15967        final int emptyProcessLimit;
15968        final int cachedProcessLimit;
15969        if (mProcessLimit <= 0) {
15970            emptyProcessLimit = cachedProcessLimit = 0;
15971        } else if (mProcessLimit == 1) {
15972            emptyProcessLimit = 1;
15973            cachedProcessLimit = 0;
15974        } else {
15975            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15976            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15977        }
15978
15979        // Let's determine how many processes we have running vs.
15980        // how many slots we have for background processes; we may want
15981        // to put multiple processes in a slot of there are enough of
15982        // them.
15983        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15984                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15985        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15986        if (numEmptyProcs > cachedProcessLimit) {
15987            // If there are more empty processes than our limit on cached
15988            // processes, then use the cached process limit for the factor.
15989            // This ensures that the really old empty processes get pushed
15990            // down to the bottom, so if we are running low on memory we will
15991            // have a better chance at keeping around more cached processes
15992            // instead of a gazillion empty processes.
15993            numEmptyProcs = cachedProcessLimit;
15994        }
15995        int emptyFactor = numEmptyProcs/numSlots;
15996        if (emptyFactor < 1) emptyFactor = 1;
15997        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15998        if (cachedFactor < 1) cachedFactor = 1;
15999        int stepCached = 0;
16000        int stepEmpty = 0;
16001        int numCached = 0;
16002        int numEmpty = 0;
16003        int numTrimming = 0;
16004
16005        mNumNonCachedProcs = 0;
16006        mNumCachedHiddenProcs = 0;
16007
16008        // First update the OOM adjustment for each of the
16009        // application processes based on their current state.
16010        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16011        int nextCachedAdj = curCachedAdj+1;
16012        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16013        int nextEmptyAdj = curEmptyAdj+2;
16014        for (int i=N-1; i>=0; i--) {
16015            ProcessRecord app = mLruProcesses.get(i);
16016            if (!app.killedByAm && app.thread != null) {
16017                app.procStateChanged = false;
16018                final boolean wasKeeping = app.keeping;
16019                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16020
16021                // If we haven't yet assigned the final cached adj
16022                // to the process, do that now.
16023                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16024                    switch (app.curProcState) {
16025                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16026                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16027                            // This process is a cached process holding activities...
16028                            // assign it the next cached value for that type, and then
16029                            // step that cached level.
16030                            app.curRawAdj = curCachedAdj;
16031                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16032                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16033                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16034                                    + ")");
16035                            if (curCachedAdj != nextCachedAdj) {
16036                                stepCached++;
16037                                if (stepCached >= cachedFactor) {
16038                                    stepCached = 0;
16039                                    curCachedAdj = nextCachedAdj;
16040                                    nextCachedAdj += 2;
16041                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16042                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16043                                    }
16044                                }
16045                            }
16046                            break;
16047                        default:
16048                            // For everything else, assign next empty cached process
16049                            // level and bump that up.  Note that this means that
16050                            // long-running services that have dropped down to the
16051                            // cached level will be treated as empty (since their process
16052                            // state is still as a service), which is what we want.
16053                            app.curRawAdj = curEmptyAdj;
16054                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16055                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16056                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16057                                    + ")");
16058                            if (curEmptyAdj != nextEmptyAdj) {
16059                                stepEmpty++;
16060                                if (stepEmpty >= emptyFactor) {
16061                                    stepEmpty = 0;
16062                                    curEmptyAdj = nextEmptyAdj;
16063                                    nextEmptyAdj += 2;
16064                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16065                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16066                                    }
16067                                }
16068                            }
16069                            break;
16070                    }
16071                }
16072
16073                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16074
16075                // Count the number of process types.
16076                switch (app.curProcState) {
16077                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16078                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16079                        mNumCachedHiddenProcs++;
16080                        numCached++;
16081                        if (numCached > cachedProcessLimit) {
16082                            killUnneededProcessLocked(app, "cached #" + numCached);
16083                        }
16084                        break;
16085                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16086                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16087                                && app.lastActivityTime < oldTime) {
16088                            killUnneededProcessLocked(app, "empty for "
16089                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16090                                    / 1000) + "s");
16091                        } else {
16092                            numEmpty++;
16093                            if (numEmpty > emptyProcessLimit) {
16094                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16095                            }
16096                        }
16097                        break;
16098                    default:
16099                        mNumNonCachedProcs++;
16100                        break;
16101                }
16102
16103                if (app.isolated && app.services.size() <= 0) {
16104                    // If this is an isolated process, and there are no
16105                    // services running in it, then the process is no longer
16106                    // needed.  We agressively kill these because we can by
16107                    // definition not re-use the same process again, and it is
16108                    // good to avoid having whatever code was running in them
16109                    // left sitting around after no longer needed.
16110                    killUnneededProcessLocked(app, "isolated not needed");
16111                }
16112
16113                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16114                        && !app.killedByAm) {
16115                    numTrimming++;
16116                }
16117            }
16118        }
16119
16120        mNumServiceProcs = mNewNumServiceProcs;
16121
16122        // Now determine the memory trimming level of background processes.
16123        // Unfortunately we need to start at the back of the list to do this
16124        // properly.  We only do this if the number of background apps we
16125        // are managing to keep around is less than half the maximum we desire;
16126        // if we are keeping a good number around, we'll let them use whatever
16127        // memory they want.
16128        final int numCachedAndEmpty = numCached + numEmpty;
16129        int memFactor;
16130        if (numCached <= ProcessList.TRIM_CACHED_APPS
16131                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16132            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16133                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16134            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16135                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16136            } else {
16137                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16138            }
16139        } else {
16140            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16141        }
16142        // We always allow the memory level to go up (better).  We only allow it to go
16143        // down if we are in a state where that is allowed, *and* the total number of processes
16144        // has gone down since last time.
16145        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16146                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16147                + " last=" + mLastNumProcesses);
16148        if (memFactor > mLastMemoryLevel) {
16149            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16150                memFactor = mLastMemoryLevel;
16151                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16152            }
16153        }
16154        mLastMemoryLevel = memFactor;
16155        mLastNumProcesses = mLruProcesses.size();
16156        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16157        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16158        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16159            if (mLowRamStartTime == 0) {
16160                mLowRamStartTime = now;
16161            }
16162            int step = 0;
16163            int fgTrimLevel;
16164            switch (memFactor) {
16165                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16166                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16167                    break;
16168                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16169                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16170                    break;
16171                default:
16172                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16173                    break;
16174            }
16175            int factor = numTrimming/3;
16176            int minFactor = 2;
16177            if (mHomeProcess != null) minFactor++;
16178            if (mPreviousProcess != null) minFactor++;
16179            if (factor < minFactor) factor = minFactor;
16180            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16181            for (int i=N-1; i>=0; i--) {
16182                ProcessRecord app = mLruProcesses.get(i);
16183                if (allChanged || app.procStateChanged) {
16184                    setProcessTrackerState(app, trackerMemFactor, now);
16185                    app.procStateChanged = false;
16186                }
16187                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16188                        && !app.killedByAm) {
16189                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16190                        try {
16191                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16192                                    "Trimming memory of " + app.processName
16193                                    + " to " + curLevel);
16194                            app.thread.scheduleTrimMemory(curLevel);
16195                        } catch (RemoteException e) {
16196                        }
16197                        if (false) {
16198                            // For now we won't do this; our memory trimming seems
16199                            // to be good enough at this point that destroying
16200                            // activities causes more harm than good.
16201                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16202                                    && app != mHomeProcess && app != mPreviousProcess) {
16203                                // Need to do this on its own message because the stack may not
16204                                // be in a consistent state at this point.
16205                                // For these apps we will also finish their activities
16206                                // to help them free memory.
16207                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16208                            }
16209                        }
16210                    }
16211                    app.trimMemoryLevel = curLevel;
16212                    step++;
16213                    if (step >= factor) {
16214                        step = 0;
16215                        switch (curLevel) {
16216                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16217                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16218                                break;
16219                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16220                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16221                                break;
16222                        }
16223                    }
16224                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16225                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16226                            && app.thread != null) {
16227                        try {
16228                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16229                                    "Trimming memory of heavy-weight " + app.processName
16230                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16231                            app.thread.scheduleTrimMemory(
16232                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16233                        } catch (RemoteException e) {
16234                        }
16235                    }
16236                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16237                } else {
16238                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16239                            || app.systemNoUi) && app.pendingUiClean) {
16240                        // If this application is now in the background and it
16241                        // had done UI, then give it the special trim level to
16242                        // have it free UI resources.
16243                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16244                        if (app.trimMemoryLevel < level && app.thread != null) {
16245                            try {
16246                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16247                                        "Trimming memory of bg-ui " + app.processName
16248                                        + " to " + level);
16249                                app.thread.scheduleTrimMemory(level);
16250                            } catch (RemoteException e) {
16251                            }
16252                        }
16253                        app.pendingUiClean = false;
16254                    }
16255                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16256                        try {
16257                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16258                                    "Trimming memory of fg " + app.processName
16259                                    + " to " + fgTrimLevel);
16260                            app.thread.scheduleTrimMemory(fgTrimLevel);
16261                        } catch (RemoteException e) {
16262                        }
16263                    }
16264                    app.trimMemoryLevel = fgTrimLevel;
16265                }
16266            }
16267        } else {
16268            if (mLowRamStartTime != 0) {
16269                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16270                mLowRamStartTime = 0;
16271            }
16272            for (int i=N-1; i>=0; i--) {
16273                ProcessRecord app = mLruProcesses.get(i);
16274                if (allChanged || app.procStateChanged) {
16275                    setProcessTrackerState(app, trackerMemFactor, now);
16276                    app.procStateChanged = false;
16277                }
16278                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16279                        || app.systemNoUi) && app.pendingUiClean) {
16280                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16281                            && app.thread != null) {
16282                        try {
16283                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16284                                    "Trimming memory of ui hidden " + app.processName
16285                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16286                            app.thread.scheduleTrimMemory(
16287                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16288                        } catch (RemoteException e) {
16289                        }
16290                    }
16291                    app.pendingUiClean = false;
16292                }
16293                app.trimMemoryLevel = 0;
16294            }
16295        }
16296
16297        if (mAlwaysFinishActivities) {
16298            // Need to do this on its own message because the stack may not
16299            // be in a consistent state at this point.
16300            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16301        }
16302
16303        if (allChanged) {
16304            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16305        }
16306
16307        if (mProcessStats.shouldWriteNowLocked(now)) {
16308            mHandler.post(new Runnable() {
16309                @Override public void run() {
16310                    synchronized (ActivityManagerService.this) {
16311                        mProcessStats.writeStateAsyncLocked();
16312                    }
16313                }
16314            });
16315        }
16316
16317        if (DEBUG_OOM_ADJ) {
16318            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16319        }
16320    }
16321
16322    final void trimApplications() {
16323        synchronized (this) {
16324            int i;
16325
16326            // First remove any unused application processes whose package
16327            // has been removed.
16328            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16329                final ProcessRecord app = mRemovedProcesses.get(i);
16330                if (app.activities.size() == 0
16331                        && app.curReceiver == null && app.services.size() == 0) {
16332                    Slog.i(
16333                        TAG, "Exiting empty application process "
16334                        + app.processName + " ("
16335                        + (app.thread != null ? app.thread.asBinder() : null)
16336                        + ")\n");
16337                    if (app.pid > 0 && app.pid != MY_PID) {
16338                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16339                                app.processName, app.setAdj, "empty");
16340                        app.killedByAm = true;
16341                        Process.killProcessQuiet(app.pid);
16342                    } else {
16343                        try {
16344                            app.thread.scheduleExit();
16345                        } catch (Exception e) {
16346                            // Ignore exceptions.
16347                        }
16348                    }
16349                    cleanUpApplicationRecordLocked(app, false, true, -1);
16350                    mRemovedProcesses.remove(i);
16351
16352                    if (app.persistent) {
16353                        if (app.persistent) {
16354                            addAppLocked(app.info, false, null /* ABI override */);
16355                        }
16356                    }
16357                }
16358            }
16359
16360            // Now update the oom adj for all processes.
16361            updateOomAdjLocked();
16362        }
16363    }
16364
16365    /** This method sends the specified signal to each of the persistent apps */
16366    public void signalPersistentProcesses(int sig) throws RemoteException {
16367        if (sig != Process.SIGNAL_USR1) {
16368            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16369        }
16370
16371        synchronized (this) {
16372            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16373                    != PackageManager.PERMISSION_GRANTED) {
16374                throw new SecurityException("Requires permission "
16375                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16376            }
16377
16378            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16379                ProcessRecord r = mLruProcesses.get(i);
16380                if (r.thread != null && r.persistent) {
16381                    Process.sendSignal(r.pid, sig);
16382                }
16383            }
16384        }
16385    }
16386
16387    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16388        if (proc == null || proc == mProfileProc) {
16389            proc = mProfileProc;
16390            path = mProfileFile;
16391            profileType = mProfileType;
16392            clearProfilerLocked();
16393        }
16394        if (proc == null) {
16395            return;
16396        }
16397        try {
16398            proc.thread.profilerControl(false, path, null, profileType);
16399        } catch (RemoteException e) {
16400            throw new IllegalStateException("Process disappeared");
16401        }
16402    }
16403
16404    private void clearProfilerLocked() {
16405        if (mProfileFd != null) {
16406            try {
16407                mProfileFd.close();
16408            } catch (IOException e) {
16409            }
16410        }
16411        mProfileApp = null;
16412        mProfileProc = null;
16413        mProfileFile = null;
16414        mProfileType = 0;
16415        mAutoStopProfiler = false;
16416    }
16417
16418    public boolean profileControl(String process, int userId, boolean start,
16419            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16420
16421        try {
16422            synchronized (this) {
16423                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16424                // its own permission.
16425                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16426                        != PackageManager.PERMISSION_GRANTED) {
16427                    throw new SecurityException("Requires permission "
16428                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16429                }
16430
16431                if (start && fd == null) {
16432                    throw new IllegalArgumentException("null fd");
16433                }
16434
16435                ProcessRecord proc = null;
16436                if (process != null) {
16437                    proc = findProcessLocked(process, userId, "profileControl");
16438                }
16439
16440                if (start && (proc == null || proc.thread == null)) {
16441                    throw new IllegalArgumentException("Unknown process: " + process);
16442                }
16443
16444                if (start) {
16445                    stopProfilerLocked(null, null, 0);
16446                    setProfileApp(proc.info, proc.processName, path, fd, false);
16447                    mProfileProc = proc;
16448                    mProfileType = profileType;
16449                    try {
16450                        fd = fd.dup();
16451                    } catch (IOException e) {
16452                        fd = null;
16453                    }
16454                    proc.thread.profilerControl(start, path, fd, profileType);
16455                    fd = null;
16456                    mProfileFd = null;
16457                } else {
16458                    stopProfilerLocked(proc, path, profileType);
16459                    if (fd != null) {
16460                        try {
16461                            fd.close();
16462                        } catch (IOException e) {
16463                        }
16464                    }
16465                }
16466
16467                return true;
16468            }
16469        } catch (RemoteException e) {
16470            throw new IllegalStateException("Process disappeared");
16471        } finally {
16472            if (fd != null) {
16473                try {
16474                    fd.close();
16475                } catch (IOException e) {
16476                }
16477            }
16478        }
16479    }
16480
16481    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16482        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16483                userId, true, true, callName, null);
16484        ProcessRecord proc = null;
16485        try {
16486            int pid = Integer.parseInt(process);
16487            synchronized (mPidsSelfLocked) {
16488                proc = mPidsSelfLocked.get(pid);
16489            }
16490        } catch (NumberFormatException e) {
16491        }
16492
16493        if (proc == null) {
16494            ArrayMap<String, SparseArray<ProcessRecord>> all
16495                    = mProcessNames.getMap();
16496            SparseArray<ProcessRecord> procs = all.get(process);
16497            if (procs != null && procs.size() > 0) {
16498                proc = procs.valueAt(0);
16499                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16500                    for (int i=1; i<procs.size(); i++) {
16501                        ProcessRecord thisProc = procs.valueAt(i);
16502                        if (thisProc.userId == userId) {
16503                            proc = thisProc;
16504                            break;
16505                        }
16506                    }
16507                }
16508            }
16509        }
16510
16511        return proc;
16512    }
16513
16514    public boolean dumpHeap(String process, int userId, boolean managed,
16515            String path, ParcelFileDescriptor fd) throws RemoteException {
16516
16517        try {
16518            synchronized (this) {
16519                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16520                // its own permission (same as profileControl).
16521                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16522                        != PackageManager.PERMISSION_GRANTED) {
16523                    throw new SecurityException("Requires permission "
16524                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16525                }
16526
16527                if (fd == null) {
16528                    throw new IllegalArgumentException("null fd");
16529                }
16530
16531                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16532                if (proc == null || proc.thread == null) {
16533                    throw new IllegalArgumentException("Unknown process: " + process);
16534                }
16535
16536                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16537                if (!isDebuggable) {
16538                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16539                        throw new SecurityException("Process not debuggable: " + proc);
16540                    }
16541                }
16542
16543                proc.thread.dumpHeap(managed, path, fd);
16544                fd = null;
16545                return true;
16546            }
16547        } catch (RemoteException e) {
16548            throw new IllegalStateException("Process disappeared");
16549        } finally {
16550            if (fd != null) {
16551                try {
16552                    fd.close();
16553                } catch (IOException e) {
16554                }
16555            }
16556        }
16557    }
16558
16559    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16560    public void monitor() {
16561        synchronized (this) { }
16562    }
16563
16564    void onCoreSettingsChange(Bundle settings) {
16565        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16566            ProcessRecord processRecord = mLruProcesses.get(i);
16567            try {
16568                if (processRecord.thread != null) {
16569                    processRecord.thread.setCoreSettings(settings);
16570                }
16571            } catch (RemoteException re) {
16572                /* ignore */
16573            }
16574        }
16575    }
16576
16577    // Multi-user methods
16578
16579    /**
16580     * Start user, if its not already running, but don't bring it to foreground.
16581     */
16582    @Override
16583    public boolean startUserInBackground(final int userId) {
16584        return startUser(userId, /* foreground */ false);
16585    }
16586
16587    /**
16588     * Refreshes the list of users related to the current user when either a
16589     * user switch happens or when a new related user is started in the
16590     * background.
16591     */
16592    private void updateCurrentProfileIdsLocked() {
16593        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16594                mCurrentUserId, false /* enabledOnly */);
16595        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16596        for (int i = 0; i < currentProfileIds.length; i++) {
16597            currentProfileIds[i] = profiles.get(i).id;
16598        }
16599        mCurrentProfileIds = currentProfileIds;
16600    }
16601
16602    private Set getProfileIdsLocked(int userId) {
16603        Set userIds = new HashSet<Integer>();
16604        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16605                userId, false /* enabledOnly */);
16606        for (UserInfo user : profiles) {
16607            userIds.add(Integer.valueOf(user.id));
16608        }
16609        return userIds;
16610    }
16611
16612    @Override
16613    public boolean switchUser(final int userId) {
16614        return startUser(userId, /* foregound */ true);
16615    }
16616
16617    private boolean startUser(final int userId, boolean foreground) {
16618        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16619                != PackageManager.PERMISSION_GRANTED) {
16620            String msg = "Permission Denial: switchUser() from pid="
16621                    + Binder.getCallingPid()
16622                    + ", uid=" + Binder.getCallingUid()
16623                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16624            Slog.w(TAG, msg);
16625            throw new SecurityException(msg);
16626        }
16627
16628        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16629
16630        final long ident = Binder.clearCallingIdentity();
16631        try {
16632            synchronized (this) {
16633                final int oldUserId = mCurrentUserId;
16634                if (oldUserId == userId) {
16635                    return true;
16636                }
16637
16638                mStackSupervisor.setLockTaskModeLocked(null);
16639
16640                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16641                if (userInfo == null) {
16642                    Slog.w(TAG, "No user info for user #" + userId);
16643                    return false;
16644                }
16645
16646                if (foreground) {
16647                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16648                            R.anim.screen_user_enter);
16649                }
16650
16651                boolean needStart = false;
16652
16653                // If the user we are switching to is not currently started, then
16654                // we need to start it now.
16655                if (mStartedUsers.get(userId) == null) {
16656                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16657                    updateStartedUserArrayLocked();
16658                    needStart = true;
16659                }
16660
16661                final Integer userIdInt = Integer.valueOf(userId);
16662                mUserLru.remove(userIdInt);
16663                mUserLru.add(userIdInt);
16664
16665                if (foreground) {
16666                    mCurrentUserId = userId;
16667                    updateCurrentProfileIdsLocked();
16668                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16669                    // Once the internal notion of the active user has switched, we lock the device
16670                    // with the option to show the user switcher on the keyguard.
16671                    mWindowManager.lockNow(null);
16672                } else {
16673                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16674                    updateCurrentProfileIdsLocked();
16675                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16676                    mUserLru.remove(currentUserIdInt);
16677                    mUserLru.add(currentUserIdInt);
16678                }
16679
16680                final UserStartedState uss = mStartedUsers.get(userId);
16681
16682                // Make sure user is in the started state.  If it is currently
16683                // stopping, we need to knock that off.
16684                if (uss.mState == UserStartedState.STATE_STOPPING) {
16685                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16686                    // so we can just fairly silently bring the user back from
16687                    // the almost-dead.
16688                    uss.mState = UserStartedState.STATE_RUNNING;
16689                    updateStartedUserArrayLocked();
16690                    needStart = true;
16691                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16692                    // This means ACTION_SHUTDOWN has been sent, so we will
16693                    // need to treat this as a new boot of the user.
16694                    uss.mState = UserStartedState.STATE_BOOTING;
16695                    updateStartedUserArrayLocked();
16696                    needStart = true;
16697                }
16698
16699                if (uss.mState == UserStartedState.STATE_BOOTING) {
16700                    // Booting up a new user, need to tell system services about it.
16701                    // Note that this is on the same handler as scheduling of broadcasts,
16702                    // which is important because it needs to go first.
16703                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16704                }
16705
16706                if (foreground) {
16707                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16708                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16709                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16710                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16711                            oldUserId, userId, uss));
16712                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16713                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16714                }
16715
16716                if (needStart) {
16717                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16718                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16719                            | Intent.FLAG_RECEIVER_FOREGROUND);
16720                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16721                    broadcastIntentLocked(null, null, intent,
16722                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16723                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16724                }
16725
16726                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16727                    if (userId != UserHandle.USER_OWNER) {
16728                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16729                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16730                        broadcastIntentLocked(null, null, intent, null,
16731                                new IIntentReceiver.Stub() {
16732                                    public void performReceive(Intent intent, int resultCode,
16733                                            String data, Bundle extras, boolean ordered,
16734                                            boolean sticky, int sendingUser) {
16735                                        userInitialized(uss, userId);
16736                                    }
16737                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16738                                true, false, MY_PID, Process.SYSTEM_UID,
16739                                userId);
16740                        uss.initializing = true;
16741                    } else {
16742                        getUserManagerLocked().makeInitialized(userInfo.id);
16743                    }
16744                }
16745
16746                if (foreground) {
16747                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16748                    if (homeInFront) {
16749                        startHomeActivityLocked(userId);
16750                    } else {
16751                        mStackSupervisor.resumeTopActivitiesLocked();
16752                    }
16753                    EventLogTags.writeAmSwitchUser(userId);
16754                    getUserManagerLocked().userForeground(userId);
16755                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16756                } else {
16757                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16758                }
16759
16760                if (needStart) {
16761                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16762                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16763                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16764                    broadcastIntentLocked(null, null, intent,
16765                            null, new IIntentReceiver.Stub() {
16766                                @Override
16767                                public void performReceive(Intent intent, int resultCode, String data,
16768                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16769                                        throws RemoteException {
16770                                }
16771                            }, 0, null, null,
16772                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16773                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16774                }
16775            }
16776        } finally {
16777            Binder.restoreCallingIdentity(ident);
16778        }
16779
16780        return true;
16781    }
16782
16783    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16784        long ident = Binder.clearCallingIdentity();
16785        try {
16786            Intent intent;
16787            if (oldUserId >= 0) {
16788                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16789                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16790                        | Intent.FLAG_RECEIVER_FOREGROUND);
16791                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16792                broadcastIntentLocked(null, null, intent,
16793                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16794                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16795            }
16796            if (newUserId >= 0) {
16797                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16798                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16799                        | Intent.FLAG_RECEIVER_FOREGROUND);
16800                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16801                broadcastIntentLocked(null, null, intent,
16802                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16803                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16804                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16805                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16806                        | Intent.FLAG_RECEIVER_FOREGROUND);
16807                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16808                broadcastIntentLocked(null, null, intent,
16809                        null, null, 0, null, null,
16810                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16811                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16812            }
16813        } finally {
16814            Binder.restoreCallingIdentity(ident);
16815        }
16816    }
16817
16818    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16819            final int newUserId) {
16820        final int N = mUserSwitchObservers.beginBroadcast();
16821        if (N > 0) {
16822            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16823                int mCount = 0;
16824                @Override
16825                public void sendResult(Bundle data) throws RemoteException {
16826                    synchronized (ActivityManagerService.this) {
16827                        if (mCurUserSwitchCallback == this) {
16828                            mCount++;
16829                            if (mCount == N) {
16830                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16831                            }
16832                        }
16833                    }
16834                }
16835            };
16836            synchronized (this) {
16837                uss.switching = true;
16838                mCurUserSwitchCallback = callback;
16839            }
16840            for (int i=0; i<N; i++) {
16841                try {
16842                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16843                            newUserId, callback);
16844                } catch (RemoteException e) {
16845                }
16846            }
16847        } else {
16848            synchronized (this) {
16849                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16850            }
16851        }
16852        mUserSwitchObservers.finishBroadcast();
16853    }
16854
16855    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16856        synchronized (this) {
16857            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16858            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16859        }
16860    }
16861
16862    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16863        mCurUserSwitchCallback = null;
16864        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16865        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16866                oldUserId, newUserId, uss));
16867    }
16868
16869    void userInitialized(UserStartedState uss, int newUserId) {
16870        completeSwitchAndInitalize(uss, newUserId, true, false);
16871    }
16872
16873    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16874        completeSwitchAndInitalize(uss, newUserId, false, true);
16875    }
16876
16877    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16878            boolean clearInitializing, boolean clearSwitching) {
16879        boolean unfrozen = false;
16880        synchronized (this) {
16881            if (clearInitializing) {
16882                uss.initializing = false;
16883                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16884            }
16885            if (clearSwitching) {
16886                uss.switching = false;
16887            }
16888            if (!uss.switching && !uss.initializing) {
16889                mWindowManager.stopFreezingScreen();
16890                unfrozen = true;
16891            }
16892        }
16893        if (unfrozen) {
16894            final int N = mUserSwitchObservers.beginBroadcast();
16895            for (int i=0; i<N; i++) {
16896                try {
16897                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16898                } catch (RemoteException e) {
16899                }
16900            }
16901            mUserSwitchObservers.finishBroadcast();
16902        }
16903    }
16904
16905    void scheduleStartProfilesLocked() {
16906        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16907            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16908                    DateUtils.SECOND_IN_MILLIS);
16909        }
16910    }
16911
16912    void startProfilesLocked() {
16913        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16914        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16915                mCurrentUserId, false /* enabledOnly */);
16916        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16917        for (UserInfo user : profiles) {
16918            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16919                    && user.id != mCurrentUserId) {
16920                toStart.add(user);
16921            }
16922        }
16923        final int n = toStart.size();
16924        int i = 0;
16925        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16926            startUserInBackground(toStart.get(i).id);
16927        }
16928        if (i < n) {
16929            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16930        }
16931    }
16932
16933    void finishUserBoot(UserStartedState uss) {
16934        synchronized (this) {
16935            if (uss.mState == UserStartedState.STATE_BOOTING
16936                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16937                uss.mState = UserStartedState.STATE_RUNNING;
16938                final int userId = uss.mHandle.getIdentifier();
16939                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16940                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16941                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16942                broadcastIntentLocked(null, null, intent,
16943                        null, null, 0, null, null,
16944                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16945                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16946            }
16947        }
16948    }
16949
16950    void finishUserSwitch(UserStartedState uss) {
16951        synchronized (this) {
16952            finishUserBoot(uss);
16953
16954            startProfilesLocked();
16955
16956            int num = mUserLru.size();
16957            int i = 0;
16958            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16959                Integer oldUserId = mUserLru.get(i);
16960                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16961                if (oldUss == null) {
16962                    // Shouldn't happen, but be sane if it does.
16963                    mUserLru.remove(i);
16964                    num--;
16965                    continue;
16966                }
16967                if (oldUss.mState == UserStartedState.STATE_STOPPING
16968                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16969                    // This user is already stopping, doesn't count.
16970                    num--;
16971                    i++;
16972                    continue;
16973                }
16974                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16975                    // Owner and current can't be stopped, but count as running.
16976                    i++;
16977                    continue;
16978                }
16979                // This is a user to be stopped.
16980                stopUserLocked(oldUserId, null);
16981                num--;
16982                i++;
16983            }
16984        }
16985    }
16986
16987    @Override
16988    public int stopUser(final int userId, final IStopUserCallback callback) {
16989        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16990                != PackageManager.PERMISSION_GRANTED) {
16991            String msg = "Permission Denial: switchUser() from pid="
16992                    + Binder.getCallingPid()
16993                    + ", uid=" + Binder.getCallingUid()
16994                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16995            Slog.w(TAG, msg);
16996            throw new SecurityException(msg);
16997        }
16998        if (userId <= 0) {
16999            throw new IllegalArgumentException("Can't stop primary user " + userId);
17000        }
17001        synchronized (this) {
17002            return stopUserLocked(userId, callback);
17003        }
17004    }
17005
17006    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17007        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17008        if (mCurrentUserId == userId) {
17009            return ActivityManager.USER_OP_IS_CURRENT;
17010        }
17011
17012        final UserStartedState uss = mStartedUsers.get(userId);
17013        if (uss == null) {
17014            // User is not started, nothing to do...  but we do need to
17015            // callback if requested.
17016            if (callback != null) {
17017                mHandler.post(new Runnable() {
17018                    @Override
17019                    public void run() {
17020                        try {
17021                            callback.userStopped(userId);
17022                        } catch (RemoteException e) {
17023                        }
17024                    }
17025                });
17026            }
17027            return ActivityManager.USER_OP_SUCCESS;
17028        }
17029
17030        if (callback != null) {
17031            uss.mStopCallbacks.add(callback);
17032        }
17033
17034        if (uss.mState != UserStartedState.STATE_STOPPING
17035                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17036            uss.mState = UserStartedState.STATE_STOPPING;
17037            updateStartedUserArrayLocked();
17038
17039            long ident = Binder.clearCallingIdentity();
17040            try {
17041                // We are going to broadcast ACTION_USER_STOPPING and then
17042                // once that is done send a final ACTION_SHUTDOWN and then
17043                // stop the user.
17044                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17045                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17046                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17047                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17048                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17049                // This is the result receiver for the final shutdown broadcast.
17050                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17051                    @Override
17052                    public void performReceive(Intent intent, int resultCode, String data,
17053                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17054                        finishUserStop(uss);
17055                    }
17056                };
17057                // This is the result receiver for the initial stopping broadcast.
17058                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17059                    @Override
17060                    public void performReceive(Intent intent, int resultCode, String data,
17061                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17062                        // On to the next.
17063                        synchronized (ActivityManagerService.this) {
17064                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17065                                // Whoops, we are being started back up.  Abort, abort!
17066                                return;
17067                            }
17068                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17069                        }
17070                        mSystemServiceManager.stopUser(userId);
17071                        broadcastIntentLocked(null, null, shutdownIntent,
17072                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17073                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17074                    }
17075                };
17076                // Kick things off.
17077                broadcastIntentLocked(null, null, stoppingIntent,
17078                        null, stoppingReceiver, 0, null, null,
17079                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17080                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17081            } finally {
17082                Binder.restoreCallingIdentity(ident);
17083            }
17084        }
17085
17086        return ActivityManager.USER_OP_SUCCESS;
17087    }
17088
17089    void finishUserStop(UserStartedState uss) {
17090        final int userId = uss.mHandle.getIdentifier();
17091        boolean stopped;
17092        ArrayList<IStopUserCallback> callbacks;
17093        synchronized (this) {
17094            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17095            if (mStartedUsers.get(userId) != uss) {
17096                stopped = false;
17097            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17098                stopped = false;
17099            } else {
17100                stopped = true;
17101                // User can no longer run.
17102                mStartedUsers.remove(userId);
17103                mUserLru.remove(Integer.valueOf(userId));
17104                updateStartedUserArrayLocked();
17105
17106                // Clean up all state and processes associated with the user.
17107                // Kill all the processes for the user.
17108                forceStopUserLocked(userId, "finish user");
17109            }
17110        }
17111
17112        for (int i=0; i<callbacks.size(); i++) {
17113            try {
17114                if (stopped) callbacks.get(i).userStopped(userId);
17115                else callbacks.get(i).userStopAborted(userId);
17116            } catch (RemoteException e) {
17117            }
17118        }
17119
17120        if (stopped) {
17121            mSystemServiceManager.cleanupUser(userId);
17122            synchronized (this) {
17123                mStackSupervisor.removeUserLocked(userId);
17124            }
17125        }
17126    }
17127
17128    @Override
17129    public UserInfo getCurrentUser() {
17130        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17131                != PackageManager.PERMISSION_GRANTED) && (
17132                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17133                != PackageManager.PERMISSION_GRANTED)) {
17134            String msg = "Permission Denial: getCurrentUser() from pid="
17135                    + Binder.getCallingPid()
17136                    + ", uid=" + Binder.getCallingUid()
17137                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17138            Slog.w(TAG, msg);
17139            throw new SecurityException(msg);
17140        }
17141        synchronized (this) {
17142            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17143        }
17144    }
17145
17146    int getCurrentUserIdLocked() {
17147        return mCurrentUserId;
17148    }
17149
17150    @Override
17151    public boolean isUserRunning(int userId, boolean orStopped) {
17152        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17153                != PackageManager.PERMISSION_GRANTED) {
17154            String msg = "Permission Denial: isUserRunning() from pid="
17155                    + Binder.getCallingPid()
17156                    + ", uid=" + Binder.getCallingUid()
17157                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17158            Slog.w(TAG, msg);
17159            throw new SecurityException(msg);
17160        }
17161        synchronized (this) {
17162            return isUserRunningLocked(userId, orStopped);
17163        }
17164    }
17165
17166    boolean isUserRunningLocked(int userId, boolean orStopped) {
17167        UserStartedState state = mStartedUsers.get(userId);
17168        if (state == null) {
17169            return false;
17170        }
17171        if (orStopped) {
17172            return true;
17173        }
17174        return state.mState != UserStartedState.STATE_STOPPING
17175                && state.mState != UserStartedState.STATE_SHUTDOWN;
17176    }
17177
17178    @Override
17179    public int[] getRunningUserIds() {
17180        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17181                != PackageManager.PERMISSION_GRANTED) {
17182            String msg = "Permission Denial: isUserRunning() from pid="
17183                    + Binder.getCallingPid()
17184                    + ", uid=" + Binder.getCallingUid()
17185                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17186            Slog.w(TAG, msg);
17187            throw new SecurityException(msg);
17188        }
17189        synchronized (this) {
17190            return mStartedUserArray;
17191        }
17192    }
17193
17194    private void updateStartedUserArrayLocked() {
17195        int num = 0;
17196        for (int i=0; i<mStartedUsers.size();  i++) {
17197            UserStartedState uss = mStartedUsers.valueAt(i);
17198            // This list does not include stopping users.
17199            if (uss.mState != UserStartedState.STATE_STOPPING
17200                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17201                num++;
17202            }
17203        }
17204        mStartedUserArray = new int[num];
17205        num = 0;
17206        for (int i=0; i<mStartedUsers.size();  i++) {
17207            UserStartedState uss = mStartedUsers.valueAt(i);
17208            if (uss.mState != UserStartedState.STATE_STOPPING
17209                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17210                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17211                num++;
17212            }
17213        }
17214    }
17215
17216    @Override
17217    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17218        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17219                != PackageManager.PERMISSION_GRANTED) {
17220            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17221                    + Binder.getCallingPid()
17222                    + ", uid=" + Binder.getCallingUid()
17223                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17224            Slog.w(TAG, msg);
17225            throw new SecurityException(msg);
17226        }
17227
17228        mUserSwitchObservers.register(observer);
17229    }
17230
17231    @Override
17232    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17233        mUserSwitchObservers.unregister(observer);
17234    }
17235
17236    private boolean userExists(int userId) {
17237        if (userId == 0) {
17238            return true;
17239        }
17240        UserManagerService ums = getUserManagerLocked();
17241        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17242    }
17243
17244    int[] getUsersLocked() {
17245        UserManagerService ums = getUserManagerLocked();
17246        return ums != null ? ums.getUserIds() : new int[] { 0 };
17247    }
17248
17249    UserManagerService getUserManagerLocked() {
17250        if (mUserManager == null) {
17251            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17252            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17253        }
17254        return mUserManager;
17255    }
17256
17257    private int applyUserId(int uid, int userId) {
17258        return UserHandle.getUid(userId, uid);
17259    }
17260
17261    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17262        if (info == null) return null;
17263        ApplicationInfo newInfo = new ApplicationInfo(info);
17264        newInfo.uid = applyUserId(info.uid, userId);
17265        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17266                + info.packageName;
17267        return newInfo;
17268    }
17269
17270    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17271        if (aInfo == null
17272                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17273            return aInfo;
17274        }
17275
17276        ActivityInfo info = new ActivityInfo(aInfo);
17277        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17278        return info;
17279    }
17280
17281    private final class LocalService extends ActivityManagerInternal {
17282        @Override
17283        public void goingToSleep() {
17284            ActivityManagerService.this.goingToSleep();
17285        }
17286
17287        @Override
17288        public void wakingUp() {
17289            ActivityManagerService.this.wakingUp();
17290        }
17291    }
17292
17293    /**
17294     * An implementation of IAppTask, that allows an app to manage its own tasks via
17295     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17296     * only the process that calls getAppTasks() can call the AppTask methods.
17297     */
17298    class AppTaskImpl extends IAppTask.Stub {
17299        private int mTaskId;
17300        private int mCallingUid;
17301
17302        public AppTaskImpl(int taskId, int callingUid) {
17303            mTaskId = taskId;
17304            mCallingUid = callingUid;
17305        }
17306
17307        @Override
17308        public void finishAndRemoveTask() {
17309            // Ensure that we are called from the same process that created this AppTask
17310            if (mCallingUid != Binder.getCallingUid()) {
17311                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17312                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17313                return;
17314            }
17315
17316            synchronized (ActivityManagerService.this) {
17317                long origId = Binder.clearCallingIdentity();
17318                try {
17319                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17320                    if (tr != null) {
17321                        // Only kill the process if we are not a new document
17322                        int flags = tr.getBaseIntent().getFlags();
17323                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17324                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17325                        removeTaskByIdLocked(mTaskId,
17326                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17327                    }
17328                } finally {
17329                    Binder.restoreCallingIdentity(origId);
17330                }
17331            }
17332        }
17333
17334        @Override
17335        public ActivityManager.RecentTaskInfo getTaskInfo() {
17336            // Ensure that we are called from the same process that created this AppTask
17337            if (mCallingUid != Binder.getCallingUid()) {
17338                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17339                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17340                return null;
17341            }
17342
17343            synchronized (ActivityManagerService.this) {
17344                long origId = Binder.clearCallingIdentity();
17345                try {
17346                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17347                    if (tr != null) {
17348                        return createRecentTaskInfoFromTaskRecord(tr);
17349                    }
17350                } finally {
17351                    Binder.restoreCallingIdentity(origId);
17352                }
17353                return null;
17354            }
17355        }
17356    }
17357}
17358