ActivityManagerService.java revision 5b21454e6f81724ea48c2f85265ff107a8174005
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        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6048    }
6049
6050    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6051            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6052        if (pi.applicationInfo.uid == uid) {
6053            return true;
6054        } else if (!pi.exported) {
6055            return false;
6056        }
6057
6058        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6059        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6060        try {
6061            // check if target holds top-level <provider> permissions
6062            if (!readMet && pi.readPermission != null && considerUidPermissions
6063                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6064                readMet = true;
6065            }
6066            if (!writeMet && pi.writePermission != null && considerUidPermissions
6067                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6068                writeMet = true;
6069            }
6070
6071            // track if unprotected read/write is allowed; any denied
6072            // <path-permission> below removes this ability
6073            boolean allowDefaultRead = pi.readPermission == null;
6074            boolean allowDefaultWrite = pi.writePermission == null;
6075
6076            // check if target holds any <path-permission> that match uri
6077            final PathPermission[] pps = pi.pathPermissions;
6078            if (pps != null) {
6079                final String path = grantUri.uri.getPath();
6080                int i = pps.length;
6081                while (i > 0 && (!readMet || !writeMet)) {
6082                    i--;
6083                    PathPermission pp = pps[i];
6084                    if (pp.match(path)) {
6085                        if (!readMet) {
6086                            final String pprperm = pp.getReadPermission();
6087                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6088                                    + pprperm + " for " + pp.getPath()
6089                                    + ": match=" + pp.match(path)
6090                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6091                            if (pprperm != null) {
6092                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6093                                        == PERMISSION_GRANTED) {
6094                                    readMet = true;
6095                                } else {
6096                                    allowDefaultRead = false;
6097                                }
6098                            }
6099                        }
6100                        if (!writeMet) {
6101                            final String ppwperm = pp.getWritePermission();
6102                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6103                                    + ppwperm + " for " + pp.getPath()
6104                                    + ": match=" + pp.match(path)
6105                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6106                            if (ppwperm != null) {
6107                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6108                                        == PERMISSION_GRANTED) {
6109                                    writeMet = true;
6110                                } else {
6111                                    allowDefaultWrite = false;
6112                                }
6113                            }
6114                        }
6115                    }
6116                }
6117            }
6118
6119            // grant unprotected <provider> read/write, if not blocked by
6120            // <path-permission> above
6121            if (allowDefaultRead) readMet = true;
6122            if (allowDefaultWrite) writeMet = true;
6123
6124        } catch (RemoteException e) {
6125            return false;
6126        }
6127
6128        return readMet && writeMet;
6129    }
6130
6131    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6132        ProviderInfo pi = null;
6133        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6134        if (cpr != null) {
6135            pi = cpr.info;
6136        } else {
6137            try {
6138                pi = AppGlobals.getPackageManager().resolveContentProvider(
6139                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6140            } catch (RemoteException ex) {
6141            }
6142        }
6143        return pi;
6144    }
6145
6146    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6147        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6148        if (targetUris != null) {
6149            return targetUris.get(grantUri);
6150        }
6151        return null;
6152    }
6153
6154    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6155            String targetPkg, int targetUid, GrantUri grantUri) {
6156        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6157        if (targetUris == null) {
6158            targetUris = Maps.newArrayMap();
6159            mGrantedUriPermissions.put(targetUid, targetUris);
6160        }
6161
6162        UriPermission perm = targetUris.get(grantUri);
6163        if (perm == null) {
6164            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6165            targetUris.put(grantUri, perm);
6166        }
6167
6168        return perm;
6169    }
6170
6171    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6172            final int modeFlags) {
6173        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6174        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6175                : UriPermission.STRENGTH_OWNED;
6176
6177        // Root gets to do everything.
6178        if (uid == 0) {
6179            return true;
6180        }
6181
6182        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6183        if (perms == null) return false;
6184
6185        // First look for exact match
6186        final UriPermission exactPerm = perms.get(grantUri);
6187        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6188            return true;
6189        }
6190
6191        // No exact match, look for prefixes
6192        final int N = perms.size();
6193        for (int i = 0; i < N; i++) {
6194            final UriPermission perm = perms.valueAt(i);
6195            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6196                    && perm.getStrength(modeFlags) >= minStrength) {
6197                return true;
6198            }
6199        }
6200
6201        return false;
6202    }
6203
6204    @Override
6205    public int checkUriPermission(Uri uri, int pid, int uid,
6206            final int modeFlags, int userId) {
6207        enforceNotIsolatedCaller("checkUriPermission");
6208
6209        // Another redirected-binder-call permissions check as in
6210        // {@link checkComponentPermission}.
6211        Identity tlsIdentity = sCallerIdentity.get();
6212        if (tlsIdentity != null) {
6213            uid = tlsIdentity.uid;
6214            pid = tlsIdentity.pid;
6215        }
6216
6217        // Our own process gets to do everything.
6218        if (pid == MY_PID) {
6219            return PackageManager.PERMISSION_GRANTED;
6220        }
6221        synchronized (this) {
6222            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6223                    ? PackageManager.PERMISSION_GRANTED
6224                    : PackageManager.PERMISSION_DENIED;
6225        }
6226    }
6227
6228    /**
6229     * Check if the targetPkg can be granted permission to access uri by
6230     * the callingUid using the given modeFlags.  Throws a security exception
6231     * if callingUid is not allowed to do this.  Returns the uid of the target
6232     * if the URI permission grant should be performed; returns -1 if it is not
6233     * needed (for example targetPkg already has permission to access the URI).
6234     * If you already know the uid of the target, you can supply it in
6235     * lastTargetUid else set that to -1.
6236     */
6237    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6238            final int modeFlags, int lastTargetUid) {
6239        if (!Intent.isAccessUriMode(modeFlags)) {
6240            return -1;
6241        }
6242
6243        if (targetPkg != null) {
6244            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6245                    "Checking grant " + targetPkg + " permission to " + grantUri);
6246        }
6247
6248        final IPackageManager pm = AppGlobals.getPackageManager();
6249
6250        // If this is not a content: uri, we can't do anything with it.
6251        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6252            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6253                    "Can't grant URI permission for non-content URI: " + grantUri);
6254            return -1;
6255        }
6256
6257        final String authority = grantUri.uri.getAuthority();
6258        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6259        if (pi == null) {
6260            Slog.w(TAG, "No content provider found for permission check: " +
6261                    grantUri.uri.toSafeString());
6262            return -1;
6263        }
6264
6265        int targetUid = lastTargetUid;
6266        if (targetUid < 0 && targetPkg != null) {
6267            try {
6268                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6269                if (targetUid < 0) {
6270                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6271                            "Can't grant URI permission no uid for: " + targetPkg);
6272                    return -1;
6273                }
6274            } catch (RemoteException ex) {
6275                return -1;
6276            }
6277        }
6278
6279        if (targetUid >= 0) {
6280            // First...  does the target actually need this permission?
6281            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6282                // No need to grant the target this permission.
6283                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6284                        "Target " + targetPkg + " already has full permission to " + grantUri);
6285                return -1;
6286            }
6287        } else {
6288            // First...  there is no target package, so can anyone access it?
6289            boolean allowed = pi.exported;
6290            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6291                if (pi.readPermission != null) {
6292                    allowed = false;
6293                }
6294            }
6295            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6296                if (pi.writePermission != null) {
6297                    allowed = false;
6298                }
6299            }
6300            if (allowed) {
6301                return -1;
6302            }
6303        }
6304
6305        /* There is a special cross user grant if:
6306         * - The target is on another user.
6307         * - Apps on the current user can access the uri without any uid permissions.
6308         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6309         * grant uri permissions.
6310         */
6311        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6312                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6313                modeFlags, false /*without considering the uid permissions*/);
6314
6315        // Second...  is the provider allowing granting of URI permissions?
6316        if (!specialCrossUserGrant) {
6317            if (!pi.grantUriPermissions) {
6318                throw new SecurityException("Provider " + pi.packageName
6319                        + "/" + pi.name
6320                        + " does not allow granting of Uri permissions (uri "
6321                        + grantUri + ")");
6322            }
6323            if (pi.uriPermissionPatterns != null) {
6324                final int N = pi.uriPermissionPatterns.length;
6325                boolean allowed = false;
6326                for (int i=0; i<N; i++) {
6327                    if (pi.uriPermissionPatterns[i] != null
6328                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6329                        allowed = true;
6330                        break;
6331                    }
6332                }
6333                if (!allowed) {
6334                    throw new SecurityException("Provider " + pi.packageName
6335                            + "/" + pi.name
6336                            + " does not allow granting of permission to path of Uri "
6337                            + grantUri);
6338                }
6339            }
6340        }
6341
6342        // Third...  does the caller itself have permission to access
6343        // this uri?
6344        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6345            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6346                // Require they hold a strong enough Uri permission
6347                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6348                    throw new SecurityException("Uid " + callingUid
6349                            + " does not have permission to uri " + grantUri);
6350                }
6351            }
6352        }
6353        return targetUid;
6354    }
6355
6356    @Override
6357    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6358            final int modeFlags, int userId) {
6359        enforceNotIsolatedCaller("checkGrantUriPermission");
6360        synchronized(this) {
6361            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6362                    new GrantUri(userId, uri, false), modeFlags, -1);
6363        }
6364    }
6365
6366    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6367            final int modeFlags, UriPermissionOwner owner) {
6368        if (!Intent.isAccessUriMode(modeFlags)) {
6369            return;
6370        }
6371
6372        // So here we are: the caller has the assumed permission
6373        // to the uri, and the target doesn't.  Let's now give this to
6374        // the target.
6375
6376        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6377                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6378
6379        final String authority = grantUri.uri.getAuthority();
6380        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6381        if (pi == null) {
6382            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6383            return;
6384        }
6385
6386        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6387            grantUri.prefix = true;
6388        }
6389        final UriPermission perm = findOrCreateUriPermissionLocked(
6390                pi.packageName, targetPkg, targetUid, grantUri);
6391        perm.grantModes(modeFlags, owner);
6392    }
6393
6394    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6395            final int modeFlags, UriPermissionOwner owner) {
6396        if (targetPkg == null) {
6397            throw new NullPointerException("targetPkg");
6398        }
6399
6400        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6401                -1);
6402        if (targetUid < 0) {
6403            return;
6404        }
6405
6406        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6407                owner);
6408    }
6409
6410    static class NeededUriGrants extends ArrayList<GrantUri> {
6411        final String targetPkg;
6412        final int targetUid;
6413        final int flags;
6414
6415        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6416            this.targetPkg = targetPkg;
6417            this.targetUid = targetUid;
6418            this.flags = flags;
6419        }
6420    }
6421
6422    /**
6423     * Like checkGrantUriPermissionLocked, but takes an Intent.
6424     */
6425    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6426            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6427        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6428                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6429                + " clip=" + (intent != null ? intent.getClipData() : null)
6430                + " from " + intent + "; flags=0x"
6431                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6432
6433        if (targetPkg == null) {
6434            throw new NullPointerException("targetPkg");
6435        }
6436
6437        if (intent == null) {
6438            return null;
6439        }
6440        Uri data = intent.getData();
6441        ClipData clip = intent.getClipData();
6442        if (data == null && clip == null) {
6443            return null;
6444        }
6445        final IPackageManager pm = AppGlobals.getPackageManager();
6446        int targetUid;
6447        if (needed != null) {
6448            targetUid = needed.targetUid;
6449        } else {
6450            try {
6451                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6452            } catch (RemoteException ex) {
6453                return null;
6454            }
6455            if (targetUid < 0) {
6456                if (DEBUG_URI_PERMISSION) {
6457                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6458                            + " on user " + targetUserId);
6459                }
6460                return null;
6461            }
6462        }
6463        if (data != null) {
6464            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6465            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6466                    targetUid);
6467            if (targetUid > 0) {
6468                if (needed == null) {
6469                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6470                }
6471                needed.add(grantUri);
6472            }
6473        }
6474        if (clip != null) {
6475            for (int i=0; i<clip.getItemCount(); i++) {
6476                Uri uri = clip.getItemAt(i).getUri();
6477                if (uri != null) {
6478                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6479                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6480                            targetUid);
6481                    if (targetUid > 0) {
6482                        if (needed == null) {
6483                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6484                        }
6485                        needed.add(grantUri);
6486                    }
6487                } else {
6488                    Intent clipIntent = clip.getItemAt(i).getIntent();
6489                    if (clipIntent != null) {
6490                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6491                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6492                        if (newNeeded != null) {
6493                            needed = newNeeded;
6494                        }
6495                    }
6496                }
6497            }
6498        }
6499
6500        return needed;
6501    }
6502
6503    /**
6504     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6505     */
6506    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6507            UriPermissionOwner owner) {
6508        if (needed != null) {
6509            for (int i=0; i<needed.size(); i++) {
6510                GrantUri grantUri = needed.get(i);
6511                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6512                        grantUri, needed.flags, owner);
6513            }
6514        }
6515    }
6516
6517    void grantUriPermissionFromIntentLocked(int callingUid,
6518            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6519        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6520                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6521        if (needed == null) {
6522            return;
6523        }
6524
6525        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6526    }
6527
6528    @Override
6529    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6530            final int modeFlags, int userId) {
6531        enforceNotIsolatedCaller("grantUriPermission");
6532        GrantUri grantUri = new GrantUri(userId, uri, false);
6533        synchronized(this) {
6534            final ProcessRecord r = getRecordForAppLocked(caller);
6535            if (r == null) {
6536                throw new SecurityException("Unable to find app for caller "
6537                        + caller
6538                        + " when granting permission to uri " + grantUri);
6539            }
6540            if (targetPkg == null) {
6541                throw new IllegalArgumentException("null target");
6542            }
6543            if (grantUri == null) {
6544                throw new IllegalArgumentException("null uri");
6545            }
6546
6547            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6548                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6549                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6550                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6551
6552            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6553        }
6554    }
6555
6556    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6557        if (perm.modeFlags == 0) {
6558            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6559                    perm.targetUid);
6560            if (perms != null) {
6561                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6562                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6563
6564                perms.remove(perm.uri);
6565                if (perms.isEmpty()) {
6566                    mGrantedUriPermissions.remove(perm.targetUid);
6567                }
6568            }
6569        }
6570    }
6571
6572    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6573        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6574
6575        final IPackageManager pm = AppGlobals.getPackageManager();
6576        final String authority = grantUri.uri.getAuthority();
6577        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6578        if (pi == null) {
6579            Slog.w(TAG, "No content provider found for permission revoke: "
6580                    + grantUri.toSafeString());
6581            return;
6582        }
6583
6584        // Does the caller have this permission on the URI?
6585        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6586            // Right now, if you are not the original owner of the permission,
6587            // you are not allowed to revoke it.
6588            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6589                throw new SecurityException("Uid " + callingUid
6590                        + " does not have permission to uri " + grantUri);
6591            //}
6592        }
6593
6594        boolean persistChanged = false;
6595
6596        // Go through all of the permissions and remove any that match.
6597        int N = mGrantedUriPermissions.size();
6598        for (int i = 0; i < N; i++) {
6599            final int targetUid = mGrantedUriPermissions.keyAt(i);
6600            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6601
6602            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6603                final UriPermission perm = it.next();
6604                if (perm.uri.sourceUserId == grantUri.sourceUserId
6605                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6606                    if (DEBUG_URI_PERMISSION)
6607                        Slog.v(TAG,
6608                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6609                    persistChanged |= perm.revokeModes(
6610                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6611                    if (perm.modeFlags == 0) {
6612                        it.remove();
6613                    }
6614                }
6615            }
6616
6617            if (perms.isEmpty()) {
6618                mGrantedUriPermissions.remove(targetUid);
6619                N--;
6620                i--;
6621            }
6622        }
6623
6624        if (persistChanged) {
6625            schedulePersistUriGrants();
6626        }
6627    }
6628
6629    @Override
6630    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6631            int userId) {
6632        enforceNotIsolatedCaller("revokeUriPermission");
6633        synchronized(this) {
6634            final ProcessRecord r = getRecordForAppLocked(caller);
6635            if (r == null) {
6636                throw new SecurityException("Unable to find app for caller "
6637                        + caller
6638                        + " when revoking permission to uri " + uri);
6639            }
6640            if (uri == null) {
6641                Slog.w(TAG, "revokeUriPermission: null uri");
6642                return;
6643            }
6644
6645            if (!Intent.isAccessUriMode(modeFlags)) {
6646                return;
6647            }
6648
6649            final IPackageManager pm = AppGlobals.getPackageManager();
6650            final String authority = uri.getAuthority();
6651            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6652            if (pi == null) {
6653                Slog.w(TAG, "No content provider found for permission revoke: "
6654                        + uri.toSafeString());
6655                return;
6656            }
6657
6658            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6659        }
6660    }
6661
6662    /**
6663     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6664     * given package.
6665     *
6666     * @param packageName Package name to match, or {@code null} to apply to all
6667     *            packages.
6668     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6669     *            to all users.
6670     * @param persistable If persistable grants should be removed.
6671     */
6672    private void removeUriPermissionsForPackageLocked(
6673            String packageName, int userHandle, boolean persistable) {
6674        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6675            throw new IllegalArgumentException("Must narrow by either package or user");
6676        }
6677
6678        boolean persistChanged = false;
6679
6680        int N = mGrantedUriPermissions.size();
6681        for (int i = 0; i < N; i++) {
6682            final int targetUid = mGrantedUriPermissions.keyAt(i);
6683            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6684
6685            // Only inspect grants matching user
6686            if (userHandle == UserHandle.USER_ALL
6687                    || userHandle == UserHandle.getUserId(targetUid)) {
6688                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6689                    final UriPermission perm = it.next();
6690
6691                    // Only inspect grants matching package
6692                    if (packageName == null || perm.sourcePkg.equals(packageName)
6693                            || perm.targetPkg.equals(packageName)) {
6694                        persistChanged |= perm.revokeModes(
6695                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6696
6697                        // Only remove when no modes remain; any persisted grants
6698                        // will keep this alive.
6699                        if (perm.modeFlags == 0) {
6700                            it.remove();
6701                        }
6702                    }
6703                }
6704
6705                if (perms.isEmpty()) {
6706                    mGrantedUriPermissions.remove(targetUid);
6707                    N--;
6708                    i--;
6709                }
6710            }
6711        }
6712
6713        if (persistChanged) {
6714            schedulePersistUriGrants();
6715        }
6716    }
6717
6718    @Override
6719    public IBinder newUriPermissionOwner(String name) {
6720        enforceNotIsolatedCaller("newUriPermissionOwner");
6721        synchronized(this) {
6722            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6723            return owner.getExternalTokenLocked();
6724        }
6725    }
6726
6727    @Override
6728    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6729            final int modeFlags, int userId) {
6730        synchronized(this) {
6731            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6732            if (owner == null) {
6733                throw new IllegalArgumentException("Unknown owner: " + token);
6734            }
6735            if (fromUid != Binder.getCallingUid()) {
6736                if (Binder.getCallingUid() != Process.myUid()) {
6737                    // Only system code can grant URI permissions on behalf
6738                    // of other users.
6739                    throw new SecurityException("nice try");
6740                }
6741            }
6742            if (targetPkg == null) {
6743                throw new IllegalArgumentException("null target");
6744            }
6745            if (uri == null) {
6746                throw new IllegalArgumentException("null uri");
6747            }
6748
6749            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6750                    modeFlags, owner);
6751        }
6752    }
6753
6754    @Override
6755    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6756        synchronized(this) {
6757            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6758            if (owner == null) {
6759                throw new IllegalArgumentException("Unknown owner: " + token);
6760            }
6761
6762            if (uri == null) {
6763                owner.removeUriPermissionsLocked(mode);
6764            } else {
6765                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6766            }
6767        }
6768    }
6769
6770    private void schedulePersistUriGrants() {
6771        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6772            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6773                    10 * DateUtils.SECOND_IN_MILLIS);
6774        }
6775    }
6776
6777    private void writeGrantedUriPermissions() {
6778        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6779
6780        // Snapshot permissions so we can persist without lock
6781        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6782        synchronized (this) {
6783            final int size = mGrantedUriPermissions.size();
6784            for (int i = 0; i < size; i++) {
6785                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6786                for (UriPermission perm : perms.values()) {
6787                    if (perm.persistedModeFlags != 0) {
6788                        persist.add(perm.snapshot());
6789                    }
6790                }
6791            }
6792        }
6793
6794        FileOutputStream fos = null;
6795        try {
6796            fos = mGrantFile.startWrite();
6797
6798            XmlSerializer out = new FastXmlSerializer();
6799            out.setOutput(fos, "utf-8");
6800            out.startDocument(null, true);
6801            out.startTag(null, TAG_URI_GRANTS);
6802            for (UriPermission.Snapshot perm : persist) {
6803                out.startTag(null, TAG_URI_GRANT);
6804                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6805                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6806                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6807                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6808                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6809                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6810                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6811                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6812                out.endTag(null, TAG_URI_GRANT);
6813            }
6814            out.endTag(null, TAG_URI_GRANTS);
6815            out.endDocument();
6816
6817            mGrantFile.finishWrite(fos);
6818        } catch (IOException e) {
6819            if (fos != null) {
6820                mGrantFile.failWrite(fos);
6821            }
6822        }
6823    }
6824
6825    private void readGrantedUriPermissionsLocked() {
6826        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6827
6828        final long now = System.currentTimeMillis();
6829
6830        FileInputStream fis = null;
6831        try {
6832            fis = mGrantFile.openRead();
6833            final XmlPullParser in = Xml.newPullParser();
6834            in.setInput(fis, null);
6835
6836            int type;
6837            while ((type = in.next()) != END_DOCUMENT) {
6838                final String tag = in.getName();
6839                if (type == START_TAG) {
6840                    if (TAG_URI_GRANT.equals(tag)) {
6841                        final int sourceUserId;
6842                        final int targetUserId;
6843                        final int userHandle = readIntAttribute(in,
6844                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6845                        if (userHandle != UserHandle.USER_NULL) {
6846                            // For backwards compatibility.
6847                            sourceUserId = userHandle;
6848                            targetUserId = userHandle;
6849                        } else {
6850                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6851                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6852                        }
6853                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6854                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6855                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6856                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6857                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6858                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6859
6860                        // Sanity check that provider still belongs to source package
6861                        final ProviderInfo pi = getProviderInfoLocked(
6862                                uri.getAuthority(), sourceUserId);
6863                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6864                            int targetUid = -1;
6865                            try {
6866                                targetUid = AppGlobals.getPackageManager()
6867                                        .getPackageUid(targetPkg, targetUserId);
6868                            } catch (RemoteException e) {
6869                            }
6870                            if (targetUid != -1) {
6871                                final UriPermission perm = findOrCreateUriPermissionLocked(
6872                                        sourcePkg, targetPkg, targetUid,
6873                                        new GrantUri(sourceUserId, uri, prefix));
6874                                perm.initPersistedModes(modeFlags, createdTime);
6875                            }
6876                        } else {
6877                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6878                                    + " but instead found " + pi);
6879                        }
6880                    }
6881                }
6882            }
6883        } catch (FileNotFoundException e) {
6884            // Missing grants is okay
6885        } catch (IOException e) {
6886            Log.wtf(TAG, "Failed reading Uri grants", e);
6887        } catch (XmlPullParserException e) {
6888            Log.wtf(TAG, "Failed reading Uri grants", e);
6889        } finally {
6890            IoUtils.closeQuietly(fis);
6891        }
6892    }
6893
6894    @Override
6895    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6896        enforceNotIsolatedCaller("takePersistableUriPermission");
6897
6898        Preconditions.checkFlagsArgument(modeFlags,
6899                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6900
6901        synchronized (this) {
6902            final int callingUid = Binder.getCallingUid();
6903            boolean persistChanged = false;
6904            GrantUri grantUri = new GrantUri(userId, uri, false);
6905
6906            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6907                    new GrantUri(userId, uri, false));
6908            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6909                    new GrantUri(userId, uri, true));
6910
6911            final boolean exactValid = (exactPerm != null)
6912                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6913            final boolean prefixValid = (prefixPerm != null)
6914                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6915
6916            if (!(exactValid || prefixValid)) {
6917                throw new SecurityException("No persistable permission grants found for UID "
6918                        + callingUid + " and Uri " + grantUri.toSafeString());
6919            }
6920
6921            if (exactValid) {
6922                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6923            }
6924            if (prefixValid) {
6925                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6926            }
6927
6928            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6929
6930            if (persistChanged) {
6931                schedulePersistUriGrants();
6932            }
6933        }
6934    }
6935
6936    @Override
6937    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6938        enforceNotIsolatedCaller("releasePersistableUriPermission");
6939
6940        Preconditions.checkFlagsArgument(modeFlags,
6941                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6942
6943        synchronized (this) {
6944            final int callingUid = Binder.getCallingUid();
6945            boolean persistChanged = false;
6946
6947            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6948                    new GrantUri(userId, uri, false));
6949            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6950                    new GrantUri(userId, uri, true));
6951            if (exactPerm == null && prefixPerm == null) {
6952                throw new SecurityException("No permission grants found for UID " + callingUid
6953                        + " and Uri " + uri.toSafeString());
6954            }
6955
6956            if (exactPerm != null) {
6957                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6958                removeUriPermissionIfNeededLocked(exactPerm);
6959            }
6960            if (prefixPerm != null) {
6961                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6962                removeUriPermissionIfNeededLocked(prefixPerm);
6963            }
6964
6965            if (persistChanged) {
6966                schedulePersistUriGrants();
6967            }
6968        }
6969    }
6970
6971    /**
6972     * Prune any older {@link UriPermission} for the given UID until outstanding
6973     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6974     *
6975     * @return if any mutations occured that require persisting.
6976     */
6977    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6978        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6979        if (perms == null) return false;
6980        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6981
6982        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6983        for (UriPermission perm : perms.values()) {
6984            if (perm.persistedModeFlags != 0) {
6985                persisted.add(perm);
6986            }
6987        }
6988
6989        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6990        if (trimCount <= 0) return false;
6991
6992        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6993        for (int i = 0; i < trimCount; i++) {
6994            final UriPermission perm = persisted.get(i);
6995
6996            if (DEBUG_URI_PERMISSION) {
6997                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6998            }
6999
7000            perm.releasePersistableModes(~0);
7001            removeUriPermissionIfNeededLocked(perm);
7002        }
7003
7004        return true;
7005    }
7006
7007    @Override
7008    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7009            String packageName, boolean incoming) {
7010        enforceNotIsolatedCaller("getPersistedUriPermissions");
7011        Preconditions.checkNotNull(packageName, "packageName");
7012
7013        final int callingUid = Binder.getCallingUid();
7014        final IPackageManager pm = AppGlobals.getPackageManager();
7015        try {
7016            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7017            if (packageUid != callingUid) {
7018                throw new SecurityException(
7019                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7020            }
7021        } catch (RemoteException e) {
7022            throw new SecurityException("Failed to verify package name ownership");
7023        }
7024
7025        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7026        synchronized (this) {
7027            if (incoming) {
7028                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7029                        callingUid);
7030                if (perms == null) {
7031                    Slog.w(TAG, "No permission grants found for " + packageName);
7032                } else {
7033                    for (UriPermission perm : perms.values()) {
7034                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7035                            result.add(perm.buildPersistedPublicApiObject());
7036                        }
7037                    }
7038                }
7039            } else {
7040                final int size = mGrantedUriPermissions.size();
7041                for (int i = 0; i < size; i++) {
7042                    final ArrayMap<GrantUri, UriPermission> perms =
7043                            mGrantedUriPermissions.valueAt(i);
7044                    for (UriPermission perm : perms.values()) {
7045                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7046                            result.add(perm.buildPersistedPublicApiObject());
7047                        }
7048                    }
7049                }
7050            }
7051        }
7052        return new ParceledListSlice<android.content.UriPermission>(result);
7053    }
7054
7055    @Override
7056    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7057        synchronized (this) {
7058            ProcessRecord app =
7059                who != null ? getRecordForAppLocked(who) : null;
7060            if (app == null) return;
7061
7062            Message msg = Message.obtain();
7063            msg.what = WAIT_FOR_DEBUGGER_MSG;
7064            msg.obj = app;
7065            msg.arg1 = waiting ? 1 : 0;
7066            mHandler.sendMessage(msg);
7067        }
7068    }
7069
7070    @Override
7071    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7072        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7073        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7074        outInfo.availMem = Process.getFreeMemory();
7075        outInfo.totalMem = Process.getTotalMemory();
7076        outInfo.threshold = homeAppMem;
7077        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7078        outInfo.hiddenAppThreshold = cachedAppMem;
7079        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7080                ProcessList.SERVICE_ADJ);
7081        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7082                ProcessList.VISIBLE_APP_ADJ);
7083        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7084                ProcessList.FOREGROUND_APP_ADJ);
7085    }
7086
7087    // =========================================================
7088    // TASK MANAGEMENT
7089    // =========================================================
7090
7091    @Override
7092    public List<IAppTask> getAppTasks() {
7093        int callingUid = Binder.getCallingUid();
7094        long ident = Binder.clearCallingIdentity();
7095        synchronized(this) {
7096            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7097            try {
7098                if (localLOGV) Slog.v(TAG, "getAppTasks");
7099
7100                final int N = mRecentTasks.size();
7101                for (int i = 0; i < N; i++) {
7102                    TaskRecord tr = mRecentTasks.get(i);
7103                    // Skip tasks that are not created by the caller
7104                    if (tr.creatorUid == callingUid) {
7105                        ActivityManager.RecentTaskInfo taskInfo =
7106                                createRecentTaskInfoFromTaskRecord(tr);
7107                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7108                        list.add(taskImpl);
7109                    }
7110                }
7111            } finally {
7112                Binder.restoreCallingIdentity(ident);
7113            }
7114            return list;
7115        }
7116    }
7117
7118    @Override
7119    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7120        final int callingUid = Binder.getCallingUid();
7121        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7122
7123        synchronized(this) {
7124            if (localLOGV) Slog.v(
7125                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7126
7127            final boolean allowed = checkCallingPermission(
7128                    android.Manifest.permission.GET_TASKS)
7129                    == PackageManager.PERMISSION_GRANTED;
7130            if (!allowed) {
7131                Slog.w(TAG, "getTasks: caller " + callingUid
7132                        + " does not hold GET_TASKS; limiting output");
7133            }
7134
7135            // TODO: Improve with MRU list from all ActivityStacks.
7136            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7137        }
7138
7139        return list;
7140    }
7141
7142    TaskRecord getMostRecentTask() {
7143        return mRecentTasks.get(0);
7144    }
7145
7146    /**
7147     * Creates a new RecentTaskInfo from a TaskRecord.
7148     */
7149    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7150        // Update the task description to reflect any changes in the task stack
7151        tr.updateTaskDescription();
7152
7153        // Compose the recent task info
7154        ActivityManager.RecentTaskInfo rti
7155                = new ActivityManager.RecentTaskInfo();
7156        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7157        rti.persistentId = tr.taskId;
7158        rti.baseIntent = new Intent(tr.getBaseIntent());
7159        rti.origActivity = tr.origActivity;
7160        rti.description = tr.lastDescription;
7161        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7162        rti.userId = tr.userId;
7163        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7164        return rti;
7165    }
7166
7167    @Override
7168    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7169            int flags, int userId) {
7170        final int callingUid = Binder.getCallingUid();
7171        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7172                false, true, "getRecentTasks", null);
7173
7174        synchronized (this) {
7175            final boolean allowed = checkCallingPermission(
7176                    android.Manifest.permission.GET_TASKS)
7177                    == PackageManager.PERMISSION_GRANTED;
7178            if (!allowed) {
7179                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7180                        + " does not hold GET_TASKS; limiting output");
7181            }
7182            final boolean detailed = checkCallingPermission(
7183                    android.Manifest.permission.GET_DETAILED_TASKS)
7184                    == PackageManager.PERMISSION_GRANTED;
7185
7186            IPackageManager pm = AppGlobals.getPackageManager();
7187
7188            final int N = mRecentTasks.size();
7189            ArrayList<ActivityManager.RecentTaskInfo> res
7190                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7191                            maxNum < N ? maxNum : N);
7192
7193            final Set<Integer> includedUsers;
7194            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7195                includedUsers = getProfileIdsLocked(userId);
7196            } else {
7197                includedUsers = new HashSet<Integer>();
7198            }
7199            includedUsers.add(Integer.valueOf(userId));
7200            for (int i=0; i<N && maxNum > 0; i++) {
7201                TaskRecord tr = mRecentTasks.get(i);
7202                // Only add calling user or related users recent tasks
7203                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7204
7205                // Return the entry if desired by the caller.  We always return
7206                // the first entry, because callers always expect this to be the
7207                // foreground app.  We may filter others if the caller has
7208                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7209                // we should exclude the entry.
7210
7211                if (i == 0
7212                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7213                        || (tr.intent == null)
7214                        || ((tr.intent.getFlags()
7215                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7216                    if (!allowed) {
7217                        // If the caller doesn't have the GET_TASKS permission, then only
7218                        // allow them to see a small subset of tasks -- their own and home.
7219                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7220                            continue;
7221                        }
7222                    }
7223
7224                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7225                    if (!detailed) {
7226                        rti.baseIntent.replaceExtras((Bundle)null);
7227                    }
7228
7229                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7230                        // Check whether this activity is currently available.
7231                        try {
7232                            if (rti.origActivity != null) {
7233                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7234                                        == null) {
7235                                    continue;
7236                                }
7237                            } else if (rti.baseIntent != null) {
7238                                if (pm.queryIntentActivities(rti.baseIntent,
7239                                        null, 0, userId) == null) {
7240                                    continue;
7241                                }
7242                            }
7243                        } catch (RemoteException e) {
7244                            // Will never happen.
7245                        }
7246                    }
7247
7248                    res.add(rti);
7249                    maxNum--;
7250                }
7251            }
7252            return res;
7253        }
7254    }
7255
7256    private TaskRecord recentTaskForIdLocked(int id) {
7257        final int N = mRecentTasks.size();
7258            for (int i=0; i<N; i++) {
7259                TaskRecord tr = mRecentTasks.get(i);
7260                if (tr.taskId == id) {
7261                    return tr;
7262                }
7263            }
7264            return null;
7265    }
7266
7267    @Override
7268    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7269        synchronized (this) {
7270            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7271                    "getTaskThumbnails()");
7272            TaskRecord tr = recentTaskForIdLocked(id);
7273            if (tr != null) {
7274                return tr.getTaskThumbnailsLocked();
7275            }
7276        }
7277        return null;
7278    }
7279
7280    @Override
7281    public Bitmap getTaskTopThumbnail(int id) {
7282        synchronized (this) {
7283            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7284                    "getTaskTopThumbnail()");
7285            TaskRecord tr = recentTaskForIdLocked(id);
7286            if (tr != null) {
7287                return tr.getTaskTopThumbnailLocked();
7288            }
7289        }
7290        return null;
7291    }
7292
7293    @Override
7294    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7295        synchronized (this) {
7296            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7297            if (r != null) {
7298                r.taskDescription = td;
7299                r.task.updateTaskDescription();
7300            }
7301        }
7302    }
7303
7304    @Override
7305    public boolean removeSubTask(int taskId, int subTaskIndex) {
7306        synchronized (this) {
7307            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7308                    "removeSubTask()");
7309            long ident = Binder.clearCallingIdentity();
7310            try {
7311                TaskRecord tr = recentTaskForIdLocked(taskId);
7312                if (tr != null) {
7313                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7314                }
7315                return false;
7316            } finally {
7317                Binder.restoreCallingIdentity(ident);
7318            }
7319        }
7320    }
7321
7322    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7323        if (!pr.killedByAm) {
7324            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7325            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7326                    pr.processName, pr.setAdj, reason);
7327            pr.killedByAm = true;
7328            Process.killProcessQuiet(pr.pid);
7329        }
7330    }
7331
7332    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7333        tr.disposeThumbnail();
7334        mRecentTasks.remove(tr);
7335        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7336        Intent baseIntent = new Intent(
7337                tr.intent != null ? tr.intent : tr.affinityIntent);
7338        ComponentName component = baseIntent.getComponent();
7339        if (component == null) {
7340            Slog.w(TAG, "Now component for base intent of task: " + tr);
7341            return;
7342        }
7343
7344        // Find any running services associated with this app.
7345        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7346
7347        if (killProcesses) {
7348            // Find any running processes associated with this app.
7349            final String pkg = component.getPackageName();
7350            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7351            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7352            for (int i=0; i<pmap.size(); i++) {
7353                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7354                for (int j=0; j<uids.size(); j++) {
7355                    ProcessRecord proc = uids.valueAt(j);
7356                    if (proc.userId != tr.userId) {
7357                        continue;
7358                    }
7359                    if (!proc.pkgList.containsKey(pkg)) {
7360                        continue;
7361                    }
7362                    procs.add(proc);
7363                }
7364            }
7365
7366            // Kill the running processes.
7367            for (int i=0; i<procs.size(); i++) {
7368                ProcessRecord pr = procs.get(i);
7369                if (pr == mHomeProcess) {
7370                    // Don't kill the home process along with tasks from the same package.
7371                    continue;
7372                }
7373                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7374                    killUnneededProcessLocked(pr, "remove task");
7375                } else {
7376                    pr.waitingToKill = "remove task";
7377                }
7378            }
7379        }
7380    }
7381
7382    /**
7383     * Removes the task with the specified task id.
7384     *
7385     * @param taskId Identifier of the task to be removed.
7386     * @param flags Additional operational flags.  May be 0 or
7387     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7388     * @return Returns true if the given task was found and removed.
7389     */
7390    private boolean removeTaskByIdLocked(int taskId, int flags) {
7391        TaskRecord tr = recentTaskForIdLocked(taskId);
7392        if (tr != null) {
7393            tr.removeTaskActivitiesLocked(-1, false);
7394            cleanUpRemovedTaskLocked(tr, flags);
7395            if (tr.isPersistable) {
7396                notifyTaskPersisterLocked(tr, true);
7397            }
7398            return true;
7399        }
7400        return false;
7401    }
7402
7403    @Override
7404    public boolean removeTask(int taskId, int flags) {
7405        synchronized (this) {
7406            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7407                    "removeTask()");
7408            long ident = Binder.clearCallingIdentity();
7409            try {
7410                return removeTaskByIdLocked(taskId, flags);
7411            } finally {
7412                Binder.restoreCallingIdentity(ident);
7413            }
7414        }
7415    }
7416
7417    /**
7418     * TODO: Add mController hook
7419     */
7420    @Override
7421    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7422        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7423                "moveTaskToFront()");
7424
7425        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7426        synchronized(this) {
7427            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7428                    Binder.getCallingUid(), "Task to front")) {
7429                ActivityOptions.abort(options);
7430                return;
7431            }
7432            final long origId = Binder.clearCallingIdentity();
7433            try {
7434                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7435                if (task == null) {
7436                    return;
7437                }
7438                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7439                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7440                    return;
7441                }
7442                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7443            } finally {
7444                Binder.restoreCallingIdentity(origId);
7445            }
7446            ActivityOptions.abort(options);
7447        }
7448    }
7449
7450    @Override
7451    public void moveTaskToBack(int taskId) {
7452        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7453                "moveTaskToBack()");
7454
7455        synchronized(this) {
7456            TaskRecord tr = recentTaskForIdLocked(taskId);
7457            if (tr != null) {
7458                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7459                ActivityStack stack = tr.stack;
7460                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7461                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7462                            Binder.getCallingUid(), "Task to back")) {
7463                        return;
7464                    }
7465                }
7466                final long origId = Binder.clearCallingIdentity();
7467                try {
7468                    stack.moveTaskToBackLocked(taskId, null);
7469                } finally {
7470                    Binder.restoreCallingIdentity(origId);
7471                }
7472            }
7473        }
7474    }
7475
7476    /**
7477     * Moves an activity, and all of the other activities within the same task, to the bottom
7478     * of the history stack.  The activity's order within the task is unchanged.
7479     *
7480     * @param token A reference to the activity we wish to move
7481     * @param nonRoot If false then this only works if the activity is the root
7482     *                of a task; if true it will work for any activity in a task.
7483     * @return Returns true if the move completed, false if not.
7484     */
7485    @Override
7486    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7487        enforceNotIsolatedCaller("moveActivityTaskToBack");
7488        synchronized(this) {
7489            final long origId = Binder.clearCallingIdentity();
7490            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7491            if (taskId >= 0) {
7492                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7493            }
7494            Binder.restoreCallingIdentity(origId);
7495        }
7496        return false;
7497    }
7498
7499    @Override
7500    public void moveTaskBackwards(int task) {
7501        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7502                "moveTaskBackwards()");
7503
7504        synchronized(this) {
7505            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7506                    Binder.getCallingUid(), "Task backwards")) {
7507                return;
7508            }
7509            final long origId = Binder.clearCallingIdentity();
7510            moveTaskBackwardsLocked(task);
7511            Binder.restoreCallingIdentity(origId);
7512        }
7513    }
7514
7515    private final void moveTaskBackwardsLocked(int task) {
7516        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7517    }
7518
7519    @Override
7520    public IBinder getHomeActivityToken() throws RemoteException {
7521        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7522                "getHomeActivityToken()");
7523        synchronized (this) {
7524            return mStackSupervisor.getHomeActivityToken();
7525        }
7526    }
7527
7528    @Override
7529    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7530            IActivityContainerCallback callback) throws RemoteException {
7531        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7532                "createActivityContainer()");
7533        synchronized (this) {
7534            if (parentActivityToken == null) {
7535                throw new IllegalArgumentException("parent token must not be null");
7536            }
7537            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7538            if (r == null) {
7539                return null;
7540            }
7541            if (callback == null) {
7542                throw new IllegalArgumentException("callback must not be null");
7543            }
7544            return mStackSupervisor.createActivityContainer(r, callback);
7545        }
7546    }
7547
7548    @Override
7549    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7550        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7551                "deleteActivityContainer()");
7552        synchronized (this) {
7553            mStackSupervisor.deleteActivityContainer(container);
7554        }
7555    }
7556
7557    @Override
7558    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7559            throws RemoteException {
7560        synchronized (this) {
7561            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7562            if (stack != null) {
7563                return stack.mActivityContainer;
7564            }
7565            return null;
7566        }
7567    }
7568
7569    @Override
7570    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7571        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7572                "moveTaskToStack()");
7573        if (stackId == HOME_STACK_ID) {
7574            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7575                    new RuntimeException("here").fillInStackTrace());
7576        }
7577        synchronized (this) {
7578            long ident = Binder.clearCallingIdentity();
7579            try {
7580                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7581                        + stackId + " toTop=" + toTop);
7582                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7583            } finally {
7584                Binder.restoreCallingIdentity(ident);
7585            }
7586        }
7587    }
7588
7589    @Override
7590    public void resizeStack(int stackBoxId, Rect bounds) {
7591        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7592                "resizeStackBox()");
7593        long ident = Binder.clearCallingIdentity();
7594        try {
7595            mWindowManager.resizeStack(stackBoxId, bounds);
7596        } finally {
7597            Binder.restoreCallingIdentity(ident);
7598        }
7599    }
7600
7601    @Override
7602    public List<StackInfo> getAllStackInfos() {
7603        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7604                "getAllStackInfos()");
7605        long ident = Binder.clearCallingIdentity();
7606        try {
7607            synchronized (this) {
7608                return mStackSupervisor.getAllStackInfosLocked();
7609            }
7610        } finally {
7611            Binder.restoreCallingIdentity(ident);
7612        }
7613    }
7614
7615    @Override
7616    public StackInfo getStackInfo(int stackId) {
7617        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7618                "getStackInfo()");
7619        long ident = Binder.clearCallingIdentity();
7620        try {
7621            synchronized (this) {
7622                return mStackSupervisor.getStackInfoLocked(stackId);
7623            }
7624        } finally {
7625            Binder.restoreCallingIdentity(ident);
7626        }
7627    }
7628
7629    @Override
7630    public boolean isInHomeStack(int taskId) {
7631        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7632                "getStackInfo()");
7633        long ident = Binder.clearCallingIdentity();
7634        try {
7635            synchronized (this) {
7636                TaskRecord tr = recentTaskForIdLocked(taskId);
7637                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7638            }
7639        } finally {
7640            Binder.restoreCallingIdentity(ident);
7641        }
7642    }
7643
7644    @Override
7645    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7646        synchronized(this) {
7647            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7648        }
7649    }
7650
7651    private boolean isLockTaskAuthorized(ComponentName name) {
7652        final DevicePolicyManager dpm = (DevicePolicyManager)
7653                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7654        return dpm != null && dpm.isLockTaskPermitted(name);
7655    }
7656
7657    private void startLockTaskMode(TaskRecord task) {
7658        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7659            return;
7660        }
7661        long ident = Binder.clearCallingIdentity();
7662        try {
7663            synchronized (this) {
7664                // Since we lost lock on task, make sure it is still there.
7665                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7666                if (task != null) {
7667                    mStackSupervisor.setLockTaskModeLocked(task);
7668                }
7669            }
7670        } finally {
7671            Binder.restoreCallingIdentity(ident);
7672        }
7673    }
7674
7675    @Override
7676    public void startLockTaskMode(int taskId) {
7677        long ident = Binder.clearCallingIdentity();
7678        try {
7679            final TaskRecord task;
7680            synchronized (this) {
7681                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7682            }
7683            if (task != null) {
7684                startLockTaskMode(task);
7685            }
7686        } finally {
7687            Binder.restoreCallingIdentity(ident);
7688        }
7689    }
7690
7691    @Override
7692    public void startLockTaskMode(IBinder token) {
7693        long ident = Binder.clearCallingIdentity();
7694        try {
7695            final TaskRecord task;
7696            synchronized (this) {
7697                final ActivityRecord r = ActivityRecord.forToken(token);
7698                if (r == null) {
7699                    return;
7700                }
7701                task = r.task;
7702            }
7703            if (task != null) {
7704                startLockTaskMode(task);
7705            }
7706        } finally {
7707            Binder.restoreCallingIdentity(ident);
7708        }
7709    }
7710
7711    @Override
7712    public void stopLockTaskMode() {
7713        // Check if the calling task is eligible to use lock task
7714        final int uid = Binder.getCallingUid();
7715        try {
7716            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7717            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7718                return;
7719            }
7720        } catch (RemoteException e) {
7721            Log.d(TAG, "stopLockTaskMode " + e);
7722            return;
7723        }
7724        // Stop lock task
7725        synchronized (this) {
7726            mStackSupervisor.setLockTaskModeLocked(null);
7727        }
7728    }
7729
7730    @Override
7731    public boolean isInLockTaskMode() {
7732        synchronized (this) {
7733            return mStackSupervisor.isInLockTaskMode();
7734        }
7735    }
7736
7737    // =========================================================
7738    // CONTENT PROVIDERS
7739    // =========================================================
7740
7741    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7742        List<ProviderInfo> providers = null;
7743        try {
7744            providers = AppGlobals.getPackageManager().
7745                queryContentProviders(app.processName, app.uid,
7746                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7747        } catch (RemoteException ex) {
7748        }
7749        if (DEBUG_MU)
7750            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7751        int userId = app.userId;
7752        if (providers != null) {
7753            int N = providers.size();
7754            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7755            for (int i=0; i<N; i++) {
7756                ProviderInfo cpi =
7757                    (ProviderInfo)providers.get(i);
7758                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7759                        cpi.name, cpi.flags);
7760                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7761                    // This is a singleton provider, but a user besides the
7762                    // default user is asking to initialize a process it runs
7763                    // in...  well, no, it doesn't actually run in this process,
7764                    // it runs in the process of the default user.  Get rid of it.
7765                    providers.remove(i);
7766                    N--;
7767                    i--;
7768                    continue;
7769                }
7770
7771                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7772                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7773                if (cpr == null) {
7774                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7775                    mProviderMap.putProviderByClass(comp, cpr);
7776                }
7777                if (DEBUG_MU)
7778                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7779                app.pubProviders.put(cpi.name, cpr);
7780                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7781                    // Don't add this if it is a platform component that is marked
7782                    // to run in multiple processes, because this is actually
7783                    // part of the framework so doesn't make sense to track as a
7784                    // separate apk in the process.
7785                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7786                }
7787                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7788            }
7789        }
7790        return providers;
7791    }
7792
7793    /**
7794     * Check if {@link ProcessRecord} has a possible chance at accessing the
7795     * given {@link ProviderInfo}. Final permission checking is always done
7796     * in {@link ContentProvider}.
7797     */
7798    private final String checkContentProviderPermissionLocked(
7799            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7800        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7801        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7802        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7803        // Looking for cross-user grants before to enforce the typical cross-users permissions
7804        if (userId != UserHandle.getUserId(callingUid)) {
7805            if (perms != null) {
7806                for (GrantUri grantUri : perms.keySet()) {
7807                    if (grantUri.sourceUserId == userId) {
7808                        String authority = grantUri.uri.getAuthority();
7809                        if (authority.equals(cpi.authority)) {
7810                            return null;
7811                        }
7812                    }
7813                }
7814            }
7815        }
7816        if (checkUser) {
7817            userId = handleIncomingUser(callingPid, callingUid, userId,
7818                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7819        }
7820        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7821                cpi.applicationInfo.uid, cpi.exported)
7822                == PackageManager.PERMISSION_GRANTED) {
7823            return null;
7824        }
7825        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7826                cpi.applicationInfo.uid, cpi.exported)
7827                == PackageManager.PERMISSION_GRANTED) {
7828            return null;
7829        }
7830
7831        PathPermission[] pps = cpi.pathPermissions;
7832        if (pps != null) {
7833            int i = pps.length;
7834            while (i > 0) {
7835                i--;
7836                PathPermission pp = pps[i];
7837                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7838                        cpi.applicationInfo.uid, cpi.exported)
7839                        == PackageManager.PERMISSION_GRANTED) {
7840                    return null;
7841                }
7842                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7843                        cpi.applicationInfo.uid, cpi.exported)
7844                        == PackageManager.PERMISSION_GRANTED) {
7845                    return null;
7846                }
7847            }
7848        }
7849
7850        if (perms != null) {
7851            for (GrantUri grantUri : perms.keySet()) {
7852                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7853                    return null;
7854                }
7855            }
7856        }
7857
7858        String msg;
7859        if (!cpi.exported) {
7860            msg = "Permission Denial: opening provider " + cpi.name
7861                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7862                    + ", uid=" + callingUid + ") that is not exported from uid "
7863                    + cpi.applicationInfo.uid;
7864        } else {
7865            msg = "Permission Denial: opening provider " + cpi.name
7866                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7867                    + ", uid=" + callingUid + ") requires "
7868                    + cpi.readPermission + " or " + cpi.writePermission;
7869        }
7870        Slog.w(TAG, msg);
7871        return msg;
7872    }
7873
7874    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7875            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7876        if (r != null) {
7877            for (int i=0; i<r.conProviders.size(); i++) {
7878                ContentProviderConnection conn = r.conProviders.get(i);
7879                if (conn.provider == cpr) {
7880                    if (DEBUG_PROVIDER) Slog.v(TAG,
7881                            "Adding provider requested by "
7882                            + r.processName + " from process "
7883                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7884                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7885                    if (stable) {
7886                        conn.stableCount++;
7887                        conn.numStableIncs++;
7888                    } else {
7889                        conn.unstableCount++;
7890                        conn.numUnstableIncs++;
7891                    }
7892                    return conn;
7893                }
7894            }
7895            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7896            if (stable) {
7897                conn.stableCount = 1;
7898                conn.numStableIncs = 1;
7899            } else {
7900                conn.unstableCount = 1;
7901                conn.numUnstableIncs = 1;
7902            }
7903            cpr.connections.add(conn);
7904            r.conProviders.add(conn);
7905            return conn;
7906        }
7907        cpr.addExternalProcessHandleLocked(externalProcessToken);
7908        return null;
7909    }
7910
7911    boolean decProviderCountLocked(ContentProviderConnection conn,
7912            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7913        if (conn != null) {
7914            cpr = conn.provider;
7915            if (DEBUG_PROVIDER) Slog.v(TAG,
7916                    "Removing provider requested by "
7917                    + conn.client.processName + " from process "
7918                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7919                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7920            if (stable) {
7921                conn.stableCount--;
7922            } else {
7923                conn.unstableCount--;
7924            }
7925            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7926                cpr.connections.remove(conn);
7927                conn.client.conProviders.remove(conn);
7928                return true;
7929            }
7930            return false;
7931        }
7932        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7933        return false;
7934    }
7935
7936    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7937            String name, IBinder token, boolean stable, int userId) {
7938        ContentProviderRecord cpr;
7939        ContentProviderConnection conn = null;
7940        ProviderInfo cpi = null;
7941
7942        synchronized(this) {
7943            ProcessRecord r = null;
7944            if (caller != null) {
7945                r = getRecordForAppLocked(caller);
7946                if (r == null) {
7947                    throw new SecurityException(
7948                            "Unable to find app for caller " + caller
7949                          + " (pid=" + Binder.getCallingPid()
7950                          + ") when getting content provider " + name);
7951                }
7952            }
7953
7954            boolean checkCrossUser = true;
7955
7956            // First check if this content provider has been published...
7957            cpr = mProviderMap.getProviderByName(name, userId);
7958            // If that didn't work, check if it exists for user 0 and then
7959            // verify that it's a singleton provider before using it.
7960            if (cpr == null && userId != UserHandle.USER_OWNER) {
7961                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
7962                if (cpr != null) {
7963                    cpi = cpr.info;
7964                    if (isSingleton(cpi.processName, cpi.applicationInfo,
7965                            cpi.name, cpi.flags)
7966                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
7967                        userId = UserHandle.USER_OWNER;
7968                        checkCrossUser = false;
7969                    } else {
7970                        cpr = null;
7971                        cpi = null;
7972                    }
7973                }
7974            }
7975
7976            boolean providerRunning = cpr != null;
7977            if (providerRunning) {
7978                cpi = cpr.info;
7979                String msg;
7980                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
7981                        != null) {
7982                    throw new SecurityException(msg);
7983                }
7984
7985                if (r != null && cpr.canRunHere(r)) {
7986                    // This provider has been published or is in the process
7987                    // of being published...  but it is also allowed to run
7988                    // in the caller's process, so don't make a connection
7989                    // and just let the caller instantiate its own instance.
7990                    ContentProviderHolder holder = cpr.newHolder(null);
7991                    // don't give caller the provider object, it needs
7992                    // to make its own.
7993                    holder.provider = null;
7994                    return holder;
7995                }
7996
7997                final long origId = Binder.clearCallingIdentity();
7998
7999                // In this case the provider instance already exists, so we can
8000                // return it right away.
8001                conn = incProviderCountLocked(r, cpr, token, stable);
8002                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8003                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8004                        // If this is a perceptible app accessing the provider,
8005                        // make sure to count it as being accessed and thus
8006                        // back up on the LRU list.  This is good because
8007                        // content providers are often expensive to start.
8008                        updateLruProcessLocked(cpr.proc, false, null);
8009                    }
8010                }
8011
8012                if (cpr.proc != null) {
8013                    if (false) {
8014                        if (cpr.name.flattenToShortString().equals(
8015                                "com.android.providers.calendar/.CalendarProvider2")) {
8016                            Slog.v(TAG, "****************** KILLING "
8017                                + cpr.name.flattenToShortString());
8018                            Process.killProcess(cpr.proc.pid);
8019                        }
8020                    }
8021                    boolean success = updateOomAdjLocked(cpr.proc);
8022                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8023                    // NOTE: there is still a race here where a signal could be
8024                    // pending on the process even though we managed to update its
8025                    // adj level.  Not sure what to do about this, but at least
8026                    // the race is now smaller.
8027                    if (!success) {
8028                        // Uh oh...  it looks like the provider's process
8029                        // has been killed on us.  We need to wait for a new
8030                        // process to be started, and make sure its death
8031                        // doesn't kill our process.
8032                        Slog.i(TAG,
8033                                "Existing provider " + cpr.name.flattenToShortString()
8034                                + " is crashing; detaching " + r);
8035                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8036                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8037                        if (!lastRef) {
8038                            // This wasn't the last ref our process had on
8039                            // the provider...  we have now been killed, bail.
8040                            return null;
8041                        }
8042                        providerRunning = false;
8043                        conn = null;
8044                    }
8045                }
8046
8047                Binder.restoreCallingIdentity(origId);
8048            }
8049
8050            boolean singleton;
8051            if (!providerRunning) {
8052                try {
8053                    cpi = AppGlobals.getPackageManager().
8054                        resolveContentProvider(name,
8055                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8056                } catch (RemoteException ex) {
8057                }
8058                if (cpi == null) {
8059                    return null;
8060                }
8061                // If the provider is a singleton AND
8062                // (it's a call within the same user || the provider is a
8063                // privileged app)
8064                // Then allow connecting to the singleton provider
8065                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8066                        cpi.name, cpi.flags)
8067                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8068                if (singleton) {
8069                    userId = UserHandle.USER_OWNER;
8070                }
8071                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8072
8073                String msg;
8074                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8075                        != null) {
8076                    throw new SecurityException(msg);
8077                }
8078
8079                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8080                        && !cpi.processName.equals("system")) {
8081                    // If this content provider does not run in the system
8082                    // process, and the system is not yet ready to run other
8083                    // processes, then fail fast instead of hanging.
8084                    throw new IllegalArgumentException(
8085                            "Attempt to launch content provider before system ready");
8086                }
8087
8088                // Make sure that the user who owns this provider is started.  If not,
8089                // we don't want to allow it to run.
8090                if (mStartedUsers.get(userId) == null) {
8091                    Slog.w(TAG, "Unable to launch app "
8092                            + cpi.applicationInfo.packageName + "/"
8093                            + cpi.applicationInfo.uid + " for provider "
8094                            + name + ": user " + userId + " is stopped");
8095                    return null;
8096                }
8097
8098                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8099                cpr = mProviderMap.getProviderByClass(comp, userId);
8100                final boolean firstClass = cpr == null;
8101                if (firstClass) {
8102                    try {
8103                        ApplicationInfo ai =
8104                            AppGlobals.getPackageManager().
8105                                getApplicationInfo(
8106                                        cpi.applicationInfo.packageName,
8107                                        STOCK_PM_FLAGS, userId);
8108                        if (ai == null) {
8109                            Slog.w(TAG, "No package info for content provider "
8110                                    + cpi.name);
8111                            return null;
8112                        }
8113                        ai = getAppInfoForUser(ai, userId);
8114                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8115                    } catch (RemoteException ex) {
8116                        // pm is in same process, this will never happen.
8117                    }
8118                }
8119
8120                if (r != null && cpr.canRunHere(r)) {
8121                    // If this is a multiprocess provider, then just return its
8122                    // info and allow the caller to instantiate it.  Only do
8123                    // this if the provider is the same user as the caller's
8124                    // process, or can run as root (so can be in any process).
8125                    return cpr.newHolder(null);
8126                }
8127
8128                if (DEBUG_PROVIDER) {
8129                    RuntimeException e = new RuntimeException("here");
8130                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8131                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8132                }
8133
8134                // This is single process, and our app is now connecting to it.
8135                // See if we are already in the process of launching this
8136                // provider.
8137                final int N = mLaunchingProviders.size();
8138                int i;
8139                for (i=0; i<N; i++) {
8140                    if (mLaunchingProviders.get(i) == cpr) {
8141                        break;
8142                    }
8143                }
8144
8145                // If the provider is not already being launched, then get it
8146                // started.
8147                if (i >= N) {
8148                    final long origId = Binder.clearCallingIdentity();
8149
8150                    try {
8151                        // Content provider is now in use, its package can't be stopped.
8152                        try {
8153                            AppGlobals.getPackageManager().setPackageStoppedState(
8154                                    cpr.appInfo.packageName, false, userId);
8155                        } catch (RemoteException e) {
8156                        } catch (IllegalArgumentException e) {
8157                            Slog.w(TAG, "Failed trying to unstop package "
8158                                    + cpr.appInfo.packageName + ": " + e);
8159                        }
8160
8161                        // Use existing process if already started
8162                        ProcessRecord proc = getProcessRecordLocked(
8163                                cpi.processName, cpr.appInfo.uid, false);
8164                        if (proc != null && proc.thread != null) {
8165                            if (DEBUG_PROVIDER) {
8166                                Slog.d(TAG, "Installing in existing process " + proc);
8167                            }
8168                            proc.pubProviders.put(cpi.name, cpr);
8169                            try {
8170                                proc.thread.scheduleInstallProvider(cpi);
8171                            } catch (RemoteException e) {
8172                            }
8173                        } else {
8174                            proc = startProcessLocked(cpi.processName,
8175                                    cpr.appInfo, false, 0, "content provider",
8176                                    new ComponentName(cpi.applicationInfo.packageName,
8177                                            cpi.name), false, false, false);
8178                            if (proc == null) {
8179                                Slog.w(TAG, "Unable to launch app "
8180                                        + cpi.applicationInfo.packageName + "/"
8181                                        + cpi.applicationInfo.uid + " for provider "
8182                                        + name + ": process is bad");
8183                                return null;
8184                            }
8185                        }
8186                        cpr.launchingApp = proc;
8187                        mLaunchingProviders.add(cpr);
8188                    } finally {
8189                        Binder.restoreCallingIdentity(origId);
8190                    }
8191                }
8192
8193                // Make sure the provider is published (the same provider class
8194                // may be published under multiple names).
8195                if (firstClass) {
8196                    mProviderMap.putProviderByClass(comp, cpr);
8197                }
8198
8199                mProviderMap.putProviderByName(name, cpr);
8200                conn = incProviderCountLocked(r, cpr, token, stable);
8201                if (conn != null) {
8202                    conn.waiting = true;
8203                }
8204            }
8205        }
8206
8207        // Wait for the provider to be published...
8208        synchronized (cpr) {
8209            while (cpr.provider == null) {
8210                if (cpr.launchingApp == null) {
8211                    Slog.w(TAG, "Unable to launch app "
8212                            + cpi.applicationInfo.packageName + "/"
8213                            + cpi.applicationInfo.uid + " for provider "
8214                            + name + ": launching app became null");
8215                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8216                            UserHandle.getUserId(cpi.applicationInfo.uid),
8217                            cpi.applicationInfo.packageName,
8218                            cpi.applicationInfo.uid, name);
8219                    return null;
8220                }
8221                try {
8222                    if (DEBUG_MU) {
8223                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8224                                + cpr.launchingApp);
8225                    }
8226                    if (conn != null) {
8227                        conn.waiting = true;
8228                    }
8229                    cpr.wait();
8230                } catch (InterruptedException ex) {
8231                } finally {
8232                    if (conn != null) {
8233                        conn.waiting = false;
8234                    }
8235                }
8236            }
8237        }
8238        return cpr != null ? cpr.newHolder(conn) : null;
8239    }
8240
8241    @Override
8242    public final ContentProviderHolder getContentProvider(
8243            IApplicationThread caller, String name, int userId, boolean stable) {
8244        enforceNotIsolatedCaller("getContentProvider");
8245        if (caller == null) {
8246            String msg = "null IApplicationThread when getting content provider "
8247                    + name;
8248            Slog.w(TAG, msg);
8249            throw new SecurityException(msg);
8250        }
8251        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8252        // with cross-user grant.
8253        return getContentProviderImpl(caller, name, null, stable, userId);
8254    }
8255
8256    public ContentProviderHolder getContentProviderExternal(
8257            String name, int userId, IBinder token) {
8258        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8259            "Do not have permission in call getContentProviderExternal()");
8260        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8261                false, true, "getContentProvider", null);
8262        return getContentProviderExternalUnchecked(name, token, userId);
8263    }
8264
8265    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8266            IBinder token, int userId) {
8267        return getContentProviderImpl(null, name, token, true, userId);
8268    }
8269
8270    /**
8271     * Drop a content provider from a ProcessRecord's bookkeeping
8272     */
8273    public void removeContentProvider(IBinder connection, boolean stable) {
8274        enforceNotIsolatedCaller("removeContentProvider");
8275        long ident = Binder.clearCallingIdentity();
8276        try {
8277            synchronized (this) {
8278                ContentProviderConnection conn;
8279                try {
8280                    conn = (ContentProviderConnection)connection;
8281                } catch (ClassCastException e) {
8282                    String msg ="removeContentProvider: " + connection
8283                            + " not a ContentProviderConnection";
8284                    Slog.w(TAG, msg);
8285                    throw new IllegalArgumentException(msg);
8286                }
8287                if (conn == null) {
8288                    throw new NullPointerException("connection is null");
8289                }
8290                if (decProviderCountLocked(conn, null, null, stable)) {
8291                    updateOomAdjLocked();
8292                }
8293            }
8294        } finally {
8295            Binder.restoreCallingIdentity(ident);
8296        }
8297    }
8298
8299    public void removeContentProviderExternal(String name, IBinder token) {
8300        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8301            "Do not have permission in call removeContentProviderExternal()");
8302        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8303    }
8304
8305    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8306        synchronized (this) {
8307            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8308            if(cpr == null) {
8309                //remove from mProvidersByClass
8310                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8311                return;
8312            }
8313
8314            //update content provider record entry info
8315            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8316            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8317            if (localCpr.hasExternalProcessHandles()) {
8318                if (localCpr.removeExternalProcessHandleLocked(token)) {
8319                    updateOomAdjLocked();
8320                } else {
8321                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8322                            + " with no external reference for token: "
8323                            + token + ".");
8324                }
8325            } else {
8326                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8327                        + " with no external references.");
8328            }
8329        }
8330    }
8331
8332    public final void publishContentProviders(IApplicationThread caller,
8333            List<ContentProviderHolder> providers) {
8334        if (providers == null) {
8335            return;
8336        }
8337
8338        enforceNotIsolatedCaller("publishContentProviders");
8339        synchronized (this) {
8340            final ProcessRecord r = getRecordForAppLocked(caller);
8341            if (DEBUG_MU)
8342                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8343            if (r == null) {
8344                throw new SecurityException(
8345                        "Unable to find app for caller " + caller
8346                      + " (pid=" + Binder.getCallingPid()
8347                      + ") when publishing content providers");
8348            }
8349
8350            final long origId = Binder.clearCallingIdentity();
8351
8352            final int N = providers.size();
8353            for (int i=0; i<N; i++) {
8354                ContentProviderHolder src = providers.get(i);
8355                if (src == null || src.info == null || src.provider == null) {
8356                    continue;
8357                }
8358                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8359                if (DEBUG_MU)
8360                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8361                if (dst != null) {
8362                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8363                    mProviderMap.putProviderByClass(comp, dst);
8364                    String names[] = dst.info.authority.split(";");
8365                    for (int j = 0; j < names.length; j++) {
8366                        mProviderMap.putProviderByName(names[j], dst);
8367                    }
8368
8369                    int NL = mLaunchingProviders.size();
8370                    int j;
8371                    for (j=0; j<NL; j++) {
8372                        if (mLaunchingProviders.get(j) == dst) {
8373                            mLaunchingProviders.remove(j);
8374                            j--;
8375                            NL--;
8376                        }
8377                    }
8378                    synchronized (dst) {
8379                        dst.provider = src.provider;
8380                        dst.proc = r;
8381                        dst.notifyAll();
8382                    }
8383                    updateOomAdjLocked(r);
8384                }
8385            }
8386
8387            Binder.restoreCallingIdentity(origId);
8388        }
8389    }
8390
8391    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8392        ContentProviderConnection conn;
8393        try {
8394            conn = (ContentProviderConnection)connection;
8395        } catch (ClassCastException e) {
8396            String msg ="refContentProvider: " + connection
8397                    + " not a ContentProviderConnection";
8398            Slog.w(TAG, msg);
8399            throw new IllegalArgumentException(msg);
8400        }
8401        if (conn == null) {
8402            throw new NullPointerException("connection is null");
8403        }
8404
8405        synchronized (this) {
8406            if (stable > 0) {
8407                conn.numStableIncs += stable;
8408            }
8409            stable = conn.stableCount + stable;
8410            if (stable < 0) {
8411                throw new IllegalStateException("stableCount < 0: " + stable);
8412            }
8413
8414            if (unstable > 0) {
8415                conn.numUnstableIncs += unstable;
8416            }
8417            unstable = conn.unstableCount + unstable;
8418            if (unstable < 0) {
8419                throw new IllegalStateException("unstableCount < 0: " + unstable);
8420            }
8421
8422            if ((stable+unstable) <= 0) {
8423                throw new IllegalStateException("ref counts can't go to zero here: stable="
8424                        + stable + " unstable=" + unstable);
8425            }
8426            conn.stableCount = stable;
8427            conn.unstableCount = unstable;
8428            return !conn.dead;
8429        }
8430    }
8431
8432    public void unstableProviderDied(IBinder connection) {
8433        ContentProviderConnection conn;
8434        try {
8435            conn = (ContentProviderConnection)connection;
8436        } catch (ClassCastException e) {
8437            String msg ="refContentProvider: " + connection
8438                    + " not a ContentProviderConnection";
8439            Slog.w(TAG, msg);
8440            throw new IllegalArgumentException(msg);
8441        }
8442        if (conn == null) {
8443            throw new NullPointerException("connection is null");
8444        }
8445
8446        // Safely retrieve the content provider associated with the connection.
8447        IContentProvider provider;
8448        synchronized (this) {
8449            provider = conn.provider.provider;
8450        }
8451
8452        if (provider == null) {
8453            // Um, yeah, we're way ahead of you.
8454            return;
8455        }
8456
8457        // Make sure the caller is being honest with us.
8458        if (provider.asBinder().pingBinder()) {
8459            // Er, no, still looks good to us.
8460            synchronized (this) {
8461                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8462                        + " says " + conn + " died, but we don't agree");
8463                return;
8464            }
8465        }
8466
8467        // Well look at that!  It's dead!
8468        synchronized (this) {
8469            if (conn.provider.provider != provider) {
8470                // But something changed...  good enough.
8471                return;
8472            }
8473
8474            ProcessRecord proc = conn.provider.proc;
8475            if (proc == null || proc.thread == null) {
8476                // Seems like the process is already cleaned up.
8477                return;
8478            }
8479
8480            // As far as we're concerned, this is just like receiving a
8481            // death notification...  just a bit prematurely.
8482            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8483                    + ") early provider death");
8484            final long ident = Binder.clearCallingIdentity();
8485            try {
8486                appDiedLocked(proc, proc.pid, proc.thread);
8487            } finally {
8488                Binder.restoreCallingIdentity(ident);
8489            }
8490        }
8491    }
8492
8493    @Override
8494    public void appNotRespondingViaProvider(IBinder connection) {
8495        enforceCallingPermission(
8496                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8497
8498        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8499        if (conn == null) {
8500            Slog.w(TAG, "ContentProviderConnection is null");
8501            return;
8502        }
8503
8504        final ProcessRecord host = conn.provider.proc;
8505        if (host == null) {
8506            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8507            return;
8508        }
8509
8510        final long token = Binder.clearCallingIdentity();
8511        try {
8512            appNotResponding(host, null, null, false, "ContentProvider not responding");
8513        } finally {
8514            Binder.restoreCallingIdentity(token);
8515        }
8516    }
8517
8518    public final void installSystemProviders() {
8519        List<ProviderInfo> providers;
8520        synchronized (this) {
8521            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8522            providers = generateApplicationProvidersLocked(app);
8523            if (providers != null) {
8524                for (int i=providers.size()-1; i>=0; i--) {
8525                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8526                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8527                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8528                                + ": not system .apk");
8529                        providers.remove(i);
8530                    }
8531                }
8532            }
8533        }
8534        if (providers != null) {
8535            mSystemThread.installSystemProviders(providers);
8536        }
8537
8538        mCoreSettingsObserver = new CoreSettingsObserver(this);
8539
8540        mUsageStatsService.monitorPackages();
8541    }
8542
8543    /**
8544     * Allows app to retrieve the MIME type of a URI without having permission
8545     * to access its content provider.
8546     *
8547     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8548     *
8549     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8550     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8551     */
8552    public String getProviderMimeType(Uri uri, int userId) {
8553        enforceNotIsolatedCaller("getProviderMimeType");
8554        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8555                userId, false, true, "getProviderMimeType", null);
8556        final String name = uri.getAuthority();
8557        final long ident = Binder.clearCallingIdentity();
8558        ContentProviderHolder holder = null;
8559
8560        try {
8561            holder = getContentProviderExternalUnchecked(name, null, userId);
8562            if (holder != null) {
8563                return holder.provider.getType(uri);
8564            }
8565        } catch (RemoteException e) {
8566            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8567            return null;
8568        } finally {
8569            if (holder != null) {
8570                removeContentProviderExternalUnchecked(name, null, userId);
8571            }
8572            Binder.restoreCallingIdentity(ident);
8573        }
8574
8575        return null;
8576    }
8577
8578    // =========================================================
8579    // GLOBAL MANAGEMENT
8580    // =========================================================
8581
8582    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8583            boolean isolated) {
8584        String proc = customProcess != null ? customProcess : info.processName;
8585        BatteryStatsImpl.Uid.Proc ps = null;
8586        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8587        int uid = info.uid;
8588        if (isolated) {
8589            int userId = UserHandle.getUserId(uid);
8590            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8591            while (true) {
8592                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8593                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8594                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8595                }
8596                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8597                mNextIsolatedProcessUid++;
8598                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8599                    // No process for this uid, use it.
8600                    break;
8601                }
8602                stepsLeft--;
8603                if (stepsLeft <= 0) {
8604                    return null;
8605                }
8606            }
8607        }
8608        return new ProcessRecord(stats, info, proc, uid);
8609    }
8610
8611    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8612            String abiOverride) {
8613        ProcessRecord app;
8614        if (!isolated) {
8615            app = getProcessRecordLocked(info.processName, info.uid, true);
8616        } else {
8617            app = null;
8618        }
8619
8620        if (app == null) {
8621            app = newProcessRecordLocked(info, null, isolated);
8622            mProcessNames.put(info.processName, app.uid, app);
8623            if (isolated) {
8624                mIsolatedProcesses.put(app.uid, app);
8625            }
8626            updateLruProcessLocked(app, false, null);
8627            updateOomAdjLocked();
8628        }
8629
8630        // This package really, really can not be stopped.
8631        try {
8632            AppGlobals.getPackageManager().setPackageStoppedState(
8633                    info.packageName, false, UserHandle.getUserId(app.uid));
8634        } catch (RemoteException e) {
8635        } catch (IllegalArgumentException e) {
8636            Slog.w(TAG, "Failed trying to unstop package "
8637                    + info.packageName + ": " + e);
8638        }
8639
8640        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8641                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8642            app.persistent = true;
8643            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8644        }
8645        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8646            mPersistentStartingProcesses.add(app);
8647            startProcessLocked(app, "added application", app.processName,
8648                    abiOverride);
8649        }
8650
8651        return app;
8652    }
8653
8654    public void unhandledBack() {
8655        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8656                "unhandledBack()");
8657
8658        synchronized(this) {
8659            final long origId = Binder.clearCallingIdentity();
8660            try {
8661                getFocusedStack().unhandledBackLocked();
8662            } finally {
8663                Binder.restoreCallingIdentity(origId);
8664            }
8665        }
8666    }
8667
8668    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8669        enforceNotIsolatedCaller("openContentUri");
8670        final int userId = UserHandle.getCallingUserId();
8671        String name = uri.getAuthority();
8672        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8673        ParcelFileDescriptor pfd = null;
8674        if (cph != null) {
8675            // We record the binder invoker's uid in thread-local storage before
8676            // going to the content provider to open the file.  Later, in the code
8677            // that handles all permissions checks, we look for this uid and use
8678            // that rather than the Activity Manager's own uid.  The effect is that
8679            // we do the check against the caller's permissions even though it looks
8680            // to the content provider like the Activity Manager itself is making
8681            // the request.
8682            sCallerIdentity.set(new Identity(
8683                    Binder.getCallingPid(), Binder.getCallingUid()));
8684            try {
8685                pfd = cph.provider.openFile(null, uri, "r", null);
8686            } catch (FileNotFoundException e) {
8687                // do nothing; pfd will be returned null
8688            } finally {
8689                // Ensure that whatever happens, we clean up the identity state
8690                sCallerIdentity.remove();
8691            }
8692
8693            // We've got the fd now, so we're done with the provider.
8694            removeContentProviderExternalUnchecked(name, null, userId);
8695        } else {
8696            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8697        }
8698        return pfd;
8699    }
8700
8701    // Actually is sleeping or shutting down or whatever else in the future
8702    // is an inactive state.
8703    public boolean isSleepingOrShuttingDown() {
8704        return mSleeping || mShuttingDown;
8705    }
8706
8707    public boolean isSleeping() {
8708        return mSleeping;
8709    }
8710
8711    void goingToSleep() {
8712        synchronized(this) {
8713            mWentToSleep = true;
8714            updateEventDispatchingLocked();
8715            goToSleepIfNeededLocked();
8716        }
8717    }
8718
8719    void finishRunningVoiceLocked() {
8720        if (mRunningVoice) {
8721            mRunningVoice = false;
8722            goToSleepIfNeededLocked();
8723        }
8724    }
8725
8726    void goToSleepIfNeededLocked() {
8727        if (mWentToSleep && !mRunningVoice) {
8728            if (!mSleeping) {
8729                mSleeping = true;
8730                mStackSupervisor.goingToSleepLocked();
8731
8732                // Initialize the wake times of all processes.
8733                checkExcessivePowerUsageLocked(false);
8734                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8735                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8736                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8737            }
8738        }
8739    }
8740
8741    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8742        mTaskPersister.notify(task, flush);
8743    }
8744
8745    @Override
8746    public boolean shutdown(int timeout) {
8747        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8748                != PackageManager.PERMISSION_GRANTED) {
8749            throw new SecurityException("Requires permission "
8750                    + android.Manifest.permission.SHUTDOWN);
8751        }
8752
8753        boolean timedout = false;
8754
8755        synchronized(this) {
8756            mShuttingDown = true;
8757            updateEventDispatchingLocked();
8758            timedout = mStackSupervisor.shutdownLocked(timeout);
8759        }
8760
8761        mAppOpsService.shutdown();
8762        mUsageStatsService.shutdown();
8763        mBatteryStatsService.shutdown();
8764        synchronized (this) {
8765            mProcessStats.shutdownLocked();
8766        }
8767        notifyTaskPersisterLocked(null, true);
8768
8769        return timedout;
8770    }
8771
8772    public final void activitySlept(IBinder token) {
8773        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8774
8775        final long origId = Binder.clearCallingIdentity();
8776
8777        synchronized (this) {
8778            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8779            if (r != null) {
8780                mStackSupervisor.activitySleptLocked(r);
8781            }
8782        }
8783
8784        Binder.restoreCallingIdentity(origId);
8785    }
8786
8787    void logLockScreen(String msg) {
8788        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8789                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8790                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8791                mStackSupervisor.mDismissKeyguardOnNextActivity);
8792    }
8793
8794    private void comeOutOfSleepIfNeededLocked() {
8795        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8796            if (mSleeping) {
8797                mSleeping = false;
8798                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8799            }
8800        }
8801    }
8802
8803    void wakingUp() {
8804        synchronized(this) {
8805            mWentToSleep = false;
8806            updateEventDispatchingLocked();
8807            comeOutOfSleepIfNeededLocked();
8808        }
8809    }
8810
8811    void startRunningVoiceLocked() {
8812        if (!mRunningVoice) {
8813            mRunningVoice = true;
8814            comeOutOfSleepIfNeededLocked();
8815        }
8816    }
8817
8818    private void updateEventDispatchingLocked() {
8819        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8820    }
8821
8822    public void setLockScreenShown(boolean shown) {
8823        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8824                != PackageManager.PERMISSION_GRANTED) {
8825            throw new SecurityException("Requires permission "
8826                    + android.Manifest.permission.DEVICE_POWER);
8827        }
8828
8829        synchronized(this) {
8830            long ident = Binder.clearCallingIdentity();
8831            try {
8832                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8833                mLockScreenShown = shown;
8834                comeOutOfSleepIfNeededLocked();
8835            } finally {
8836                Binder.restoreCallingIdentity(ident);
8837            }
8838        }
8839    }
8840
8841    public void stopAppSwitches() {
8842        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8843                != PackageManager.PERMISSION_GRANTED) {
8844            throw new SecurityException("Requires permission "
8845                    + android.Manifest.permission.STOP_APP_SWITCHES);
8846        }
8847
8848        synchronized(this) {
8849            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8850                    + APP_SWITCH_DELAY_TIME;
8851            mDidAppSwitch = false;
8852            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8853            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8854            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8855        }
8856    }
8857
8858    public void resumeAppSwitches() {
8859        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8860                != PackageManager.PERMISSION_GRANTED) {
8861            throw new SecurityException("Requires permission "
8862                    + android.Manifest.permission.STOP_APP_SWITCHES);
8863        }
8864
8865        synchronized(this) {
8866            // Note that we don't execute any pending app switches... we will
8867            // let those wait until either the timeout, or the next start
8868            // activity request.
8869            mAppSwitchesAllowedTime = 0;
8870        }
8871    }
8872
8873    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8874            String name) {
8875        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8876            return true;
8877        }
8878
8879        final int perm = checkComponentPermission(
8880                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8881                callingUid, -1, true);
8882        if (perm == PackageManager.PERMISSION_GRANTED) {
8883            return true;
8884        }
8885
8886        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8887        return false;
8888    }
8889
8890    public void setDebugApp(String packageName, boolean waitForDebugger,
8891            boolean persistent) {
8892        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8893                "setDebugApp()");
8894
8895        long ident = Binder.clearCallingIdentity();
8896        try {
8897            // Note that this is not really thread safe if there are multiple
8898            // callers into it at the same time, but that's not a situation we
8899            // care about.
8900            if (persistent) {
8901                final ContentResolver resolver = mContext.getContentResolver();
8902                Settings.Global.putString(
8903                    resolver, Settings.Global.DEBUG_APP,
8904                    packageName);
8905                Settings.Global.putInt(
8906                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8907                    waitForDebugger ? 1 : 0);
8908            }
8909
8910            synchronized (this) {
8911                if (!persistent) {
8912                    mOrigDebugApp = mDebugApp;
8913                    mOrigWaitForDebugger = mWaitForDebugger;
8914                }
8915                mDebugApp = packageName;
8916                mWaitForDebugger = waitForDebugger;
8917                mDebugTransient = !persistent;
8918                if (packageName != null) {
8919                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8920                            false, UserHandle.USER_ALL, "set debug app");
8921                }
8922            }
8923        } finally {
8924            Binder.restoreCallingIdentity(ident);
8925        }
8926    }
8927
8928    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8929        synchronized (this) {
8930            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8931            if (!isDebuggable) {
8932                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8933                    throw new SecurityException("Process not debuggable: " + app.packageName);
8934                }
8935            }
8936
8937            mOpenGlTraceApp = processName;
8938        }
8939    }
8940
8941    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8942            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8943        synchronized (this) {
8944            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8945            if (!isDebuggable) {
8946                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8947                    throw new SecurityException("Process not debuggable: " + app.packageName);
8948                }
8949            }
8950            mProfileApp = processName;
8951            mProfileFile = profileFile;
8952            if (mProfileFd != null) {
8953                try {
8954                    mProfileFd.close();
8955                } catch (IOException e) {
8956                }
8957                mProfileFd = null;
8958            }
8959            mProfileFd = profileFd;
8960            mProfileType = 0;
8961            mAutoStopProfiler = autoStopProfiler;
8962        }
8963    }
8964
8965    @Override
8966    public void setAlwaysFinish(boolean enabled) {
8967        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8968                "setAlwaysFinish()");
8969
8970        Settings.Global.putInt(
8971                mContext.getContentResolver(),
8972                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8973
8974        synchronized (this) {
8975            mAlwaysFinishActivities = enabled;
8976        }
8977    }
8978
8979    @Override
8980    public void setActivityController(IActivityController controller) {
8981        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8982                "setActivityController()");
8983        synchronized (this) {
8984            mController = controller;
8985            Watchdog.getInstance().setActivityController(controller);
8986        }
8987    }
8988
8989    @Override
8990    public void setUserIsMonkey(boolean userIsMonkey) {
8991        synchronized (this) {
8992            synchronized (mPidsSelfLocked) {
8993                final int callingPid = Binder.getCallingPid();
8994                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8995                if (precessRecord == null) {
8996                    throw new SecurityException("Unknown process: " + callingPid);
8997                }
8998                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8999                    throw new SecurityException("Only an instrumentation process "
9000                            + "with a UiAutomation can call setUserIsMonkey");
9001                }
9002            }
9003            mUserIsMonkey = userIsMonkey;
9004        }
9005    }
9006
9007    @Override
9008    public boolean isUserAMonkey() {
9009        synchronized (this) {
9010            // If there is a controller also implies the user is a monkey.
9011            return (mUserIsMonkey || mController != null);
9012        }
9013    }
9014
9015    public void requestBugReport() {
9016        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9017        SystemProperties.set("ctl.start", "bugreport");
9018    }
9019
9020    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9021        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9022    }
9023
9024    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9025        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9026            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9027        }
9028        return KEY_DISPATCHING_TIMEOUT;
9029    }
9030
9031    @Override
9032    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9033        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9034                != PackageManager.PERMISSION_GRANTED) {
9035            throw new SecurityException("Requires permission "
9036                    + android.Manifest.permission.FILTER_EVENTS);
9037        }
9038        ProcessRecord proc;
9039        long timeout;
9040        synchronized (this) {
9041            synchronized (mPidsSelfLocked) {
9042                proc = mPidsSelfLocked.get(pid);
9043            }
9044            timeout = getInputDispatchingTimeoutLocked(proc);
9045        }
9046
9047        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9048            return -1;
9049        }
9050
9051        return timeout;
9052    }
9053
9054    /**
9055     * Handle input dispatching timeouts.
9056     * Returns whether input dispatching should be aborted or not.
9057     */
9058    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9059            final ActivityRecord activity, final ActivityRecord parent,
9060            final boolean aboveSystem, String reason) {
9061        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9062                != PackageManager.PERMISSION_GRANTED) {
9063            throw new SecurityException("Requires permission "
9064                    + android.Manifest.permission.FILTER_EVENTS);
9065        }
9066
9067        final String annotation;
9068        if (reason == null) {
9069            annotation = "Input dispatching timed out";
9070        } else {
9071            annotation = "Input dispatching timed out (" + reason + ")";
9072        }
9073
9074        if (proc != null) {
9075            synchronized (this) {
9076                if (proc.debugging) {
9077                    return false;
9078                }
9079
9080                if (mDidDexOpt) {
9081                    // Give more time since we were dexopting.
9082                    mDidDexOpt = false;
9083                    return false;
9084                }
9085
9086                if (proc.instrumentationClass != null) {
9087                    Bundle info = new Bundle();
9088                    info.putString("shortMsg", "keyDispatchingTimedOut");
9089                    info.putString("longMsg", annotation);
9090                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9091                    return true;
9092                }
9093            }
9094            mHandler.post(new Runnable() {
9095                @Override
9096                public void run() {
9097                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9098                }
9099            });
9100        }
9101
9102        return true;
9103    }
9104
9105    public Bundle getAssistContextExtras(int requestType) {
9106        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9107                "getAssistContextExtras()");
9108        PendingAssistExtras pae;
9109        Bundle extras = new Bundle();
9110        synchronized (this) {
9111            ActivityRecord activity = getFocusedStack().mResumedActivity;
9112            if (activity == null) {
9113                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9114                return null;
9115            }
9116            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9117            if (activity.app == null || activity.app.thread == null) {
9118                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9119                return extras;
9120            }
9121            if (activity.app.pid == Binder.getCallingPid()) {
9122                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9123                return extras;
9124            }
9125            pae = new PendingAssistExtras(activity);
9126            try {
9127                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9128                        requestType);
9129                mPendingAssistExtras.add(pae);
9130                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9131            } catch (RemoteException e) {
9132                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9133                return extras;
9134            }
9135        }
9136        synchronized (pae) {
9137            while (!pae.haveResult) {
9138                try {
9139                    pae.wait();
9140                } catch (InterruptedException e) {
9141                }
9142            }
9143            if (pae.result != null) {
9144                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9145            }
9146        }
9147        synchronized (this) {
9148            mPendingAssistExtras.remove(pae);
9149            mHandler.removeCallbacks(pae);
9150        }
9151        return extras;
9152    }
9153
9154    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9155        PendingAssistExtras pae = (PendingAssistExtras)token;
9156        synchronized (pae) {
9157            pae.result = extras;
9158            pae.haveResult = true;
9159            pae.notifyAll();
9160        }
9161    }
9162
9163    public void registerProcessObserver(IProcessObserver observer) {
9164        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9165                "registerProcessObserver()");
9166        synchronized (this) {
9167            mProcessObservers.register(observer);
9168        }
9169    }
9170
9171    @Override
9172    public void unregisterProcessObserver(IProcessObserver observer) {
9173        synchronized (this) {
9174            mProcessObservers.unregister(observer);
9175        }
9176    }
9177
9178    @Override
9179    public boolean convertFromTranslucent(IBinder token) {
9180        final long origId = Binder.clearCallingIdentity();
9181        try {
9182            synchronized (this) {
9183                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9184                if (r == null) {
9185                    return false;
9186                }
9187                if (r.changeWindowTranslucency(true)) {
9188                    mWindowManager.setAppFullscreen(token, true);
9189                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9190                    return true;
9191                }
9192                return false;
9193            }
9194        } finally {
9195            Binder.restoreCallingIdentity(origId);
9196        }
9197    }
9198
9199    @Override
9200    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9201        final long origId = Binder.clearCallingIdentity();
9202        try {
9203            synchronized (this) {
9204                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9205                if (r == null) {
9206                    return false;
9207                }
9208                if (r.changeWindowTranslucency(false)) {
9209                    r.task.stack.convertToTranslucent(r, options);
9210                    mWindowManager.setAppFullscreen(token, false);
9211                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9212                    return true;
9213                }
9214                return false;
9215            }
9216        } finally {
9217            Binder.restoreCallingIdentity(origId);
9218        }
9219    }
9220
9221    @Override
9222    public ActivityOptions getActivityOptions(IBinder token) {
9223        final long origId = Binder.clearCallingIdentity();
9224        try {
9225            synchronized (this) {
9226                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9227                if (r != null) {
9228                    final ActivityOptions activityOptions = r.pendingOptions;
9229                    r.pendingOptions = null;
9230                    return activityOptions;
9231                }
9232                return null;
9233            }
9234        } finally {
9235            Binder.restoreCallingIdentity(origId);
9236        }
9237    }
9238
9239    @Override
9240    public void setImmersive(IBinder token, boolean immersive) {
9241        synchronized(this) {
9242            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9243            if (r == null) {
9244                throw new IllegalArgumentException();
9245            }
9246            r.immersive = immersive;
9247
9248            // update associated state if we're frontmost
9249            if (r == mFocusedActivity) {
9250                if (DEBUG_IMMERSIVE) {
9251                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9252                }
9253                applyUpdateLockStateLocked(r);
9254            }
9255        }
9256    }
9257
9258    @Override
9259    public boolean isImmersive(IBinder token) {
9260        synchronized (this) {
9261            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9262            if (r == null) {
9263                throw new IllegalArgumentException();
9264            }
9265            return r.immersive;
9266        }
9267    }
9268
9269    public boolean isTopActivityImmersive() {
9270        enforceNotIsolatedCaller("startActivity");
9271        synchronized (this) {
9272            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9273            return (r != null) ? r.immersive : false;
9274        }
9275    }
9276
9277    public final void enterSafeMode() {
9278        synchronized(this) {
9279            // It only makes sense to do this before the system is ready
9280            // and started launching other packages.
9281            if (!mSystemReady) {
9282                try {
9283                    AppGlobals.getPackageManager().enterSafeMode();
9284                } catch (RemoteException e) {
9285                }
9286            }
9287
9288            mSafeMode = true;
9289        }
9290    }
9291
9292    public final void showSafeModeOverlay() {
9293        View v = LayoutInflater.from(mContext).inflate(
9294                com.android.internal.R.layout.safe_mode, null);
9295        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9296        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9297        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9298        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9299        lp.gravity = Gravity.BOTTOM | Gravity.START;
9300        lp.format = v.getBackground().getOpacity();
9301        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9302                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9303        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9304        ((WindowManager)mContext.getSystemService(
9305                Context.WINDOW_SERVICE)).addView(v, lp);
9306    }
9307
9308    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9309        if (!(sender instanceof PendingIntentRecord)) {
9310            return;
9311        }
9312        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9313        synchronized (stats) {
9314            if (mBatteryStatsService.isOnBattery()) {
9315                mBatteryStatsService.enforceCallingPermission();
9316                PendingIntentRecord rec = (PendingIntentRecord)sender;
9317                int MY_UID = Binder.getCallingUid();
9318                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9319                BatteryStatsImpl.Uid.Pkg pkg =
9320                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9321                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9322                pkg.incWakeupsLocked();
9323            }
9324        }
9325    }
9326
9327    public boolean killPids(int[] pids, String pReason, boolean secure) {
9328        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9329            throw new SecurityException("killPids only available to the system");
9330        }
9331        String reason = (pReason == null) ? "Unknown" : pReason;
9332        // XXX Note: don't acquire main activity lock here, because the window
9333        // manager calls in with its locks held.
9334
9335        boolean killed = false;
9336        synchronized (mPidsSelfLocked) {
9337            int[] types = new int[pids.length];
9338            int worstType = 0;
9339            for (int i=0; i<pids.length; i++) {
9340                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9341                if (proc != null) {
9342                    int type = proc.setAdj;
9343                    types[i] = type;
9344                    if (type > worstType) {
9345                        worstType = type;
9346                    }
9347                }
9348            }
9349
9350            // If the worst oom_adj is somewhere in the cached proc LRU range,
9351            // then constrain it so we will kill all cached procs.
9352            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9353                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9354                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9355            }
9356
9357            // If this is not a secure call, don't let it kill processes that
9358            // are important.
9359            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9360                worstType = ProcessList.SERVICE_ADJ;
9361            }
9362
9363            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9364            for (int i=0; i<pids.length; i++) {
9365                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9366                if (proc == null) {
9367                    continue;
9368                }
9369                int adj = proc.setAdj;
9370                if (adj >= worstType && !proc.killedByAm) {
9371                    killUnneededProcessLocked(proc, reason);
9372                    killed = true;
9373                }
9374            }
9375        }
9376        return killed;
9377    }
9378
9379    @Override
9380    public void killUid(int uid, String reason) {
9381        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9382            throw new SecurityException("killUid only available to the system");
9383        }
9384        synchronized (this) {
9385            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9386                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9387                    reason != null ? reason : "kill uid");
9388        }
9389    }
9390
9391    @Override
9392    public boolean killProcessesBelowForeground(String reason) {
9393        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9394            throw new SecurityException("killProcessesBelowForeground() only available to system");
9395        }
9396
9397        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9398    }
9399
9400    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9401        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9402            throw new SecurityException("killProcessesBelowAdj() only available to system");
9403        }
9404
9405        boolean killed = false;
9406        synchronized (mPidsSelfLocked) {
9407            final int size = mPidsSelfLocked.size();
9408            for (int i = 0; i < size; i++) {
9409                final int pid = mPidsSelfLocked.keyAt(i);
9410                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9411                if (proc == null) continue;
9412
9413                final int adj = proc.setAdj;
9414                if (adj > belowAdj && !proc.killedByAm) {
9415                    killUnneededProcessLocked(proc, reason);
9416                    killed = true;
9417                }
9418            }
9419        }
9420        return killed;
9421    }
9422
9423    @Override
9424    public void hang(final IBinder who, boolean allowRestart) {
9425        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9426                != PackageManager.PERMISSION_GRANTED) {
9427            throw new SecurityException("Requires permission "
9428                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9429        }
9430
9431        final IBinder.DeathRecipient death = new DeathRecipient() {
9432            @Override
9433            public void binderDied() {
9434                synchronized (this) {
9435                    notifyAll();
9436                }
9437            }
9438        };
9439
9440        try {
9441            who.linkToDeath(death, 0);
9442        } catch (RemoteException e) {
9443            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9444            return;
9445        }
9446
9447        synchronized (this) {
9448            Watchdog.getInstance().setAllowRestart(allowRestart);
9449            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9450            synchronized (death) {
9451                while (who.isBinderAlive()) {
9452                    try {
9453                        death.wait();
9454                    } catch (InterruptedException e) {
9455                    }
9456                }
9457            }
9458            Watchdog.getInstance().setAllowRestart(true);
9459        }
9460    }
9461
9462    @Override
9463    public void restart() {
9464        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9465                != PackageManager.PERMISSION_GRANTED) {
9466            throw new SecurityException("Requires permission "
9467                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9468        }
9469
9470        Log.i(TAG, "Sending shutdown broadcast...");
9471
9472        BroadcastReceiver br = new BroadcastReceiver() {
9473            @Override public void onReceive(Context context, Intent intent) {
9474                // Now the broadcast is done, finish up the low-level shutdown.
9475                Log.i(TAG, "Shutting down activity manager...");
9476                shutdown(10000);
9477                Log.i(TAG, "Shutdown complete, restarting!");
9478                Process.killProcess(Process.myPid());
9479                System.exit(10);
9480            }
9481        };
9482
9483        // First send the high-level shut down broadcast.
9484        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9485        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9486        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9487        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9488        mContext.sendOrderedBroadcastAsUser(intent,
9489                UserHandle.ALL, null, br, mHandler, 0, null, null);
9490        */
9491        br.onReceive(mContext, intent);
9492    }
9493
9494    private long getLowRamTimeSinceIdle(long now) {
9495        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9496    }
9497
9498    @Override
9499    public void performIdleMaintenance() {
9500        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9501                != PackageManager.PERMISSION_GRANTED) {
9502            throw new SecurityException("Requires permission "
9503                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9504        }
9505
9506        synchronized (this) {
9507            final long now = SystemClock.uptimeMillis();
9508            final long timeSinceLastIdle = now - mLastIdleTime;
9509            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9510            mLastIdleTime = now;
9511            mLowRamTimeSinceLastIdle = 0;
9512            if (mLowRamStartTime != 0) {
9513                mLowRamStartTime = now;
9514            }
9515
9516            StringBuilder sb = new StringBuilder(128);
9517            sb.append("Idle maintenance over ");
9518            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9519            sb.append(" low RAM for ");
9520            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9521            Slog.i(TAG, sb.toString());
9522
9523            // If at least 1/3 of our time since the last idle period has been spent
9524            // with RAM low, then we want to kill processes.
9525            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9526
9527            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9528                ProcessRecord proc = mLruProcesses.get(i);
9529                if (proc.notCachedSinceIdle) {
9530                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9531                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9532                        if (doKilling && proc.initialIdlePss != 0
9533                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9534                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9535                                    + " from " + proc.initialIdlePss + ")");
9536                        }
9537                    }
9538                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9539                    proc.notCachedSinceIdle = true;
9540                    proc.initialIdlePss = 0;
9541                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9542                            isSleeping(), now);
9543                }
9544            }
9545
9546            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9547            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9548        }
9549    }
9550
9551    private void retrieveSettings() {
9552        final ContentResolver resolver = mContext.getContentResolver();
9553        String debugApp = Settings.Global.getString(
9554            resolver, Settings.Global.DEBUG_APP);
9555        boolean waitForDebugger = Settings.Global.getInt(
9556            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9557        boolean alwaysFinishActivities = Settings.Global.getInt(
9558            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9559        boolean forceRtl = Settings.Global.getInt(
9560                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9561        // Transfer any global setting for forcing RTL layout, into a System Property
9562        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9563
9564        Configuration configuration = new Configuration();
9565        Settings.System.getConfiguration(resolver, configuration);
9566        if (forceRtl) {
9567            // This will take care of setting the correct layout direction flags
9568            configuration.setLayoutDirection(configuration.locale);
9569        }
9570
9571        synchronized (this) {
9572            mDebugApp = mOrigDebugApp = debugApp;
9573            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9574            mAlwaysFinishActivities = alwaysFinishActivities;
9575            // This happens before any activities are started, so we can
9576            // change mConfiguration in-place.
9577            updateConfigurationLocked(configuration, null, false, true);
9578            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9579        }
9580    }
9581
9582    public boolean testIsSystemReady() {
9583        // no need to synchronize(this) just to read & return the value
9584        return mSystemReady;
9585    }
9586
9587    private static File getCalledPreBootReceiversFile() {
9588        File dataDir = Environment.getDataDirectory();
9589        File systemDir = new File(dataDir, "system");
9590        File fname = new File(systemDir, "called_pre_boots.dat");
9591        return fname;
9592    }
9593
9594    static final int LAST_DONE_VERSION = 10000;
9595
9596    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9597        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9598        File file = getCalledPreBootReceiversFile();
9599        FileInputStream fis = null;
9600        try {
9601            fis = new FileInputStream(file);
9602            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9603            int fvers = dis.readInt();
9604            if (fvers == LAST_DONE_VERSION) {
9605                String vers = dis.readUTF();
9606                String codename = dis.readUTF();
9607                String build = dis.readUTF();
9608                if (android.os.Build.VERSION.RELEASE.equals(vers)
9609                        && android.os.Build.VERSION.CODENAME.equals(codename)
9610                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9611                    int num = dis.readInt();
9612                    while (num > 0) {
9613                        num--;
9614                        String pkg = dis.readUTF();
9615                        String cls = dis.readUTF();
9616                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9617                    }
9618                }
9619            }
9620        } catch (FileNotFoundException e) {
9621        } catch (IOException e) {
9622            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9623        } finally {
9624            if (fis != null) {
9625                try {
9626                    fis.close();
9627                } catch (IOException e) {
9628                }
9629            }
9630        }
9631        return lastDoneReceivers;
9632    }
9633
9634    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9635        File file = getCalledPreBootReceiversFile();
9636        FileOutputStream fos = null;
9637        DataOutputStream dos = null;
9638        try {
9639            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9640            fos = new FileOutputStream(file);
9641            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9642            dos.writeInt(LAST_DONE_VERSION);
9643            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9644            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9645            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9646            dos.writeInt(list.size());
9647            for (int i=0; i<list.size(); i++) {
9648                dos.writeUTF(list.get(i).getPackageName());
9649                dos.writeUTF(list.get(i).getClassName());
9650            }
9651        } catch (IOException e) {
9652            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9653            file.delete();
9654        } finally {
9655            FileUtils.sync(fos);
9656            if (dos != null) {
9657                try {
9658                    dos.close();
9659                } catch (IOException e) {
9660                    // TODO Auto-generated catch block
9661                    e.printStackTrace();
9662                }
9663            }
9664        }
9665    }
9666
9667    public void systemReady(final Runnable goingCallback) {
9668        synchronized(this) {
9669            if (mSystemReady) {
9670                if (goingCallback != null) goingCallback.run();
9671                return;
9672            }
9673
9674            if (mRecentTasks == null) {
9675                mRecentTasks = mTaskPersister.restoreTasksLocked();
9676                if (!mRecentTasks.isEmpty()) {
9677                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9678                }
9679                mTaskPersister.startPersisting();
9680            }
9681
9682            // Check to see if there are any update receivers to run.
9683            if (!mDidUpdate) {
9684                if (mWaitingUpdate) {
9685                    return;
9686                }
9687                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9688                List<ResolveInfo> ris = null;
9689                try {
9690                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9691                            intent, null, 0, 0);
9692                } catch (RemoteException e) {
9693                }
9694                if (ris != null) {
9695                    for (int i=ris.size()-1; i>=0; i--) {
9696                        if ((ris.get(i).activityInfo.applicationInfo.flags
9697                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9698                            ris.remove(i);
9699                        }
9700                    }
9701                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9702
9703                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9704
9705                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9706                    for (int i=0; i<ris.size(); i++) {
9707                        ActivityInfo ai = ris.get(i).activityInfo;
9708                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9709                        if (lastDoneReceivers.contains(comp)) {
9710                            // We already did the pre boot receiver for this app with the current
9711                            // platform version, so don't do it again...
9712                            ris.remove(i);
9713                            i--;
9714                            // ...however, do keep it as one that has been done, so we don't
9715                            // forget about it when rewriting the file of last done receivers.
9716                            doneReceivers.add(comp);
9717                        }
9718                    }
9719
9720                    final int[] users = getUsersLocked();
9721                    for (int i=0; i<ris.size(); i++) {
9722                        ActivityInfo ai = ris.get(i).activityInfo;
9723                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9724                        doneReceivers.add(comp);
9725                        intent.setComponent(comp);
9726                        for (int j=0; j<users.length; j++) {
9727                            IIntentReceiver finisher = null;
9728                            if (i == ris.size()-1 && j == users.length-1) {
9729                                finisher = new IIntentReceiver.Stub() {
9730                                    public void performReceive(Intent intent, int resultCode,
9731                                            String data, Bundle extras, boolean ordered,
9732                                            boolean sticky, int sendingUser) {
9733                                        // The raw IIntentReceiver interface is called
9734                                        // with the AM lock held, so redispatch to
9735                                        // execute our code without the lock.
9736                                        mHandler.post(new Runnable() {
9737                                            public void run() {
9738                                                synchronized (ActivityManagerService.this) {
9739                                                    mDidUpdate = true;
9740                                                }
9741                                                writeLastDonePreBootReceivers(doneReceivers);
9742                                                showBootMessage(mContext.getText(
9743                                                        R.string.android_upgrading_complete),
9744                                                        false);
9745                                                systemReady(goingCallback);
9746                                            }
9747                                        });
9748                                    }
9749                                };
9750                            }
9751                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9752                                    + " for user " + users[j]);
9753                            broadcastIntentLocked(null, null, intent, null, finisher,
9754                                    0, null, null, null, AppOpsManager.OP_NONE,
9755                                    true, false, MY_PID, Process.SYSTEM_UID,
9756                                    users[j]);
9757                            if (finisher != null) {
9758                                mWaitingUpdate = true;
9759                            }
9760                        }
9761                    }
9762                }
9763                if (mWaitingUpdate) {
9764                    return;
9765                }
9766                mDidUpdate = true;
9767            }
9768
9769            mAppOpsService.systemReady();
9770            mUsageStatsService.systemReady();
9771            mSystemReady = true;
9772        }
9773
9774        ArrayList<ProcessRecord> procsToKill = null;
9775        synchronized(mPidsSelfLocked) {
9776            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9777                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9778                if (!isAllowedWhileBooting(proc.info)){
9779                    if (procsToKill == null) {
9780                        procsToKill = new ArrayList<ProcessRecord>();
9781                    }
9782                    procsToKill.add(proc);
9783                }
9784            }
9785        }
9786
9787        synchronized(this) {
9788            if (procsToKill != null) {
9789                for (int i=procsToKill.size()-1; i>=0; i--) {
9790                    ProcessRecord proc = procsToKill.get(i);
9791                    Slog.i(TAG, "Removing system update proc: " + proc);
9792                    removeProcessLocked(proc, true, false, "system update done");
9793                }
9794            }
9795
9796            // Now that we have cleaned up any update processes, we
9797            // are ready to start launching real processes and know that
9798            // we won't trample on them any more.
9799            mProcessesReady = true;
9800        }
9801
9802        Slog.i(TAG, "System now ready");
9803        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9804            SystemClock.uptimeMillis());
9805
9806        synchronized(this) {
9807            // Make sure we have no pre-ready processes sitting around.
9808
9809            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9810                ResolveInfo ri = mContext.getPackageManager()
9811                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9812                                STOCK_PM_FLAGS);
9813                CharSequence errorMsg = null;
9814                if (ri != null) {
9815                    ActivityInfo ai = ri.activityInfo;
9816                    ApplicationInfo app = ai.applicationInfo;
9817                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9818                        mTopAction = Intent.ACTION_FACTORY_TEST;
9819                        mTopData = null;
9820                        mTopComponent = new ComponentName(app.packageName,
9821                                ai.name);
9822                    } else {
9823                        errorMsg = mContext.getResources().getText(
9824                                com.android.internal.R.string.factorytest_not_system);
9825                    }
9826                } else {
9827                    errorMsg = mContext.getResources().getText(
9828                            com.android.internal.R.string.factorytest_no_action);
9829                }
9830                if (errorMsg != null) {
9831                    mTopAction = null;
9832                    mTopData = null;
9833                    mTopComponent = null;
9834                    Message msg = Message.obtain();
9835                    msg.what = SHOW_FACTORY_ERROR_MSG;
9836                    msg.getData().putCharSequence("msg", errorMsg);
9837                    mHandler.sendMessage(msg);
9838                }
9839            }
9840        }
9841
9842        retrieveSettings();
9843
9844        synchronized (this) {
9845            readGrantedUriPermissionsLocked();
9846        }
9847
9848        if (goingCallback != null) goingCallback.run();
9849
9850        mSystemServiceManager.startUser(mCurrentUserId);
9851
9852        synchronized (this) {
9853            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9854                try {
9855                    List apps = AppGlobals.getPackageManager().
9856                        getPersistentApplications(STOCK_PM_FLAGS);
9857                    if (apps != null) {
9858                        int N = apps.size();
9859                        int i;
9860                        for (i=0; i<N; i++) {
9861                            ApplicationInfo info
9862                                = (ApplicationInfo)apps.get(i);
9863                            if (info != null &&
9864                                    !info.packageName.equals("android")) {
9865                                addAppLocked(info, false, null /* ABI override */);
9866                            }
9867                        }
9868                    }
9869                } catch (RemoteException ex) {
9870                    // pm is in same process, this will never happen.
9871                }
9872            }
9873
9874            // Start up initial activity.
9875            mBooting = true;
9876
9877            try {
9878                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9879                    Message msg = Message.obtain();
9880                    msg.what = SHOW_UID_ERROR_MSG;
9881                    mHandler.sendMessage(msg);
9882                }
9883            } catch (RemoteException e) {
9884            }
9885
9886            long ident = Binder.clearCallingIdentity();
9887            try {
9888                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9889                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9890                        | Intent.FLAG_RECEIVER_FOREGROUND);
9891                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9892                broadcastIntentLocked(null, null, intent,
9893                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9894                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9895                intent = new Intent(Intent.ACTION_USER_STARTING);
9896                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9897                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9898                broadcastIntentLocked(null, null, intent,
9899                        null, new IIntentReceiver.Stub() {
9900                            @Override
9901                            public void performReceive(Intent intent, int resultCode, String data,
9902                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9903                                    throws RemoteException {
9904                            }
9905                        }, 0, null, null,
9906                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9907                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9908            } catch (Throwable t) {
9909                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9910            } finally {
9911                Binder.restoreCallingIdentity(ident);
9912            }
9913            mStackSupervisor.resumeTopActivitiesLocked();
9914            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9915        }
9916    }
9917
9918    private boolean makeAppCrashingLocked(ProcessRecord app,
9919            String shortMsg, String longMsg, String stackTrace) {
9920        app.crashing = true;
9921        app.crashingReport = generateProcessError(app,
9922                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9923        startAppProblemLocked(app);
9924        app.stopFreezingAllLocked();
9925        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9926    }
9927
9928    private void makeAppNotRespondingLocked(ProcessRecord app,
9929            String activity, String shortMsg, String longMsg) {
9930        app.notResponding = true;
9931        app.notRespondingReport = generateProcessError(app,
9932                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9933                activity, shortMsg, longMsg, null);
9934        startAppProblemLocked(app);
9935        app.stopFreezingAllLocked();
9936    }
9937
9938    /**
9939     * Generate a process error record, suitable for attachment to a ProcessRecord.
9940     *
9941     * @param app The ProcessRecord in which the error occurred.
9942     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9943     *                      ActivityManager.AppErrorStateInfo
9944     * @param activity The activity associated with the crash, if known.
9945     * @param shortMsg Short message describing the crash.
9946     * @param longMsg Long message describing the crash.
9947     * @param stackTrace Full crash stack trace, may be null.
9948     *
9949     * @return Returns a fully-formed AppErrorStateInfo record.
9950     */
9951    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9952            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9953        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9954
9955        report.condition = condition;
9956        report.processName = app.processName;
9957        report.pid = app.pid;
9958        report.uid = app.info.uid;
9959        report.tag = activity;
9960        report.shortMsg = shortMsg;
9961        report.longMsg = longMsg;
9962        report.stackTrace = stackTrace;
9963
9964        return report;
9965    }
9966
9967    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9968        synchronized (this) {
9969            app.crashing = false;
9970            app.crashingReport = null;
9971            app.notResponding = false;
9972            app.notRespondingReport = null;
9973            if (app.anrDialog == fromDialog) {
9974                app.anrDialog = null;
9975            }
9976            if (app.waitDialog == fromDialog) {
9977                app.waitDialog = null;
9978            }
9979            if (app.pid > 0 && app.pid != MY_PID) {
9980                handleAppCrashLocked(app, null, null, null);
9981                killUnneededProcessLocked(app, "user request after error");
9982            }
9983        }
9984    }
9985
9986    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9987            String stackTrace) {
9988        long now = SystemClock.uptimeMillis();
9989
9990        Long crashTime;
9991        if (!app.isolated) {
9992            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9993        } else {
9994            crashTime = null;
9995        }
9996        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9997            // This process loses!
9998            Slog.w(TAG, "Process " + app.info.processName
9999                    + " has crashed too many times: killing!");
10000            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10001                    app.userId, app.info.processName, app.uid);
10002            mStackSupervisor.handleAppCrashLocked(app);
10003            if (!app.persistent) {
10004                // We don't want to start this process again until the user
10005                // explicitly does so...  but for persistent process, we really
10006                // need to keep it running.  If a persistent process is actually
10007                // repeatedly crashing, then badness for everyone.
10008                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10009                        app.info.processName);
10010                if (!app.isolated) {
10011                    // XXX We don't have a way to mark isolated processes
10012                    // as bad, since they don't have a peristent identity.
10013                    mBadProcesses.put(app.info.processName, app.uid,
10014                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10015                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10016                }
10017                app.bad = true;
10018                app.removed = true;
10019                // Don't let services in this process be restarted and potentially
10020                // annoy the user repeatedly.  Unless it is persistent, since those
10021                // processes run critical code.
10022                removeProcessLocked(app, false, false, "crash");
10023                mStackSupervisor.resumeTopActivitiesLocked();
10024                return false;
10025            }
10026            mStackSupervisor.resumeTopActivitiesLocked();
10027        } else {
10028            mStackSupervisor.finishTopRunningActivityLocked(app);
10029        }
10030
10031        // Bump up the crash count of any services currently running in the proc.
10032        for (int i=app.services.size()-1; i>=0; i--) {
10033            // Any services running in the application need to be placed
10034            // back in the pending list.
10035            ServiceRecord sr = app.services.valueAt(i);
10036            sr.crashCount++;
10037        }
10038
10039        // If the crashing process is what we consider to be the "home process" and it has been
10040        // replaced by a third-party app, clear the package preferred activities from packages
10041        // with a home activity running in the process to prevent a repeatedly crashing app
10042        // from blocking the user to manually clear the list.
10043        final ArrayList<ActivityRecord> activities = app.activities;
10044        if (app == mHomeProcess && activities.size() > 0
10045                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10046            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10047                final ActivityRecord r = activities.get(activityNdx);
10048                if (r.isHomeActivity()) {
10049                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10050                    try {
10051                        ActivityThread.getPackageManager()
10052                                .clearPackagePreferredActivities(r.packageName);
10053                    } catch (RemoteException c) {
10054                        // pm is in same process, this will never happen.
10055                    }
10056                }
10057            }
10058        }
10059
10060        if (!app.isolated) {
10061            // XXX Can't keep track of crash times for isolated processes,
10062            // because they don't have a perisistent identity.
10063            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10064        }
10065
10066        return true;
10067    }
10068
10069    void startAppProblemLocked(ProcessRecord app) {
10070        if (app.userId == mCurrentUserId) {
10071            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10072                    mContext, app.info.packageName, app.info.flags);
10073        } else {
10074            // If this app is not running under the current user, then we
10075            // can't give it a report button because that would require
10076            // launching the report UI under a different user.
10077            app.errorReportReceiver = null;
10078        }
10079        skipCurrentReceiverLocked(app);
10080    }
10081
10082    void skipCurrentReceiverLocked(ProcessRecord app) {
10083        for (BroadcastQueue queue : mBroadcastQueues) {
10084            queue.skipCurrentReceiverLocked(app);
10085        }
10086    }
10087
10088    /**
10089     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10090     * The application process will exit immediately after this call returns.
10091     * @param app object of the crashing app, null for the system server
10092     * @param crashInfo describing the exception
10093     */
10094    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10095        ProcessRecord r = findAppProcess(app, "Crash");
10096        final String processName = app == null ? "system_server"
10097                : (r == null ? "unknown" : r.processName);
10098
10099        handleApplicationCrashInner("crash", r, processName, crashInfo);
10100    }
10101
10102    /* Native crash reporting uses this inner version because it needs to be somewhat
10103     * decoupled from the AM-managed cleanup lifecycle
10104     */
10105    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10106            ApplicationErrorReport.CrashInfo crashInfo) {
10107        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10108                UserHandle.getUserId(Binder.getCallingUid()), processName,
10109                r == null ? -1 : r.info.flags,
10110                crashInfo.exceptionClassName,
10111                crashInfo.exceptionMessage,
10112                crashInfo.throwFileName,
10113                crashInfo.throwLineNumber);
10114
10115        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10116
10117        crashApplication(r, crashInfo);
10118    }
10119
10120    public void handleApplicationStrictModeViolation(
10121            IBinder app,
10122            int violationMask,
10123            StrictMode.ViolationInfo info) {
10124        ProcessRecord r = findAppProcess(app, "StrictMode");
10125        if (r == null) {
10126            return;
10127        }
10128
10129        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10130            Integer stackFingerprint = info.hashCode();
10131            boolean logIt = true;
10132            synchronized (mAlreadyLoggedViolatedStacks) {
10133                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10134                    logIt = false;
10135                    // TODO: sub-sample into EventLog for these, with
10136                    // the info.durationMillis?  Then we'd get
10137                    // the relative pain numbers, without logging all
10138                    // the stack traces repeatedly.  We'd want to do
10139                    // likewise in the client code, which also does
10140                    // dup suppression, before the Binder call.
10141                } else {
10142                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10143                        mAlreadyLoggedViolatedStacks.clear();
10144                    }
10145                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10146                }
10147            }
10148            if (logIt) {
10149                logStrictModeViolationToDropBox(r, info);
10150            }
10151        }
10152
10153        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10154            AppErrorResult result = new AppErrorResult();
10155            synchronized (this) {
10156                final long origId = Binder.clearCallingIdentity();
10157
10158                Message msg = Message.obtain();
10159                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10160                HashMap<String, Object> data = new HashMap<String, Object>();
10161                data.put("result", result);
10162                data.put("app", r);
10163                data.put("violationMask", violationMask);
10164                data.put("info", info);
10165                msg.obj = data;
10166                mHandler.sendMessage(msg);
10167
10168                Binder.restoreCallingIdentity(origId);
10169            }
10170            int res = result.get();
10171            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10172        }
10173    }
10174
10175    // Depending on the policy in effect, there could be a bunch of
10176    // these in quick succession so we try to batch these together to
10177    // minimize disk writes, number of dropbox entries, and maximize
10178    // compression, by having more fewer, larger records.
10179    private void logStrictModeViolationToDropBox(
10180            ProcessRecord process,
10181            StrictMode.ViolationInfo info) {
10182        if (info == null) {
10183            return;
10184        }
10185        final boolean isSystemApp = process == null ||
10186                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10187                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10188        final String processName = process == null ? "unknown" : process.processName;
10189        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10190        final DropBoxManager dbox = (DropBoxManager)
10191                mContext.getSystemService(Context.DROPBOX_SERVICE);
10192
10193        // Exit early if the dropbox isn't configured to accept this report type.
10194        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10195
10196        boolean bufferWasEmpty;
10197        boolean needsFlush;
10198        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10199        synchronized (sb) {
10200            bufferWasEmpty = sb.length() == 0;
10201            appendDropBoxProcessHeaders(process, processName, sb);
10202            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10203            sb.append("System-App: ").append(isSystemApp).append("\n");
10204            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10205            if (info.violationNumThisLoop != 0) {
10206                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10207            }
10208            if (info.numAnimationsRunning != 0) {
10209                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10210            }
10211            if (info.broadcastIntentAction != null) {
10212                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10213            }
10214            if (info.durationMillis != -1) {
10215                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10216            }
10217            if (info.numInstances != -1) {
10218                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10219            }
10220            if (info.tags != null) {
10221                for (String tag : info.tags) {
10222                    sb.append("Span-Tag: ").append(tag).append("\n");
10223                }
10224            }
10225            sb.append("\n");
10226            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10227                sb.append(info.crashInfo.stackTrace);
10228            }
10229            sb.append("\n");
10230
10231            // Only buffer up to ~64k.  Various logging bits truncate
10232            // things at 128k.
10233            needsFlush = (sb.length() > 64 * 1024);
10234        }
10235
10236        // Flush immediately if the buffer's grown too large, or this
10237        // is a non-system app.  Non-system apps are isolated with a
10238        // different tag & policy and not batched.
10239        //
10240        // Batching is useful during internal testing with
10241        // StrictMode settings turned up high.  Without batching,
10242        // thousands of separate files could be created on boot.
10243        if (!isSystemApp || needsFlush) {
10244            new Thread("Error dump: " + dropboxTag) {
10245                @Override
10246                public void run() {
10247                    String report;
10248                    synchronized (sb) {
10249                        report = sb.toString();
10250                        sb.delete(0, sb.length());
10251                        sb.trimToSize();
10252                    }
10253                    if (report.length() != 0) {
10254                        dbox.addText(dropboxTag, report);
10255                    }
10256                }
10257            }.start();
10258            return;
10259        }
10260
10261        // System app batching:
10262        if (!bufferWasEmpty) {
10263            // An existing dropbox-writing thread is outstanding, so
10264            // we don't need to start it up.  The existing thread will
10265            // catch the buffer appends we just did.
10266            return;
10267        }
10268
10269        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10270        // (After this point, we shouldn't access AMS internal data structures.)
10271        new Thread("Error dump: " + dropboxTag) {
10272            @Override
10273            public void run() {
10274                // 5 second sleep to let stacks arrive and be batched together
10275                try {
10276                    Thread.sleep(5000);  // 5 seconds
10277                } catch (InterruptedException e) {}
10278
10279                String errorReport;
10280                synchronized (mStrictModeBuffer) {
10281                    errorReport = mStrictModeBuffer.toString();
10282                    if (errorReport.length() == 0) {
10283                        return;
10284                    }
10285                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10286                    mStrictModeBuffer.trimToSize();
10287                }
10288                dbox.addText(dropboxTag, errorReport);
10289            }
10290        }.start();
10291    }
10292
10293    /**
10294     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10295     * @param app object of the crashing app, null for the system server
10296     * @param tag reported by the caller
10297     * @param crashInfo describing the context of the error
10298     * @return true if the process should exit immediately (WTF is fatal)
10299     */
10300    public boolean handleApplicationWtf(IBinder app, String tag,
10301            ApplicationErrorReport.CrashInfo crashInfo) {
10302        ProcessRecord r = findAppProcess(app, "WTF");
10303        final String processName = app == null ? "system_server"
10304                : (r == null ? "unknown" : r.processName);
10305
10306        EventLog.writeEvent(EventLogTags.AM_WTF,
10307                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10308                processName,
10309                r == null ? -1 : r.info.flags,
10310                tag, crashInfo.exceptionMessage);
10311
10312        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10313
10314        if (r != null && r.pid != Process.myPid() &&
10315                Settings.Global.getInt(mContext.getContentResolver(),
10316                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10317            crashApplication(r, crashInfo);
10318            return true;
10319        } else {
10320            return false;
10321        }
10322    }
10323
10324    /**
10325     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10326     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10327     */
10328    private ProcessRecord findAppProcess(IBinder app, String reason) {
10329        if (app == null) {
10330            return null;
10331        }
10332
10333        synchronized (this) {
10334            final int NP = mProcessNames.getMap().size();
10335            for (int ip=0; ip<NP; ip++) {
10336                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10337                final int NA = apps.size();
10338                for (int ia=0; ia<NA; ia++) {
10339                    ProcessRecord p = apps.valueAt(ia);
10340                    if (p.thread != null && p.thread.asBinder() == app) {
10341                        return p;
10342                    }
10343                }
10344            }
10345
10346            Slog.w(TAG, "Can't find mystery application for " + reason
10347                    + " from pid=" + Binder.getCallingPid()
10348                    + " uid=" + Binder.getCallingUid() + ": " + app);
10349            return null;
10350        }
10351    }
10352
10353    /**
10354     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10355     * to append various headers to the dropbox log text.
10356     */
10357    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10358            StringBuilder sb) {
10359        // Watchdog thread ends up invoking this function (with
10360        // a null ProcessRecord) to add the stack file to dropbox.
10361        // Do not acquire a lock on this (am) in such cases, as it
10362        // could cause a potential deadlock, if and when watchdog
10363        // is invoked due to unavailability of lock on am and it
10364        // would prevent watchdog from killing system_server.
10365        if (process == null) {
10366            sb.append("Process: ").append(processName).append("\n");
10367            return;
10368        }
10369        // Note: ProcessRecord 'process' is guarded by the service
10370        // instance.  (notably process.pkgList, which could otherwise change
10371        // concurrently during execution of this method)
10372        synchronized (this) {
10373            sb.append("Process: ").append(processName).append("\n");
10374            int flags = process.info.flags;
10375            IPackageManager pm = AppGlobals.getPackageManager();
10376            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10377            for (int ip=0; ip<process.pkgList.size(); ip++) {
10378                String pkg = process.pkgList.keyAt(ip);
10379                sb.append("Package: ").append(pkg);
10380                try {
10381                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10382                    if (pi != null) {
10383                        sb.append(" v").append(pi.versionCode);
10384                        if (pi.versionName != null) {
10385                            sb.append(" (").append(pi.versionName).append(")");
10386                        }
10387                    }
10388                } catch (RemoteException e) {
10389                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10390                }
10391                sb.append("\n");
10392            }
10393        }
10394    }
10395
10396    private static String processClass(ProcessRecord process) {
10397        if (process == null || process.pid == MY_PID) {
10398            return "system_server";
10399        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10400            return "system_app";
10401        } else {
10402            return "data_app";
10403        }
10404    }
10405
10406    /**
10407     * Write a description of an error (crash, WTF, ANR) to the drop box.
10408     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10409     * @param process which caused the error, null means the system server
10410     * @param activity which triggered the error, null if unknown
10411     * @param parent activity related to the error, null if unknown
10412     * @param subject line related to the error, null if absent
10413     * @param report in long form describing the error, null if absent
10414     * @param logFile to include in the report, null if none
10415     * @param crashInfo giving an application stack trace, null if absent
10416     */
10417    public void addErrorToDropBox(String eventType,
10418            ProcessRecord process, String processName, ActivityRecord activity,
10419            ActivityRecord parent, String subject,
10420            final String report, final File logFile,
10421            final ApplicationErrorReport.CrashInfo crashInfo) {
10422        // NOTE -- this must never acquire the ActivityManagerService lock,
10423        // otherwise the watchdog may be prevented from resetting the system.
10424
10425        final String dropboxTag = processClass(process) + "_" + eventType;
10426        final DropBoxManager dbox = (DropBoxManager)
10427                mContext.getSystemService(Context.DROPBOX_SERVICE);
10428
10429        // Exit early if the dropbox isn't configured to accept this report type.
10430        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10431
10432        final StringBuilder sb = new StringBuilder(1024);
10433        appendDropBoxProcessHeaders(process, processName, sb);
10434        if (activity != null) {
10435            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10436        }
10437        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10438            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10439        }
10440        if (parent != null && parent != activity) {
10441            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10442        }
10443        if (subject != null) {
10444            sb.append("Subject: ").append(subject).append("\n");
10445        }
10446        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10447        if (Debug.isDebuggerConnected()) {
10448            sb.append("Debugger: Connected\n");
10449        }
10450        sb.append("\n");
10451
10452        // Do the rest in a worker thread to avoid blocking the caller on I/O
10453        // (After this point, we shouldn't access AMS internal data structures.)
10454        Thread worker = new Thread("Error dump: " + dropboxTag) {
10455            @Override
10456            public void run() {
10457                if (report != null) {
10458                    sb.append(report);
10459                }
10460                if (logFile != null) {
10461                    try {
10462                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10463                                    "\n\n[[TRUNCATED]]"));
10464                    } catch (IOException e) {
10465                        Slog.e(TAG, "Error reading " + logFile, e);
10466                    }
10467                }
10468                if (crashInfo != null && crashInfo.stackTrace != null) {
10469                    sb.append(crashInfo.stackTrace);
10470                }
10471
10472                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10473                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10474                if (lines > 0) {
10475                    sb.append("\n");
10476
10477                    // Merge several logcat streams, and take the last N lines
10478                    InputStreamReader input = null;
10479                    try {
10480                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10481                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10482                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10483
10484                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10485                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10486                        input = new InputStreamReader(logcat.getInputStream());
10487
10488                        int num;
10489                        char[] buf = new char[8192];
10490                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10491                    } catch (IOException e) {
10492                        Slog.e(TAG, "Error running logcat", e);
10493                    } finally {
10494                        if (input != null) try { input.close(); } catch (IOException e) {}
10495                    }
10496                }
10497
10498                dbox.addText(dropboxTag, sb.toString());
10499            }
10500        };
10501
10502        if (process == null) {
10503            // If process is null, we are being called from some internal code
10504            // and may be about to die -- run this synchronously.
10505            worker.run();
10506        } else {
10507            worker.start();
10508        }
10509    }
10510
10511    /**
10512     * Bring up the "unexpected error" dialog box for a crashing app.
10513     * Deal with edge cases (intercepts from instrumented applications,
10514     * ActivityController, error intent receivers, that sort of thing).
10515     * @param r the application crashing
10516     * @param crashInfo describing the failure
10517     */
10518    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10519        long timeMillis = System.currentTimeMillis();
10520        String shortMsg = crashInfo.exceptionClassName;
10521        String longMsg = crashInfo.exceptionMessage;
10522        String stackTrace = crashInfo.stackTrace;
10523        if (shortMsg != null && longMsg != null) {
10524            longMsg = shortMsg + ": " + longMsg;
10525        } else if (shortMsg != null) {
10526            longMsg = shortMsg;
10527        }
10528
10529        AppErrorResult result = new AppErrorResult();
10530        synchronized (this) {
10531            if (mController != null) {
10532                try {
10533                    String name = r != null ? r.processName : null;
10534                    int pid = r != null ? r.pid : Binder.getCallingPid();
10535                    if (!mController.appCrashed(name, pid,
10536                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10537                        Slog.w(TAG, "Force-killing crashed app " + name
10538                                + " at watcher's request");
10539                        Process.killProcess(pid);
10540                        return;
10541                    }
10542                } catch (RemoteException e) {
10543                    mController = null;
10544                    Watchdog.getInstance().setActivityController(null);
10545                }
10546            }
10547
10548            final long origId = Binder.clearCallingIdentity();
10549
10550            // If this process is running instrumentation, finish it.
10551            if (r != null && r.instrumentationClass != null) {
10552                Slog.w(TAG, "Error in app " + r.processName
10553                      + " running instrumentation " + r.instrumentationClass + ":");
10554                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10555                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10556                Bundle info = new Bundle();
10557                info.putString("shortMsg", shortMsg);
10558                info.putString("longMsg", longMsg);
10559                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10560                Binder.restoreCallingIdentity(origId);
10561                return;
10562            }
10563
10564            // If we can't identify the process or it's already exceeded its crash quota,
10565            // quit right away without showing a crash dialog.
10566            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10567                Binder.restoreCallingIdentity(origId);
10568                return;
10569            }
10570
10571            Message msg = Message.obtain();
10572            msg.what = SHOW_ERROR_MSG;
10573            HashMap data = new HashMap();
10574            data.put("result", result);
10575            data.put("app", r);
10576            msg.obj = data;
10577            mHandler.sendMessage(msg);
10578
10579            Binder.restoreCallingIdentity(origId);
10580        }
10581
10582        int res = result.get();
10583
10584        Intent appErrorIntent = null;
10585        synchronized (this) {
10586            if (r != null && !r.isolated) {
10587                // XXX Can't keep track of crash time for isolated processes,
10588                // since they don't have a persistent identity.
10589                mProcessCrashTimes.put(r.info.processName, r.uid,
10590                        SystemClock.uptimeMillis());
10591            }
10592            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10593                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10594            }
10595        }
10596
10597        if (appErrorIntent != null) {
10598            try {
10599                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10600            } catch (ActivityNotFoundException e) {
10601                Slog.w(TAG, "bug report receiver dissappeared", e);
10602            }
10603        }
10604    }
10605
10606    Intent createAppErrorIntentLocked(ProcessRecord r,
10607            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10608        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10609        if (report == null) {
10610            return null;
10611        }
10612        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10613        result.setComponent(r.errorReportReceiver);
10614        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10615        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10616        return result;
10617    }
10618
10619    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10620            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10621        if (r.errorReportReceiver == null) {
10622            return null;
10623        }
10624
10625        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10626            return null;
10627        }
10628
10629        ApplicationErrorReport report = new ApplicationErrorReport();
10630        report.packageName = r.info.packageName;
10631        report.installerPackageName = r.errorReportReceiver.getPackageName();
10632        report.processName = r.processName;
10633        report.time = timeMillis;
10634        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10635
10636        if (r.crashing || r.forceCrashReport) {
10637            report.type = ApplicationErrorReport.TYPE_CRASH;
10638            report.crashInfo = crashInfo;
10639        } else if (r.notResponding) {
10640            report.type = ApplicationErrorReport.TYPE_ANR;
10641            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10642
10643            report.anrInfo.activity = r.notRespondingReport.tag;
10644            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10645            report.anrInfo.info = r.notRespondingReport.longMsg;
10646        }
10647
10648        return report;
10649    }
10650
10651    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10652        enforceNotIsolatedCaller("getProcessesInErrorState");
10653        // assume our apps are happy - lazy create the list
10654        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10655
10656        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10657                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10658        int userId = UserHandle.getUserId(Binder.getCallingUid());
10659
10660        synchronized (this) {
10661
10662            // iterate across all processes
10663            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10664                ProcessRecord app = mLruProcesses.get(i);
10665                if (!allUsers && app.userId != userId) {
10666                    continue;
10667                }
10668                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10669                    // This one's in trouble, so we'll generate a report for it
10670                    // crashes are higher priority (in case there's a crash *and* an anr)
10671                    ActivityManager.ProcessErrorStateInfo report = null;
10672                    if (app.crashing) {
10673                        report = app.crashingReport;
10674                    } else if (app.notResponding) {
10675                        report = app.notRespondingReport;
10676                    }
10677
10678                    if (report != null) {
10679                        if (errList == null) {
10680                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10681                        }
10682                        errList.add(report);
10683                    } else {
10684                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10685                                " crashing = " + app.crashing +
10686                                " notResponding = " + app.notResponding);
10687                    }
10688                }
10689            }
10690        }
10691
10692        return errList;
10693    }
10694
10695    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10696        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10697            if (currApp != null) {
10698                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10699            }
10700            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10701        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10702            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10703        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10704            if (currApp != null) {
10705                currApp.lru = 0;
10706            }
10707            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10708        } else if (adj >= ProcessList.SERVICE_ADJ) {
10709            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10710        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10711            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10712        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10713            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10714        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10715            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10716        } else {
10717            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10718        }
10719    }
10720
10721    private void fillInProcMemInfo(ProcessRecord app,
10722            ActivityManager.RunningAppProcessInfo outInfo) {
10723        outInfo.pid = app.pid;
10724        outInfo.uid = app.info.uid;
10725        if (mHeavyWeightProcess == app) {
10726            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10727        }
10728        if (app.persistent) {
10729            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10730        }
10731        if (app.activities.size() > 0) {
10732            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10733        }
10734        outInfo.lastTrimLevel = app.trimMemoryLevel;
10735        int adj = app.curAdj;
10736        outInfo.importance = oomAdjToImportance(adj, outInfo);
10737        outInfo.importanceReasonCode = app.adjTypeCode;
10738        outInfo.processState = app.curProcState;
10739    }
10740
10741    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10742        enforceNotIsolatedCaller("getRunningAppProcesses");
10743        // Lazy instantiation of list
10744        List<ActivityManager.RunningAppProcessInfo> runList = null;
10745        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10746                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10747        int userId = UserHandle.getUserId(Binder.getCallingUid());
10748        synchronized (this) {
10749            // Iterate across all processes
10750            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10751                ProcessRecord app = mLruProcesses.get(i);
10752                if (!allUsers && app.userId != userId) {
10753                    continue;
10754                }
10755                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10756                    // Generate process state info for running application
10757                    ActivityManager.RunningAppProcessInfo currApp =
10758                        new ActivityManager.RunningAppProcessInfo(app.processName,
10759                                app.pid, app.getPackageList());
10760                    fillInProcMemInfo(app, currApp);
10761                    if (app.adjSource instanceof ProcessRecord) {
10762                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10763                        currApp.importanceReasonImportance = oomAdjToImportance(
10764                                app.adjSourceOom, null);
10765                    } else if (app.adjSource instanceof ActivityRecord) {
10766                        ActivityRecord r = (ActivityRecord)app.adjSource;
10767                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10768                    }
10769                    if (app.adjTarget instanceof ComponentName) {
10770                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10771                    }
10772                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10773                    //        + " lru=" + currApp.lru);
10774                    if (runList == null) {
10775                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10776                    }
10777                    runList.add(currApp);
10778                }
10779            }
10780        }
10781        return runList;
10782    }
10783
10784    public List<ApplicationInfo> getRunningExternalApplications() {
10785        enforceNotIsolatedCaller("getRunningExternalApplications");
10786        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10787        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10788        if (runningApps != null && runningApps.size() > 0) {
10789            Set<String> extList = new HashSet<String>();
10790            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10791                if (app.pkgList != null) {
10792                    for (String pkg : app.pkgList) {
10793                        extList.add(pkg);
10794                    }
10795                }
10796            }
10797            IPackageManager pm = AppGlobals.getPackageManager();
10798            for (String pkg : extList) {
10799                try {
10800                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10801                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10802                        retList.add(info);
10803                    }
10804                } catch (RemoteException e) {
10805                }
10806            }
10807        }
10808        return retList;
10809    }
10810
10811    @Override
10812    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10813        enforceNotIsolatedCaller("getMyMemoryState");
10814        synchronized (this) {
10815            ProcessRecord proc;
10816            synchronized (mPidsSelfLocked) {
10817                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10818            }
10819            fillInProcMemInfo(proc, outInfo);
10820        }
10821    }
10822
10823    @Override
10824    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10825        if (checkCallingPermission(android.Manifest.permission.DUMP)
10826                != PackageManager.PERMISSION_GRANTED) {
10827            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10828                    + Binder.getCallingPid()
10829                    + ", uid=" + Binder.getCallingUid()
10830                    + " without permission "
10831                    + android.Manifest.permission.DUMP);
10832            return;
10833        }
10834
10835        boolean dumpAll = false;
10836        boolean dumpClient = false;
10837        String dumpPackage = null;
10838
10839        int opti = 0;
10840        while (opti < args.length) {
10841            String opt = args[opti];
10842            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10843                break;
10844            }
10845            opti++;
10846            if ("-a".equals(opt)) {
10847                dumpAll = true;
10848            } else if ("-c".equals(opt)) {
10849                dumpClient = true;
10850            } else if ("-h".equals(opt)) {
10851                pw.println("Activity manager dump options:");
10852                pw.println("  [-a] [-c] [-h] [cmd] ...");
10853                pw.println("  cmd may be one of:");
10854                pw.println("    a[ctivities]: activity stack state");
10855                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10856                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10857                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10858                pw.println("    o[om]: out of memory management");
10859                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10860                pw.println("    provider [COMP_SPEC]: provider client-side state");
10861                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10862                pw.println("    service [COMP_SPEC]: service client-side state");
10863                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10864                pw.println("    all: dump all activities");
10865                pw.println("    top: dump the top activity");
10866                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10867                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10868                pw.println("    a partial substring in a component name, a");
10869                pw.println("    hex object identifier.");
10870                pw.println("  -a: include all available server state.");
10871                pw.println("  -c: include client state.");
10872                return;
10873            } else {
10874                pw.println("Unknown argument: " + opt + "; use -h for help");
10875            }
10876        }
10877
10878        long origId = Binder.clearCallingIdentity();
10879        boolean more = false;
10880        // Is the caller requesting to dump a particular piece of data?
10881        if (opti < args.length) {
10882            String cmd = args[opti];
10883            opti++;
10884            if ("activities".equals(cmd) || "a".equals(cmd)) {
10885                synchronized (this) {
10886                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10887                }
10888            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10889                String[] newArgs;
10890                String name;
10891                if (opti >= args.length) {
10892                    name = null;
10893                    newArgs = EMPTY_STRING_ARRAY;
10894                } else {
10895                    name = args[opti];
10896                    opti++;
10897                    newArgs = new String[args.length - opti];
10898                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10899                            args.length - opti);
10900                }
10901                synchronized (this) {
10902                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10903                }
10904            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10905                String[] newArgs;
10906                String name;
10907                if (opti >= args.length) {
10908                    name = null;
10909                    newArgs = EMPTY_STRING_ARRAY;
10910                } else {
10911                    name = args[opti];
10912                    opti++;
10913                    newArgs = new String[args.length - opti];
10914                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10915                            args.length - opti);
10916                }
10917                synchronized (this) {
10918                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10919                }
10920            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10921                String[] newArgs;
10922                String name;
10923                if (opti >= args.length) {
10924                    name = null;
10925                    newArgs = EMPTY_STRING_ARRAY;
10926                } else {
10927                    name = args[opti];
10928                    opti++;
10929                    newArgs = new String[args.length - opti];
10930                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10931                            args.length - opti);
10932                }
10933                synchronized (this) {
10934                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10935                }
10936            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10937                synchronized (this) {
10938                    dumpOomLocked(fd, pw, args, opti, true);
10939                }
10940            } else if ("provider".equals(cmd)) {
10941                String[] newArgs;
10942                String name;
10943                if (opti >= args.length) {
10944                    name = null;
10945                    newArgs = EMPTY_STRING_ARRAY;
10946                } else {
10947                    name = args[opti];
10948                    opti++;
10949                    newArgs = new String[args.length - opti];
10950                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10951                }
10952                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10953                    pw.println("No providers match: " + name);
10954                    pw.println("Use -h for help.");
10955                }
10956            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10957                synchronized (this) {
10958                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10959                }
10960            } else if ("service".equals(cmd)) {
10961                String[] newArgs;
10962                String name;
10963                if (opti >= args.length) {
10964                    name = null;
10965                    newArgs = EMPTY_STRING_ARRAY;
10966                } else {
10967                    name = args[opti];
10968                    opti++;
10969                    newArgs = new String[args.length - opti];
10970                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10971                            args.length - opti);
10972                }
10973                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10974                    pw.println("No services match: " + name);
10975                    pw.println("Use -h for help.");
10976                }
10977            } else if ("package".equals(cmd)) {
10978                String[] newArgs;
10979                if (opti >= args.length) {
10980                    pw.println("package: no package name specified");
10981                    pw.println("Use -h for help.");
10982                } else {
10983                    dumpPackage = args[opti];
10984                    opti++;
10985                    newArgs = new String[args.length - opti];
10986                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10987                            args.length - opti);
10988                    args = newArgs;
10989                    opti = 0;
10990                    more = true;
10991                }
10992            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10993                synchronized (this) {
10994                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10995                }
10996            } else {
10997                // Dumping a single activity?
10998                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10999                    pw.println("Bad activity command, or no activities match: " + cmd);
11000                    pw.println("Use -h for help.");
11001                }
11002            }
11003            if (!more) {
11004                Binder.restoreCallingIdentity(origId);
11005                return;
11006            }
11007        }
11008
11009        // No piece of data specified, dump everything.
11010        synchronized (this) {
11011            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11012            pw.println();
11013            if (dumpAll) {
11014                pw.println("-------------------------------------------------------------------------------");
11015            }
11016            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11017            pw.println();
11018            if (dumpAll) {
11019                pw.println("-------------------------------------------------------------------------------");
11020            }
11021            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11022            pw.println();
11023            if (dumpAll) {
11024                pw.println("-------------------------------------------------------------------------------");
11025            }
11026            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11027            pw.println();
11028            if (dumpAll) {
11029                pw.println("-------------------------------------------------------------------------------");
11030            }
11031            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11032            pw.println();
11033            if (dumpAll) {
11034                pw.println("-------------------------------------------------------------------------------");
11035            }
11036            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11037        }
11038        Binder.restoreCallingIdentity(origId);
11039    }
11040
11041    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11042            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11043        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11044
11045        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11046                dumpPackage);
11047        boolean needSep = printedAnything;
11048
11049        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11050                dumpPackage, needSep, "  mFocusedActivity: ");
11051        if (printed) {
11052            printedAnything = true;
11053            needSep = false;
11054        }
11055
11056        if (dumpPackage == null) {
11057            if (needSep) {
11058                pw.println();
11059            }
11060            needSep = true;
11061            printedAnything = true;
11062            mStackSupervisor.dump(pw, "  ");
11063        }
11064
11065        if (mRecentTasks.size() > 0) {
11066            boolean printedHeader = false;
11067
11068            final int N = mRecentTasks.size();
11069            for (int i=0; i<N; i++) {
11070                TaskRecord tr = mRecentTasks.get(i);
11071                if (dumpPackage != null) {
11072                    if (tr.realActivity == null ||
11073                            !dumpPackage.equals(tr.realActivity)) {
11074                        continue;
11075                    }
11076                }
11077                if (!printedHeader) {
11078                    if (needSep) {
11079                        pw.println();
11080                    }
11081                    pw.println("  Recent tasks:");
11082                    printedHeader = true;
11083                    printedAnything = true;
11084                }
11085                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11086                        pw.println(tr);
11087                if (dumpAll) {
11088                    mRecentTasks.get(i).dump(pw, "    ");
11089                }
11090            }
11091        }
11092
11093        if (!printedAnything) {
11094            pw.println("  (nothing)");
11095        }
11096    }
11097
11098    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11099            int opti, boolean dumpAll, String dumpPackage) {
11100        boolean needSep = false;
11101        boolean printedAnything = false;
11102        int numPers = 0;
11103
11104        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11105
11106        if (dumpAll) {
11107            final int NP = mProcessNames.getMap().size();
11108            for (int ip=0; ip<NP; ip++) {
11109                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11110                final int NA = procs.size();
11111                for (int ia=0; ia<NA; ia++) {
11112                    ProcessRecord r = procs.valueAt(ia);
11113                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11114                        continue;
11115                    }
11116                    if (!needSep) {
11117                        pw.println("  All known processes:");
11118                        needSep = true;
11119                        printedAnything = true;
11120                    }
11121                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11122                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11123                        pw.print(" "); pw.println(r);
11124                    r.dump(pw, "    ");
11125                    if (r.persistent) {
11126                        numPers++;
11127                    }
11128                }
11129            }
11130        }
11131
11132        if (mIsolatedProcesses.size() > 0) {
11133            boolean printed = false;
11134            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11135                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11136                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11137                    continue;
11138                }
11139                if (!printed) {
11140                    if (needSep) {
11141                        pw.println();
11142                    }
11143                    pw.println("  Isolated process list (sorted by uid):");
11144                    printedAnything = true;
11145                    printed = true;
11146                    needSep = true;
11147                }
11148                pw.println(String.format("%sIsolated #%2d: %s",
11149                        "    ", i, r.toString()));
11150            }
11151        }
11152
11153        if (mLruProcesses.size() > 0) {
11154            if (needSep) {
11155                pw.println();
11156            }
11157            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11158                    pw.print(" total, non-act at ");
11159                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11160                    pw.print(", non-svc at ");
11161                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11162                    pw.println("):");
11163            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11164            needSep = true;
11165            printedAnything = true;
11166        }
11167
11168        if (dumpAll || dumpPackage != null) {
11169            synchronized (mPidsSelfLocked) {
11170                boolean printed = false;
11171                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11172                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11173                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11174                        continue;
11175                    }
11176                    if (!printed) {
11177                        if (needSep) pw.println();
11178                        needSep = true;
11179                        pw.println("  PID mappings:");
11180                        printed = true;
11181                        printedAnything = true;
11182                    }
11183                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11184                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11185                }
11186            }
11187        }
11188
11189        if (mForegroundProcesses.size() > 0) {
11190            synchronized (mPidsSelfLocked) {
11191                boolean printed = false;
11192                for (int i=0; i<mForegroundProcesses.size(); i++) {
11193                    ProcessRecord r = mPidsSelfLocked.get(
11194                            mForegroundProcesses.valueAt(i).pid);
11195                    if (dumpPackage != null && (r == null
11196                            || !r.pkgList.containsKey(dumpPackage))) {
11197                        continue;
11198                    }
11199                    if (!printed) {
11200                        if (needSep) pw.println();
11201                        needSep = true;
11202                        pw.println("  Foreground Processes:");
11203                        printed = true;
11204                        printedAnything = true;
11205                    }
11206                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11207                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11208                }
11209            }
11210        }
11211
11212        if (mPersistentStartingProcesses.size() > 0) {
11213            if (needSep) pw.println();
11214            needSep = true;
11215            printedAnything = true;
11216            pw.println("  Persisent processes that are starting:");
11217            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11218                    "Starting Norm", "Restarting PERS", dumpPackage);
11219        }
11220
11221        if (mRemovedProcesses.size() > 0) {
11222            if (needSep) pw.println();
11223            needSep = true;
11224            printedAnything = true;
11225            pw.println("  Processes that are being removed:");
11226            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11227                    "Removed Norm", "Removed PERS", dumpPackage);
11228        }
11229
11230        if (mProcessesOnHold.size() > 0) {
11231            if (needSep) pw.println();
11232            needSep = true;
11233            printedAnything = true;
11234            pw.println("  Processes that are on old until the system is ready:");
11235            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11236                    "OnHold Norm", "OnHold PERS", dumpPackage);
11237        }
11238
11239        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11240
11241        if (mProcessCrashTimes.getMap().size() > 0) {
11242            boolean printed = false;
11243            long now = SystemClock.uptimeMillis();
11244            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11245            final int NP = pmap.size();
11246            for (int ip=0; ip<NP; ip++) {
11247                String pname = pmap.keyAt(ip);
11248                SparseArray<Long> uids = pmap.valueAt(ip);
11249                final int N = uids.size();
11250                for (int i=0; i<N; i++) {
11251                    int puid = uids.keyAt(i);
11252                    ProcessRecord r = mProcessNames.get(pname, puid);
11253                    if (dumpPackage != null && (r == null
11254                            || !r.pkgList.containsKey(dumpPackage))) {
11255                        continue;
11256                    }
11257                    if (!printed) {
11258                        if (needSep) pw.println();
11259                        needSep = true;
11260                        pw.println("  Time since processes crashed:");
11261                        printed = true;
11262                        printedAnything = true;
11263                    }
11264                    pw.print("    Process "); pw.print(pname);
11265                            pw.print(" uid "); pw.print(puid);
11266                            pw.print(": last crashed ");
11267                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11268                            pw.println(" ago");
11269                }
11270            }
11271        }
11272
11273        if (mBadProcesses.getMap().size() > 0) {
11274            boolean printed = false;
11275            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11276            final int NP = pmap.size();
11277            for (int ip=0; ip<NP; ip++) {
11278                String pname = pmap.keyAt(ip);
11279                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11280                final int N = uids.size();
11281                for (int i=0; i<N; i++) {
11282                    int puid = uids.keyAt(i);
11283                    ProcessRecord r = mProcessNames.get(pname, puid);
11284                    if (dumpPackage != null && (r == null
11285                            || !r.pkgList.containsKey(dumpPackage))) {
11286                        continue;
11287                    }
11288                    if (!printed) {
11289                        if (needSep) pw.println();
11290                        needSep = true;
11291                        pw.println("  Bad processes:");
11292                        printedAnything = true;
11293                    }
11294                    BadProcessInfo info = uids.valueAt(i);
11295                    pw.print("    Bad process "); pw.print(pname);
11296                            pw.print(" uid "); pw.print(puid);
11297                            pw.print(": crashed at time "); pw.println(info.time);
11298                    if (info.shortMsg != null) {
11299                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11300                    }
11301                    if (info.longMsg != null) {
11302                        pw.print("      Long msg: "); pw.println(info.longMsg);
11303                    }
11304                    if (info.stack != null) {
11305                        pw.println("      Stack:");
11306                        int lastPos = 0;
11307                        for (int pos=0; pos<info.stack.length(); pos++) {
11308                            if (info.stack.charAt(pos) == '\n') {
11309                                pw.print("        ");
11310                                pw.write(info.stack, lastPos, pos-lastPos);
11311                                pw.println();
11312                                lastPos = pos+1;
11313                            }
11314                        }
11315                        if (lastPos < info.stack.length()) {
11316                            pw.print("        ");
11317                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11318                            pw.println();
11319                        }
11320                    }
11321                }
11322            }
11323        }
11324
11325        if (dumpPackage == null) {
11326            pw.println();
11327            needSep = false;
11328            pw.println("  mStartedUsers:");
11329            for (int i=0; i<mStartedUsers.size(); i++) {
11330                UserStartedState uss = mStartedUsers.valueAt(i);
11331                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11332                        pw.print(": "); uss.dump("", pw);
11333            }
11334            pw.print("  mStartedUserArray: [");
11335            for (int i=0; i<mStartedUserArray.length; i++) {
11336                if (i > 0) pw.print(", ");
11337                pw.print(mStartedUserArray[i]);
11338            }
11339            pw.println("]");
11340            pw.print("  mUserLru: [");
11341            for (int i=0; i<mUserLru.size(); i++) {
11342                if (i > 0) pw.print(", ");
11343                pw.print(mUserLru.get(i));
11344            }
11345            pw.println("]");
11346            if (dumpAll) {
11347                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11348            }
11349        }
11350        if (mHomeProcess != null && (dumpPackage == null
11351                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11352            if (needSep) {
11353                pw.println();
11354                needSep = false;
11355            }
11356            pw.println("  mHomeProcess: " + mHomeProcess);
11357        }
11358        if (mPreviousProcess != null && (dumpPackage == null
11359                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11360            if (needSep) {
11361                pw.println();
11362                needSep = false;
11363            }
11364            pw.println("  mPreviousProcess: " + mPreviousProcess);
11365        }
11366        if (dumpAll) {
11367            StringBuilder sb = new StringBuilder(128);
11368            sb.append("  mPreviousProcessVisibleTime: ");
11369            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11370            pw.println(sb);
11371        }
11372        if (mHeavyWeightProcess != null && (dumpPackage == null
11373                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11374            if (needSep) {
11375                pw.println();
11376                needSep = false;
11377            }
11378            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11379        }
11380        if (dumpPackage == null) {
11381            pw.println("  mConfiguration: " + mConfiguration);
11382        }
11383        if (dumpAll) {
11384            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11385            if (mCompatModePackages.getPackages().size() > 0) {
11386                boolean printed = false;
11387                for (Map.Entry<String, Integer> entry
11388                        : mCompatModePackages.getPackages().entrySet()) {
11389                    String pkg = entry.getKey();
11390                    int mode = entry.getValue();
11391                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11392                        continue;
11393                    }
11394                    if (!printed) {
11395                        pw.println("  mScreenCompatPackages:");
11396                        printed = true;
11397                    }
11398                    pw.print("    "); pw.print(pkg); pw.print(": ");
11399                            pw.print(mode); pw.println();
11400                }
11401            }
11402        }
11403        if (dumpPackage == null) {
11404            if (mSleeping || mWentToSleep || mLockScreenShown) {
11405                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11406                        + " mLockScreenShown " + mLockScreenShown);
11407            }
11408            if (mShuttingDown || mRunningVoice) {
11409                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11410            }
11411        }
11412        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11413                || mOrigWaitForDebugger) {
11414            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11415                    || dumpPackage.equals(mOrigDebugApp)) {
11416                if (needSep) {
11417                    pw.println();
11418                    needSep = false;
11419                }
11420                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11421                        + " mDebugTransient=" + mDebugTransient
11422                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11423            }
11424        }
11425        if (mOpenGlTraceApp != null) {
11426            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11427                if (needSep) {
11428                    pw.println();
11429                    needSep = false;
11430                }
11431                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11432            }
11433        }
11434        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11435                || mProfileFd != null) {
11436            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11437                if (needSep) {
11438                    pw.println();
11439                    needSep = false;
11440                }
11441                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11442                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11443                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11444                        + mAutoStopProfiler);
11445            }
11446        }
11447        if (dumpPackage == null) {
11448            if (mAlwaysFinishActivities || mController != null) {
11449                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11450                        + " mController=" + mController);
11451            }
11452            if (dumpAll) {
11453                pw.println("  Total persistent processes: " + numPers);
11454                pw.println("  mProcessesReady=" + mProcessesReady
11455                        + " mSystemReady=" + mSystemReady);
11456                pw.println("  mBooting=" + mBooting
11457                        + " mBooted=" + mBooted
11458                        + " mFactoryTest=" + mFactoryTest);
11459                pw.print("  mLastPowerCheckRealtime=");
11460                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11461                        pw.println("");
11462                pw.print("  mLastPowerCheckUptime=");
11463                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11464                        pw.println("");
11465                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11466                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11467                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11468                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11469                        + " (" + mLruProcesses.size() + " total)"
11470                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11471                        + " mNumServiceProcs=" + mNumServiceProcs
11472                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11473                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11474                        + " mLastMemoryLevel" + mLastMemoryLevel
11475                        + " mLastNumProcesses" + mLastNumProcesses);
11476                long now = SystemClock.uptimeMillis();
11477                pw.print("  mLastIdleTime=");
11478                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11479                        pw.print(" mLowRamSinceLastIdle=");
11480                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11481                        pw.println();
11482            }
11483        }
11484
11485        if (!printedAnything) {
11486            pw.println("  (nothing)");
11487        }
11488    }
11489
11490    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11491            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11492        if (mProcessesToGc.size() > 0) {
11493            boolean printed = false;
11494            long now = SystemClock.uptimeMillis();
11495            for (int i=0; i<mProcessesToGc.size(); i++) {
11496                ProcessRecord proc = mProcessesToGc.get(i);
11497                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11498                    continue;
11499                }
11500                if (!printed) {
11501                    if (needSep) pw.println();
11502                    needSep = true;
11503                    pw.println("  Processes that are waiting to GC:");
11504                    printed = true;
11505                }
11506                pw.print("    Process "); pw.println(proc);
11507                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11508                        pw.print(", last gced=");
11509                        pw.print(now-proc.lastRequestedGc);
11510                        pw.print(" ms ago, last lowMem=");
11511                        pw.print(now-proc.lastLowMemory);
11512                        pw.println(" ms ago");
11513
11514            }
11515        }
11516        return needSep;
11517    }
11518
11519    void printOomLevel(PrintWriter pw, String name, int adj) {
11520        pw.print("    ");
11521        if (adj >= 0) {
11522            pw.print(' ');
11523            if (adj < 10) pw.print(' ');
11524        } else {
11525            if (adj > -10) pw.print(' ');
11526        }
11527        pw.print(adj);
11528        pw.print(": ");
11529        pw.print(name);
11530        pw.print(" (");
11531        pw.print(mProcessList.getMemLevel(adj)/1024);
11532        pw.println(" kB)");
11533    }
11534
11535    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11536            int opti, boolean dumpAll) {
11537        boolean needSep = false;
11538
11539        if (mLruProcesses.size() > 0) {
11540            if (needSep) pw.println();
11541            needSep = true;
11542            pw.println("  OOM levels:");
11543            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11544            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11545            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11546            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11547            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11548            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11549            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11550            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11551            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11552            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11553            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11554            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11555            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11556
11557            if (needSep) pw.println();
11558            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11559                    pw.print(" total, non-act at ");
11560                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11561                    pw.print(", non-svc at ");
11562                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11563                    pw.println("):");
11564            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11565            needSep = true;
11566        }
11567
11568        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11569
11570        pw.println();
11571        pw.println("  mHomeProcess: " + mHomeProcess);
11572        pw.println("  mPreviousProcess: " + mPreviousProcess);
11573        if (mHeavyWeightProcess != null) {
11574            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11575        }
11576
11577        return true;
11578    }
11579
11580    /**
11581     * There are three ways to call this:
11582     *  - no provider specified: dump all the providers
11583     *  - a flattened component name that matched an existing provider was specified as the
11584     *    first arg: dump that one provider
11585     *  - the first arg isn't the flattened component name of an existing provider:
11586     *    dump all providers whose component contains the first arg as a substring
11587     */
11588    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11589            int opti, boolean dumpAll) {
11590        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11591    }
11592
11593    static class ItemMatcher {
11594        ArrayList<ComponentName> components;
11595        ArrayList<String> strings;
11596        ArrayList<Integer> objects;
11597        boolean all;
11598
11599        ItemMatcher() {
11600            all = true;
11601        }
11602
11603        void build(String name) {
11604            ComponentName componentName = ComponentName.unflattenFromString(name);
11605            if (componentName != null) {
11606                if (components == null) {
11607                    components = new ArrayList<ComponentName>();
11608                }
11609                components.add(componentName);
11610                all = false;
11611            } else {
11612                int objectId = 0;
11613                // Not a '/' separated full component name; maybe an object ID?
11614                try {
11615                    objectId = Integer.parseInt(name, 16);
11616                    if (objects == null) {
11617                        objects = new ArrayList<Integer>();
11618                    }
11619                    objects.add(objectId);
11620                    all = false;
11621                } catch (RuntimeException e) {
11622                    // Not an integer; just do string match.
11623                    if (strings == null) {
11624                        strings = new ArrayList<String>();
11625                    }
11626                    strings.add(name);
11627                    all = false;
11628                }
11629            }
11630        }
11631
11632        int build(String[] args, int opti) {
11633            for (; opti<args.length; opti++) {
11634                String name = args[opti];
11635                if ("--".equals(name)) {
11636                    return opti+1;
11637                }
11638                build(name);
11639            }
11640            return opti;
11641        }
11642
11643        boolean match(Object object, ComponentName comp) {
11644            if (all) {
11645                return true;
11646            }
11647            if (components != null) {
11648                for (int i=0; i<components.size(); i++) {
11649                    if (components.get(i).equals(comp)) {
11650                        return true;
11651                    }
11652                }
11653            }
11654            if (objects != null) {
11655                for (int i=0; i<objects.size(); i++) {
11656                    if (System.identityHashCode(object) == objects.get(i)) {
11657                        return true;
11658                    }
11659                }
11660            }
11661            if (strings != null) {
11662                String flat = comp.flattenToString();
11663                for (int i=0; i<strings.size(); i++) {
11664                    if (flat.contains(strings.get(i))) {
11665                        return true;
11666                    }
11667                }
11668            }
11669            return false;
11670        }
11671    }
11672
11673    /**
11674     * There are three things that cmd can be:
11675     *  - a flattened component name that matches an existing activity
11676     *  - the cmd arg isn't the flattened component name of an existing activity:
11677     *    dump all activity whose component contains the cmd as a substring
11678     *  - A hex number of the ActivityRecord object instance.
11679     */
11680    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11681            int opti, boolean dumpAll) {
11682        ArrayList<ActivityRecord> activities;
11683
11684        synchronized (this) {
11685            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11686        }
11687
11688        if (activities.size() <= 0) {
11689            return false;
11690        }
11691
11692        String[] newArgs = new String[args.length - opti];
11693        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11694
11695        TaskRecord lastTask = null;
11696        boolean needSep = false;
11697        for (int i=activities.size()-1; i>=0; i--) {
11698            ActivityRecord r = activities.get(i);
11699            if (needSep) {
11700                pw.println();
11701            }
11702            needSep = true;
11703            synchronized (this) {
11704                if (lastTask != r.task) {
11705                    lastTask = r.task;
11706                    pw.print("TASK "); pw.print(lastTask.affinity);
11707                            pw.print(" id="); pw.println(lastTask.taskId);
11708                    if (dumpAll) {
11709                        lastTask.dump(pw, "  ");
11710                    }
11711                }
11712            }
11713            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11714        }
11715        return true;
11716    }
11717
11718    /**
11719     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11720     * there is a thread associated with the activity.
11721     */
11722    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11723            final ActivityRecord r, String[] args, boolean dumpAll) {
11724        String innerPrefix = prefix + "  ";
11725        synchronized (this) {
11726            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11727                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11728                    pw.print(" pid=");
11729                    if (r.app != null) pw.println(r.app.pid);
11730                    else pw.println("(not running)");
11731            if (dumpAll) {
11732                r.dump(pw, innerPrefix);
11733            }
11734        }
11735        if (r.app != null && r.app.thread != null) {
11736            // flush anything that is already in the PrintWriter since the thread is going
11737            // to write to the file descriptor directly
11738            pw.flush();
11739            try {
11740                TransferPipe tp = new TransferPipe();
11741                try {
11742                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11743                            r.appToken, innerPrefix, args);
11744                    tp.go(fd);
11745                } finally {
11746                    tp.kill();
11747                }
11748            } catch (IOException e) {
11749                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11750            } catch (RemoteException e) {
11751                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11752            }
11753        }
11754    }
11755
11756    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11757            int opti, boolean dumpAll, String dumpPackage) {
11758        boolean needSep = false;
11759        boolean onlyHistory = false;
11760        boolean printedAnything = false;
11761
11762        if ("history".equals(dumpPackage)) {
11763            if (opti < args.length && "-s".equals(args[opti])) {
11764                dumpAll = false;
11765            }
11766            onlyHistory = true;
11767            dumpPackage = null;
11768        }
11769
11770        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11771        if (!onlyHistory && dumpAll) {
11772            if (mRegisteredReceivers.size() > 0) {
11773                boolean printed = false;
11774                Iterator it = mRegisteredReceivers.values().iterator();
11775                while (it.hasNext()) {
11776                    ReceiverList r = (ReceiverList)it.next();
11777                    if (dumpPackage != null && (r.app == null ||
11778                            !dumpPackage.equals(r.app.info.packageName))) {
11779                        continue;
11780                    }
11781                    if (!printed) {
11782                        pw.println("  Registered Receivers:");
11783                        needSep = true;
11784                        printed = true;
11785                        printedAnything = true;
11786                    }
11787                    pw.print("  * "); pw.println(r);
11788                    r.dump(pw, "    ");
11789                }
11790            }
11791
11792            if (mReceiverResolver.dump(pw, needSep ?
11793                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11794                    "    ", dumpPackage, false)) {
11795                needSep = true;
11796                printedAnything = true;
11797            }
11798        }
11799
11800        for (BroadcastQueue q : mBroadcastQueues) {
11801            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11802            printedAnything |= needSep;
11803        }
11804
11805        needSep = true;
11806
11807        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11808            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11809                if (needSep) {
11810                    pw.println();
11811                }
11812                needSep = true;
11813                printedAnything = true;
11814                pw.print("  Sticky broadcasts for user ");
11815                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11816                StringBuilder sb = new StringBuilder(128);
11817                for (Map.Entry<String, ArrayList<Intent>> ent
11818                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11819                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11820                    if (dumpAll) {
11821                        pw.println(":");
11822                        ArrayList<Intent> intents = ent.getValue();
11823                        final int N = intents.size();
11824                        for (int i=0; i<N; i++) {
11825                            sb.setLength(0);
11826                            sb.append("    Intent: ");
11827                            intents.get(i).toShortString(sb, false, true, false, false);
11828                            pw.println(sb.toString());
11829                            Bundle bundle = intents.get(i).getExtras();
11830                            if (bundle != null) {
11831                                pw.print("      ");
11832                                pw.println(bundle.toString());
11833                            }
11834                        }
11835                    } else {
11836                        pw.println("");
11837                    }
11838                }
11839            }
11840        }
11841
11842        if (!onlyHistory && dumpAll) {
11843            pw.println();
11844            for (BroadcastQueue queue : mBroadcastQueues) {
11845                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11846                        + queue.mBroadcastsScheduled);
11847            }
11848            pw.println("  mHandler:");
11849            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11850            needSep = true;
11851            printedAnything = true;
11852        }
11853
11854        if (!printedAnything) {
11855            pw.println("  (nothing)");
11856        }
11857    }
11858
11859    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11860            int opti, boolean dumpAll, String dumpPackage) {
11861        boolean needSep;
11862        boolean printedAnything = false;
11863
11864        ItemMatcher matcher = new ItemMatcher();
11865        matcher.build(args, opti);
11866
11867        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11868
11869        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11870        printedAnything |= needSep;
11871
11872        if (mLaunchingProviders.size() > 0) {
11873            boolean printed = false;
11874            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11875                ContentProviderRecord r = mLaunchingProviders.get(i);
11876                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11877                    continue;
11878                }
11879                if (!printed) {
11880                    if (needSep) pw.println();
11881                    needSep = true;
11882                    pw.println("  Launching content providers:");
11883                    printed = true;
11884                    printedAnything = true;
11885                }
11886                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11887                        pw.println(r);
11888            }
11889        }
11890
11891        if (mGrantedUriPermissions.size() > 0) {
11892            boolean printed = false;
11893            int dumpUid = -2;
11894            if (dumpPackage != null) {
11895                try {
11896                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11897                } catch (NameNotFoundException e) {
11898                    dumpUid = -1;
11899                }
11900            }
11901            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11902                int uid = mGrantedUriPermissions.keyAt(i);
11903                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11904                    continue;
11905                }
11906                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11907                if (!printed) {
11908                    if (needSep) pw.println();
11909                    needSep = true;
11910                    pw.println("  Granted Uri Permissions:");
11911                    printed = true;
11912                    printedAnything = true;
11913                }
11914                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11915                for (UriPermission perm : perms.values()) {
11916                    pw.print("    "); pw.println(perm);
11917                    if (dumpAll) {
11918                        perm.dump(pw, "      ");
11919                    }
11920                }
11921            }
11922        }
11923
11924        if (!printedAnything) {
11925            pw.println("  (nothing)");
11926        }
11927    }
11928
11929    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11930            int opti, boolean dumpAll, String dumpPackage) {
11931        boolean printed = false;
11932
11933        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11934
11935        if (mIntentSenderRecords.size() > 0) {
11936            Iterator<WeakReference<PendingIntentRecord>> it
11937                    = mIntentSenderRecords.values().iterator();
11938            while (it.hasNext()) {
11939                WeakReference<PendingIntentRecord> ref = it.next();
11940                PendingIntentRecord rec = ref != null ? ref.get(): null;
11941                if (dumpPackage != null && (rec == null
11942                        || !dumpPackage.equals(rec.key.packageName))) {
11943                    continue;
11944                }
11945                printed = true;
11946                if (rec != null) {
11947                    pw.print("  * "); pw.println(rec);
11948                    if (dumpAll) {
11949                        rec.dump(pw, "    ");
11950                    }
11951                } else {
11952                    pw.print("  * "); pw.println(ref);
11953                }
11954            }
11955        }
11956
11957        if (!printed) {
11958            pw.println("  (nothing)");
11959        }
11960    }
11961
11962    private static final int dumpProcessList(PrintWriter pw,
11963            ActivityManagerService service, List list,
11964            String prefix, String normalLabel, String persistentLabel,
11965            String dumpPackage) {
11966        int numPers = 0;
11967        final int N = list.size()-1;
11968        for (int i=N; i>=0; i--) {
11969            ProcessRecord r = (ProcessRecord)list.get(i);
11970            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11971                continue;
11972            }
11973            pw.println(String.format("%s%s #%2d: %s",
11974                    prefix, (r.persistent ? persistentLabel : normalLabel),
11975                    i, r.toString()));
11976            if (r.persistent) {
11977                numPers++;
11978            }
11979        }
11980        return numPers;
11981    }
11982
11983    private static final boolean dumpProcessOomList(PrintWriter pw,
11984            ActivityManagerService service, List<ProcessRecord> origList,
11985            String prefix, String normalLabel, String persistentLabel,
11986            boolean inclDetails, String dumpPackage) {
11987
11988        ArrayList<Pair<ProcessRecord, Integer>> list
11989                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11990        for (int i=0; i<origList.size(); i++) {
11991            ProcessRecord r = origList.get(i);
11992            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11993                continue;
11994            }
11995            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11996        }
11997
11998        if (list.size() <= 0) {
11999            return false;
12000        }
12001
12002        Comparator<Pair<ProcessRecord, Integer>> comparator
12003                = new Comparator<Pair<ProcessRecord, Integer>>() {
12004            @Override
12005            public int compare(Pair<ProcessRecord, Integer> object1,
12006                    Pair<ProcessRecord, Integer> object2) {
12007                if (object1.first.setAdj != object2.first.setAdj) {
12008                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12009                }
12010                if (object1.second.intValue() != object2.second.intValue()) {
12011                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12012                }
12013                return 0;
12014            }
12015        };
12016
12017        Collections.sort(list, comparator);
12018
12019        final long curRealtime = SystemClock.elapsedRealtime();
12020        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12021        final long curUptime = SystemClock.uptimeMillis();
12022        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12023
12024        for (int i=list.size()-1; i>=0; i--) {
12025            ProcessRecord r = list.get(i).first;
12026            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12027            char schedGroup;
12028            switch (r.setSchedGroup) {
12029                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12030                    schedGroup = 'B';
12031                    break;
12032                case Process.THREAD_GROUP_DEFAULT:
12033                    schedGroup = 'F';
12034                    break;
12035                default:
12036                    schedGroup = '?';
12037                    break;
12038            }
12039            char foreground;
12040            if (r.foregroundActivities) {
12041                foreground = 'A';
12042            } else if (r.foregroundServices) {
12043                foreground = 'S';
12044            } else {
12045                foreground = ' ';
12046            }
12047            String procState = ProcessList.makeProcStateString(r.curProcState);
12048            pw.print(prefix);
12049            pw.print(r.persistent ? persistentLabel : normalLabel);
12050            pw.print(" #");
12051            int num = (origList.size()-1)-list.get(i).second;
12052            if (num < 10) pw.print(' ');
12053            pw.print(num);
12054            pw.print(": ");
12055            pw.print(oomAdj);
12056            pw.print(' ');
12057            pw.print(schedGroup);
12058            pw.print('/');
12059            pw.print(foreground);
12060            pw.print('/');
12061            pw.print(procState);
12062            pw.print(" trm:");
12063            if (r.trimMemoryLevel < 10) pw.print(' ');
12064            pw.print(r.trimMemoryLevel);
12065            pw.print(' ');
12066            pw.print(r.toShortString());
12067            pw.print(" (");
12068            pw.print(r.adjType);
12069            pw.println(')');
12070            if (r.adjSource != null || r.adjTarget != null) {
12071                pw.print(prefix);
12072                pw.print("    ");
12073                if (r.adjTarget instanceof ComponentName) {
12074                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12075                } else if (r.adjTarget != null) {
12076                    pw.print(r.adjTarget.toString());
12077                } else {
12078                    pw.print("{null}");
12079                }
12080                pw.print("<=");
12081                if (r.adjSource instanceof ProcessRecord) {
12082                    pw.print("Proc{");
12083                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12084                    pw.println("}");
12085                } else if (r.adjSource != null) {
12086                    pw.println(r.adjSource.toString());
12087                } else {
12088                    pw.println("{null}");
12089                }
12090            }
12091            if (inclDetails) {
12092                pw.print(prefix);
12093                pw.print("    ");
12094                pw.print("oom: max="); pw.print(r.maxAdj);
12095                pw.print(" curRaw="); pw.print(r.curRawAdj);
12096                pw.print(" setRaw="); pw.print(r.setRawAdj);
12097                pw.print(" cur="); pw.print(r.curAdj);
12098                pw.print(" set="); pw.println(r.setAdj);
12099                pw.print(prefix);
12100                pw.print("    ");
12101                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12102                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12103                pw.print(" lastPss="); pw.print(r.lastPss);
12104                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12105                pw.print(prefix);
12106                pw.print("    ");
12107                pw.print("keeping="); pw.print(r.keeping);
12108                pw.print(" cached="); pw.print(r.cached);
12109                pw.print(" empty="); pw.print(r.empty);
12110                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12111
12112                if (!r.keeping) {
12113                    if (r.lastWakeTime != 0) {
12114                        long wtime;
12115                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12116                        synchronized (stats) {
12117                            wtime = stats.getProcessWakeTime(r.info.uid,
12118                                    r.pid, curRealtime);
12119                        }
12120                        long timeUsed = wtime - r.lastWakeTime;
12121                        pw.print(prefix);
12122                        pw.print("    ");
12123                        pw.print("keep awake over ");
12124                        TimeUtils.formatDuration(realtimeSince, pw);
12125                        pw.print(" used ");
12126                        TimeUtils.formatDuration(timeUsed, pw);
12127                        pw.print(" (");
12128                        pw.print((timeUsed*100)/realtimeSince);
12129                        pw.println("%)");
12130                    }
12131                    if (r.lastCpuTime != 0) {
12132                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12133                        pw.print(prefix);
12134                        pw.print("    ");
12135                        pw.print("run cpu over ");
12136                        TimeUtils.formatDuration(uptimeSince, pw);
12137                        pw.print(" used ");
12138                        TimeUtils.formatDuration(timeUsed, pw);
12139                        pw.print(" (");
12140                        pw.print((timeUsed*100)/uptimeSince);
12141                        pw.println("%)");
12142                    }
12143                }
12144            }
12145        }
12146        return true;
12147    }
12148
12149    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12150        ArrayList<ProcessRecord> procs;
12151        synchronized (this) {
12152            if (args != null && args.length > start
12153                    && args[start].charAt(0) != '-') {
12154                procs = new ArrayList<ProcessRecord>();
12155                int pid = -1;
12156                try {
12157                    pid = Integer.parseInt(args[start]);
12158                } catch (NumberFormatException e) {
12159                }
12160                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12161                    ProcessRecord proc = mLruProcesses.get(i);
12162                    if (proc.pid == pid) {
12163                        procs.add(proc);
12164                    } else if (proc.processName.equals(args[start])) {
12165                        procs.add(proc);
12166                    }
12167                }
12168                if (procs.size() <= 0) {
12169                    return null;
12170                }
12171            } else {
12172                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12173            }
12174        }
12175        return procs;
12176    }
12177
12178    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12179            PrintWriter pw, String[] args) {
12180        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12181        if (procs == null) {
12182            pw.println("No process found for: " + args[0]);
12183            return;
12184        }
12185
12186        long uptime = SystemClock.uptimeMillis();
12187        long realtime = SystemClock.elapsedRealtime();
12188        pw.println("Applications Graphics Acceleration Info:");
12189        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12190
12191        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12192            ProcessRecord r = procs.get(i);
12193            if (r.thread != null) {
12194                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12195                pw.flush();
12196                try {
12197                    TransferPipe tp = new TransferPipe();
12198                    try {
12199                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12200                        tp.go(fd);
12201                    } finally {
12202                        tp.kill();
12203                    }
12204                } catch (IOException e) {
12205                    pw.println("Failure while dumping the app: " + r);
12206                    pw.flush();
12207                } catch (RemoteException e) {
12208                    pw.println("Got a RemoteException while dumping the app " + r);
12209                    pw.flush();
12210                }
12211            }
12212        }
12213    }
12214
12215    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12216        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12217        if (procs == null) {
12218            pw.println("No process found for: " + args[0]);
12219            return;
12220        }
12221
12222        pw.println("Applications Database Info:");
12223
12224        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12225            ProcessRecord r = procs.get(i);
12226            if (r.thread != null) {
12227                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12228                pw.flush();
12229                try {
12230                    TransferPipe tp = new TransferPipe();
12231                    try {
12232                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12233                        tp.go(fd);
12234                    } finally {
12235                        tp.kill();
12236                    }
12237                } catch (IOException e) {
12238                    pw.println("Failure while dumping the app: " + r);
12239                    pw.flush();
12240                } catch (RemoteException e) {
12241                    pw.println("Got a RemoteException while dumping the app " + r);
12242                    pw.flush();
12243                }
12244            }
12245        }
12246    }
12247
12248    final static class MemItem {
12249        final boolean isProc;
12250        final String label;
12251        final String shortLabel;
12252        final long pss;
12253        final int id;
12254        final boolean hasActivities;
12255        ArrayList<MemItem> subitems;
12256
12257        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12258                boolean _hasActivities) {
12259            isProc = true;
12260            label = _label;
12261            shortLabel = _shortLabel;
12262            pss = _pss;
12263            id = _id;
12264            hasActivities = _hasActivities;
12265        }
12266
12267        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12268            isProc = false;
12269            label = _label;
12270            shortLabel = _shortLabel;
12271            pss = _pss;
12272            id = _id;
12273            hasActivities = false;
12274        }
12275    }
12276
12277    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12278            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12279        if (sort && !isCompact) {
12280            Collections.sort(items, new Comparator<MemItem>() {
12281                @Override
12282                public int compare(MemItem lhs, MemItem rhs) {
12283                    if (lhs.pss < rhs.pss) {
12284                        return 1;
12285                    } else if (lhs.pss > rhs.pss) {
12286                        return -1;
12287                    }
12288                    return 0;
12289                }
12290            });
12291        }
12292
12293        for (int i=0; i<items.size(); i++) {
12294            MemItem mi = items.get(i);
12295            if (!isCompact) {
12296                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12297            } else if (mi.isProc) {
12298                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12299                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12300                pw.println(mi.hasActivities ? ",a" : ",e");
12301            } else {
12302                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12303                pw.println(mi.pss);
12304            }
12305            if (mi.subitems != null) {
12306                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12307                        true, isCompact);
12308            }
12309        }
12310    }
12311
12312    // These are in KB.
12313    static final long[] DUMP_MEM_BUCKETS = new long[] {
12314        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12315        120*1024, 160*1024, 200*1024,
12316        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12317        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12318    };
12319
12320    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12321            boolean stackLike) {
12322        int start = label.lastIndexOf('.');
12323        if (start >= 0) start++;
12324        else start = 0;
12325        int end = label.length();
12326        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12327            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12328                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12329                out.append(bucket);
12330                out.append(stackLike ? "MB." : "MB ");
12331                out.append(label, start, end);
12332                return;
12333            }
12334        }
12335        out.append(memKB/1024);
12336        out.append(stackLike ? "MB." : "MB ");
12337        out.append(label, start, end);
12338    }
12339
12340    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12341            ProcessList.NATIVE_ADJ,
12342            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12343            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12344            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12345            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12346            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12347    };
12348    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12349            "Native",
12350            "System", "Persistent", "Foreground",
12351            "Visible", "Perceptible",
12352            "Heavy Weight", "Backup",
12353            "A Services", "Home",
12354            "Previous", "B Services", "Cached"
12355    };
12356    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12357            "native",
12358            "sys", "pers", "fore",
12359            "vis", "percept",
12360            "heavy", "backup",
12361            "servicea", "home",
12362            "prev", "serviceb", "cached"
12363    };
12364
12365    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12366            long realtime, boolean isCheckinRequest, boolean isCompact) {
12367        if (isCheckinRequest || isCompact) {
12368            // short checkin version
12369            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12370        } else {
12371            pw.println("Applications Memory Usage (kB):");
12372            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12373        }
12374    }
12375
12376    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12377            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12378        boolean dumpDetails = false;
12379        boolean dumpFullDetails = false;
12380        boolean dumpDalvik = false;
12381        boolean oomOnly = false;
12382        boolean isCompact = false;
12383        boolean localOnly = false;
12384
12385        int opti = 0;
12386        while (opti < args.length) {
12387            String opt = args[opti];
12388            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12389                break;
12390            }
12391            opti++;
12392            if ("-a".equals(opt)) {
12393                dumpDetails = true;
12394                dumpFullDetails = true;
12395                dumpDalvik = true;
12396            } else if ("-d".equals(opt)) {
12397                dumpDalvik = true;
12398            } else if ("-c".equals(opt)) {
12399                isCompact = true;
12400            } else if ("--oom".equals(opt)) {
12401                oomOnly = true;
12402            } else if ("--local".equals(opt)) {
12403                localOnly = true;
12404            } else if ("-h".equals(opt)) {
12405                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12406                pw.println("  -a: include all available information for each process.");
12407                pw.println("  -d: include dalvik details when dumping process details.");
12408                pw.println("  -c: dump in a compact machine-parseable representation.");
12409                pw.println("  --oom: only show processes organized by oom adj.");
12410                pw.println("  --local: only collect details locally, don't call process.");
12411                pw.println("If [process] is specified it can be the name or ");
12412                pw.println("pid of a specific process to dump.");
12413                return;
12414            } else {
12415                pw.println("Unknown argument: " + opt + "; use -h for help");
12416            }
12417        }
12418
12419        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12420        long uptime = SystemClock.uptimeMillis();
12421        long realtime = SystemClock.elapsedRealtime();
12422        final long[] tmpLong = new long[1];
12423
12424        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12425        if (procs == null) {
12426            // No Java processes.  Maybe they want to print a native process.
12427            if (args != null && args.length > opti
12428                    && args[opti].charAt(0) != '-') {
12429                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12430                        = new ArrayList<ProcessCpuTracker.Stats>();
12431                updateCpuStatsNow();
12432                int findPid = -1;
12433                try {
12434                    findPid = Integer.parseInt(args[opti]);
12435                } catch (NumberFormatException e) {
12436                }
12437                synchronized (mProcessCpuThread) {
12438                    final int N = mProcessCpuTracker.countStats();
12439                    for (int i=0; i<N; i++) {
12440                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12441                        if (st.pid == findPid || (st.baseName != null
12442                                && st.baseName.equals(args[opti]))) {
12443                            nativeProcs.add(st);
12444                        }
12445                    }
12446                }
12447                if (nativeProcs.size() > 0) {
12448                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12449                            isCompact);
12450                    Debug.MemoryInfo mi = null;
12451                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12452                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12453                        final int pid = r.pid;
12454                        if (!isCheckinRequest && dumpDetails) {
12455                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12456                        }
12457                        if (mi == null) {
12458                            mi = new Debug.MemoryInfo();
12459                        }
12460                        if (dumpDetails || (!brief && !oomOnly)) {
12461                            Debug.getMemoryInfo(pid, mi);
12462                        } else {
12463                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12464                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12465                        }
12466                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12467                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12468                        if (isCheckinRequest) {
12469                            pw.println();
12470                        }
12471                    }
12472                    return;
12473                }
12474            }
12475            pw.println("No process found for: " + args[opti]);
12476            return;
12477        }
12478
12479        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12480            dumpDetails = true;
12481        }
12482
12483        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12484
12485        String[] innerArgs = new String[args.length-opti];
12486        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12487
12488        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12489        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12490        long nativePss=0, dalvikPss=0, otherPss=0;
12491        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12492
12493        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12494        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12495                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12496
12497        long totalPss = 0;
12498        long cachedPss = 0;
12499
12500        Debug.MemoryInfo mi = null;
12501        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12502            final ProcessRecord r = procs.get(i);
12503            final IApplicationThread thread;
12504            final int pid;
12505            final int oomAdj;
12506            final boolean hasActivities;
12507            synchronized (this) {
12508                thread = r.thread;
12509                pid = r.pid;
12510                oomAdj = r.getSetAdjWithServices();
12511                hasActivities = r.activities.size() > 0;
12512            }
12513            if (thread != null) {
12514                if (!isCheckinRequest && dumpDetails) {
12515                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12516                }
12517                if (mi == null) {
12518                    mi = new Debug.MemoryInfo();
12519                }
12520                if (dumpDetails || (!brief && !oomOnly)) {
12521                    Debug.getMemoryInfo(pid, mi);
12522                } else {
12523                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12524                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12525                }
12526                if (dumpDetails) {
12527                    if (localOnly) {
12528                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12529                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12530                        if (isCheckinRequest) {
12531                            pw.println();
12532                        }
12533                    } else {
12534                        try {
12535                            pw.flush();
12536                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12537                                    dumpDalvik, innerArgs);
12538                        } catch (RemoteException e) {
12539                            if (!isCheckinRequest) {
12540                                pw.println("Got RemoteException!");
12541                                pw.flush();
12542                            }
12543                        }
12544                    }
12545                }
12546
12547                final long myTotalPss = mi.getTotalPss();
12548                final long myTotalUss = mi.getTotalUss();
12549
12550                synchronized (this) {
12551                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12552                        // Record this for posterity if the process has been stable.
12553                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12554                    }
12555                }
12556
12557                if (!isCheckinRequest && mi != null) {
12558                    totalPss += myTotalPss;
12559                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12560                            (hasActivities ? " / activities)" : ")"),
12561                            r.processName, myTotalPss, pid, hasActivities);
12562                    procMems.add(pssItem);
12563                    procMemsMap.put(pid, pssItem);
12564
12565                    nativePss += mi.nativePss;
12566                    dalvikPss += mi.dalvikPss;
12567                    otherPss += mi.otherPss;
12568                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12569                        long mem = mi.getOtherPss(j);
12570                        miscPss[j] += mem;
12571                        otherPss -= mem;
12572                    }
12573
12574                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12575                        cachedPss += myTotalPss;
12576                    }
12577
12578                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12579                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12580                                || oomIndex == (oomPss.length-1)) {
12581                            oomPss[oomIndex] += myTotalPss;
12582                            if (oomProcs[oomIndex] == null) {
12583                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12584                            }
12585                            oomProcs[oomIndex].add(pssItem);
12586                            break;
12587                        }
12588                    }
12589                }
12590            }
12591        }
12592
12593        if (!isCheckinRequest && procs.size() > 1) {
12594            // If we are showing aggregations, also look for native processes to
12595            // include so that our aggregations are more accurate.
12596            updateCpuStatsNow();
12597            synchronized (mProcessCpuThread) {
12598                final int N = mProcessCpuTracker.countStats();
12599                for (int i=0; i<N; i++) {
12600                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12601                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12602                        if (mi == null) {
12603                            mi = new Debug.MemoryInfo();
12604                        }
12605                        if (!brief && !oomOnly) {
12606                            Debug.getMemoryInfo(st.pid, mi);
12607                        } else {
12608                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12609                            mi.nativePrivateDirty = (int)tmpLong[0];
12610                        }
12611
12612                        final long myTotalPss = mi.getTotalPss();
12613                        totalPss += myTotalPss;
12614
12615                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12616                                st.name, myTotalPss, st.pid, false);
12617                        procMems.add(pssItem);
12618
12619                        nativePss += mi.nativePss;
12620                        dalvikPss += mi.dalvikPss;
12621                        otherPss += mi.otherPss;
12622                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12623                            long mem = mi.getOtherPss(j);
12624                            miscPss[j] += mem;
12625                            otherPss -= mem;
12626                        }
12627                        oomPss[0] += myTotalPss;
12628                        if (oomProcs[0] == null) {
12629                            oomProcs[0] = new ArrayList<MemItem>();
12630                        }
12631                        oomProcs[0].add(pssItem);
12632                    }
12633                }
12634            }
12635
12636            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12637
12638            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12639            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12640            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12641            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12642                String label = Debug.MemoryInfo.getOtherLabel(j);
12643                catMems.add(new MemItem(label, label, miscPss[j], j));
12644            }
12645
12646            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12647            for (int j=0; j<oomPss.length; j++) {
12648                if (oomPss[j] != 0) {
12649                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12650                            : DUMP_MEM_OOM_LABEL[j];
12651                    MemItem item = new MemItem(label, label, oomPss[j],
12652                            DUMP_MEM_OOM_ADJ[j]);
12653                    item.subitems = oomProcs[j];
12654                    oomMems.add(item);
12655                }
12656            }
12657
12658            if (!brief && !oomOnly && !isCompact) {
12659                pw.println();
12660                pw.println("Total PSS by process:");
12661                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12662                pw.println();
12663            }
12664            if (!isCompact) {
12665                pw.println("Total PSS by OOM adjustment:");
12666            }
12667            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12668            if (!brief && !oomOnly) {
12669                PrintWriter out = categoryPw != null ? categoryPw : pw;
12670                if (!isCompact) {
12671                    out.println();
12672                    out.println("Total PSS by category:");
12673                }
12674                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12675            }
12676            if (!isCompact) {
12677                pw.println();
12678            }
12679            MemInfoReader memInfo = new MemInfoReader();
12680            memInfo.readMemInfo();
12681            if (!brief) {
12682                if (!isCompact) {
12683                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12684                    pw.print(" kB (status ");
12685                    switch (mLastMemoryLevel) {
12686                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12687                            pw.println("normal)");
12688                            break;
12689                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12690                            pw.println("moderate)");
12691                            break;
12692                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12693                            pw.println("low)");
12694                            break;
12695                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12696                            pw.println("critical)");
12697                            break;
12698                        default:
12699                            pw.print(mLastMemoryLevel);
12700                            pw.println(")");
12701                            break;
12702                    }
12703                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12704                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12705                            pw.print(cachedPss); pw.print(" cached pss + ");
12706                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12707                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12708                } else {
12709                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12710                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12711                            + memInfo.getFreeSizeKb()); pw.print(",");
12712                    pw.println(totalPss - cachedPss);
12713                }
12714            }
12715            if (!isCompact) {
12716                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12717                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12718                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12719                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12720                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12721                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12722                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12723                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12724                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12725                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12726                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12727            }
12728            if (!brief) {
12729                if (memInfo.getZramTotalSizeKb() != 0) {
12730                    if (!isCompact) {
12731                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12732                                pw.print(" kB physical used for ");
12733                                pw.print(memInfo.getSwapTotalSizeKb()
12734                                        - memInfo.getSwapFreeSizeKb());
12735                                pw.print(" kB in swap (");
12736                                pw.print(memInfo.getSwapTotalSizeKb());
12737                                pw.println(" kB total swap)");
12738                    } else {
12739                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12740                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12741                                pw.println(memInfo.getSwapFreeSizeKb());
12742                    }
12743                }
12744                final int[] SINGLE_LONG_FORMAT = new int[] {
12745                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12746                };
12747                long[] longOut = new long[1];
12748                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12749                        SINGLE_LONG_FORMAT, null, longOut, null);
12750                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12751                longOut[0] = 0;
12752                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12753                        SINGLE_LONG_FORMAT, null, longOut, null);
12754                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12755                longOut[0] = 0;
12756                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12757                        SINGLE_LONG_FORMAT, null, longOut, null);
12758                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12759                longOut[0] = 0;
12760                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12761                        SINGLE_LONG_FORMAT, null, longOut, null);
12762                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12763                if (!isCompact) {
12764                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12765                        pw.print("      KSM: "); pw.print(sharing);
12766                                pw.print(" kB saved from shared ");
12767                                pw.print(shared); pw.println(" kB");
12768                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12769                                pw.print(voltile); pw.println(" kB volatile");
12770                    }
12771                    pw.print("   Tuning: ");
12772                    pw.print(ActivityManager.staticGetMemoryClass());
12773                    pw.print(" (large ");
12774                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12775                    pw.print("), oom ");
12776                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12777                    pw.print(" kB");
12778                    pw.print(", restore limit ");
12779                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12780                    pw.print(" kB");
12781                    if (ActivityManager.isLowRamDeviceStatic()) {
12782                        pw.print(" (low-ram)");
12783                    }
12784                    if (ActivityManager.isHighEndGfx()) {
12785                        pw.print(" (high-end-gfx)");
12786                    }
12787                    pw.println();
12788                } else {
12789                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12790                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12791                    pw.println(voltile);
12792                    pw.print("tuning,");
12793                    pw.print(ActivityManager.staticGetMemoryClass());
12794                    pw.print(',');
12795                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12796                    pw.print(',');
12797                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12798                    if (ActivityManager.isLowRamDeviceStatic()) {
12799                        pw.print(",low-ram");
12800                    }
12801                    if (ActivityManager.isHighEndGfx()) {
12802                        pw.print(",high-end-gfx");
12803                    }
12804                    pw.println();
12805                }
12806            }
12807        }
12808    }
12809
12810    /**
12811     * Searches array of arguments for the specified string
12812     * @param args array of argument strings
12813     * @param value value to search for
12814     * @return true if the value is contained in the array
12815     */
12816    private static boolean scanArgs(String[] args, String value) {
12817        if (args != null) {
12818            for (String arg : args) {
12819                if (value.equals(arg)) {
12820                    return true;
12821                }
12822            }
12823        }
12824        return false;
12825    }
12826
12827    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12828            ContentProviderRecord cpr, boolean always) {
12829        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12830
12831        if (!inLaunching || always) {
12832            synchronized (cpr) {
12833                cpr.launchingApp = null;
12834                cpr.notifyAll();
12835            }
12836            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12837            String names[] = cpr.info.authority.split(";");
12838            for (int j = 0; j < names.length; j++) {
12839                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12840            }
12841        }
12842
12843        for (int i=0; i<cpr.connections.size(); i++) {
12844            ContentProviderConnection conn = cpr.connections.get(i);
12845            if (conn.waiting) {
12846                // If this connection is waiting for the provider, then we don't
12847                // need to mess with its process unless we are always removing
12848                // or for some reason the provider is not currently launching.
12849                if (inLaunching && !always) {
12850                    continue;
12851                }
12852            }
12853            ProcessRecord capp = conn.client;
12854            conn.dead = true;
12855            if (conn.stableCount > 0) {
12856                if (!capp.persistent && capp.thread != null
12857                        && capp.pid != 0
12858                        && capp.pid != MY_PID) {
12859                    killUnneededProcessLocked(capp, "depends on provider "
12860                            + cpr.name.flattenToShortString()
12861                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12862                }
12863            } else if (capp.thread != null && conn.provider.provider != null) {
12864                try {
12865                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12866                } catch (RemoteException e) {
12867                }
12868                // In the protocol here, we don't expect the client to correctly
12869                // clean up this connection, we'll just remove it.
12870                cpr.connections.remove(i);
12871                conn.client.conProviders.remove(conn);
12872            }
12873        }
12874
12875        if (inLaunching && always) {
12876            mLaunchingProviders.remove(cpr);
12877        }
12878        return inLaunching;
12879    }
12880
12881    /**
12882     * Main code for cleaning up a process when it has gone away.  This is
12883     * called both as a result of the process dying, or directly when stopping
12884     * a process when running in single process mode.
12885     */
12886    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12887            boolean restarting, boolean allowRestart, int index) {
12888        if (index >= 0) {
12889            removeLruProcessLocked(app);
12890            ProcessList.remove(app.pid);
12891        }
12892
12893        mProcessesToGc.remove(app);
12894        mPendingPssProcesses.remove(app);
12895
12896        // Dismiss any open dialogs.
12897        if (app.crashDialog != null && !app.forceCrashReport) {
12898            app.crashDialog.dismiss();
12899            app.crashDialog = null;
12900        }
12901        if (app.anrDialog != null) {
12902            app.anrDialog.dismiss();
12903            app.anrDialog = null;
12904        }
12905        if (app.waitDialog != null) {
12906            app.waitDialog.dismiss();
12907            app.waitDialog = null;
12908        }
12909
12910        app.crashing = false;
12911        app.notResponding = false;
12912
12913        app.resetPackageList(mProcessStats);
12914        app.unlinkDeathRecipient();
12915        app.makeInactive(mProcessStats);
12916        app.forcingToForeground = null;
12917        updateProcessForegroundLocked(app, false, false);
12918        app.foregroundActivities = false;
12919        app.hasShownUi = false;
12920        app.treatLikeActivity = false;
12921        app.hasAboveClient = false;
12922        app.hasClientActivities = false;
12923
12924        mServices.killServicesLocked(app, allowRestart);
12925
12926        boolean restart = false;
12927
12928        // Remove published content providers.
12929        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12930            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12931            final boolean always = app.bad || !allowRestart;
12932            if (removeDyingProviderLocked(app, cpr, always) || always) {
12933                // We left the provider in the launching list, need to
12934                // restart it.
12935                restart = true;
12936            }
12937
12938            cpr.provider = null;
12939            cpr.proc = null;
12940        }
12941        app.pubProviders.clear();
12942
12943        // Take care of any launching providers waiting for this process.
12944        if (checkAppInLaunchingProvidersLocked(app, false)) {
12945            restart = true;
12946        }
12947
12948        // Unregister from connected content providers.
12949        if (!app.conProviders.isEmpty()) {
12950            for (int i=0; i<app.conProviders.size(); i++) {
12951                ContentProviderConnection conn = app.conProviders.get(i);
12952                conn.provider.connections.remove(conn);
12953            }
12954            app.conProviders.clear();
12955        }
12956
12957        // At this point there may be remaining entries in mLaunchingProviders
12958        // where we were the only one waiting, so they are no longer of use.
12959        // Look for these and clean up if found.
12960        // XXX Commented out for now.  Trying to figure out a way to reproduce
12961        // the actual situation to identify what is actually going on.
12962        if (false) {
12963            for (int i=0; i<mLaunchingProviders.size(); i++) {
12964                ContentProviderRecord cpr = (ContentProviderRecord)
12965                        mLaunchingProviders.get(i);
12966                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12967                    synchronized (cpr) {
12968                        cpr.launchingApp = null;
12969                        cpr.notifyAll();
12970                    }
12971                }
12972            }
12973        }
12974
12975        skipCurrentReceiverLocked(app);
12976
12977        // Unregister any receivers.
12978        for (int i=app.receivers.size()-1; i>=0; i--) {
12979            removeReceiverLocked(app.receivers.valueAt(i));
12980        }
12981        app.receivers.clear();
12982
12983        // If the app is undergoing backup, tell the backup manager about it
12984        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12985            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12986                    + mBackupTarget.appInfo + " died during backup");
12987            try {
12988                IBackupManager bm = IBackupManager.Stub.asInterface(
12989                        ServiceManager.getService(Context.BACKUP_SERVICE));
12990                bm.agentDisconnected(app.info.packageName);
12991            } catch (RemoteException e) {
12992                // can't happen; backup manager is local
12993            }
12994        }
12995
12996        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12997            ProcessChangeItem item = mPendingProcessChanges.get(i);
12998            if (item.pid == app.pid) {
12999                mPendingProcessChanges.remove(i);
13000                mAvailProcessChanges.add(item);
13001            }
13002        }
13003        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13004
13005        // If the caller is restarting this app, then leave it in its
13006        // current lists and let the caller take care of it.
13007        if (restarting) {
13008            return;
13009        }
13010
13011        if (!app.persistent || app.isolated) {
13012            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13013                    "Removing non-persistent process during cleanup: " + app);
13014            mProcessNames.remove(app.processName, app.uid);
13015            mIsolatedProcesses.remove(app.uid);
13016            if (mHeavyWeightProcess == app) {
13017                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13018                        mHeavyWeightProcess.userId, 0));
13019                mHeavyWeightProcess = null;
13020            }
13021        } else if (!app.removed) {
13022            // This app is persistent, so we need to keep its record around.
13023            // If it is not already on the pending app list, add it there
13024            // and start a new process for it.
13025            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13026                mPersistentStartingProcesses.add(app);
13027                restart = true;
13028            }
13029        }
13030        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13031                "Clean-up removing on hold: " + app);
13032        mProcessesOnHold.remove(app);
13033
13034        if (app == mHomeProcess) {
13035            mHomeProcess = null;
13036        }
13037        if (app == mPreviousProcess) {
13038            mPreviousProcess = null;
13039        }
13040
13041        if (restart && !app.isolated) {
13042            // We have components that still need to be running in the
13043            // process, so re-launch it.
13044            mProcessNames.put(app.processName, app.uid, app);
13045            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13046        } else if (app.pid > 0 && app.pid != MY_PID) {
13047            // Goodbye!
13048            boolean removed;
13049            synchronized (mPidsSelfLocked) {
13050                mPidsSelfLocked.remove(app.pid);
13051                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13052            }
13053            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13054                    app.processName, app.info.uid);
13055            if (app.isolated) {
13056                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13057            }
13058            app.setPid(0);
13059        }
13060    }
13061
13062    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13063        // Look through the content providers we are waiting to have launched,
13064        // and if any run in this process then either schedule a restart of
13065        // the process or kill the client waiting for it if this process has
13066        // gone bad.
13067        int NL = mLaunchingProviders.size();
13068        boolean restart = false;
13069        for (int i=0; i<NL; i++) {
13070            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13071            if (cpr.launchingApp == app) {
13072                if (!alwaysBad && !app.bad) {
13073                    restart = true;
13074                } else {
13075                    removeDyingProviderLocked(app, cpr, true);
13076                    // cpr should have been removed from mLaunchingProviders
13077                    NL = mLaunchingProviders.size();
13078                    i--;
13079                }
13080            }
13081        }
13082        return restart;
13083    }
13084
13085    // =========================================================
13086    // SERVICES
13087    // =========================================================
13088
13089    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13090            int flags) {
13091        enforceNotIsolatedCaller("getServices");
13092        synchronized (this) {
13093            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13094        }
13095    }
13096
13097    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13098        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13099        synchronized (this) {
13100            return mServices.getRunningServiceControlPanelLocked(name);
13101        }
13102    }
13103
13104    public ComponentName startService(IApplicationThread caller, Intent service,
13105            String resolvedType, int userId) {
13106        enforceNotIsolatedCaller("startService");
13107        // Refuse possible leaked file descriptors
13108        if (service != null && service.hasFileDescriptors() == true) {
13109            throw new IllegalArgumentException("File descriptors passed in Intent");
13110        }
13111
13112        if (DEBUG_SERVICE)
13113            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13114        synchronized(this) {
13115            final int callingPid = Binder.getCallingPid();
13116            final int callingUid = Binder.getCallingUid();
13117            final long origId = Binder.clearCallingIdentity();
13118            ComponentName res = mServices.startServiceLocked(caller, service,
13119                    resolvedType, callingPid, callingUid, userId);
13120            Binder.restoreCallingIdentity(origId);
13121            return res;
13122        }
13123    }
13124
13125    ComponentName startServiceInPackage(int uid,
13126            Intent service, String resolvedType, int userId) {
13127        synchronized(this) {
13128            if (DEBUG_SERVICE)
13129                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13130            final long origId = Binder.clearCallingIdentity();
13131            ComponentName res = mServices.startServiceLocked(null, service,
13132                    resolvedType, -1, uid, userId);
13133            Binder.restoreCallingIdentity(origId);
13134            return res;
13135        }
13136    }
13137
13138    public int stopService(IApplicationThread caller, Intent service,
13139            String resolvedType, int userId) {
13140        enforceNotIsolatedCaller("stopService");
13141        // Refuse possible leaked file descriptors
13142        if (service != null && service.hasFileDescriptors() == true) {
13143            throw new IllegalArgumentException("File descriptors passed in Intent");
13144        }
13145
13146        synchronized(this) {
13147            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13148        }
13149    }
13150
13151    public IBinder peekService(Intent service, String resolvedType) {
13152        enforceNotIsolatedCaller("peekService");
13153        // Refuse possible leaked file descriptors
13154        if (service != null && service.hasFileDescriptors() == true) {
13155            throw new IllegalArgumentException("File descriptors passed in Intent");
13156        }
13157        synchronized(this) {
13158            return mServices.peekServiceLocked(service, resolvedType);
13159        }
13160    }
13161
13162    public boolean stopServiceToken(ComponentName className, IBinder token,
13163            int startId) {
13164        synchronized(this) {
13165            return mServices.stopServiceTokenLocked(className, token, startId);
13166        }
13167    }
13168
13169    public void setServiceForeground(ComponentName className, IBinder token,
13170            int id, Notification notification, boolean removeNotification) {
13171        synchronized(this) {
13172            mServices.setServiceForegroundLocked(className, token, id, notification,
13173                    removeNotification);
13174        }
13175    }
13176
13177    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13178            boolean requireFull, String name, String callerPackage) {
13179        final int callingUserId = UserHandle.getUserId(callingUid);
13180        if (callingUserId != userId) {
13181            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13182                if ((requireFull || checkComponentPermission(
13183                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13184                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13185                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13186                                callingPid, callingUid, -1, true)
13187                                != PackageManager.PERMISSION_GRANTED) {
13188                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13189                        // In this case, they would like to just execute as their
13190                        // owner user instead of failing.
13191                        userId = callingUserId;
13192                    } else {
13193                        StringBuilder builder = new StringBuilder(128);
13194                        builder.append("Permission Denial: ");
13195                        builder.append(name);
13196                        if (callerPackage != null) {
13197                            builder.append(" from ");
13198                            builder.append(callerPackage);
13199                        }
13200                        builder.append(" asks to run as user ");
13201                        builder.append(userId);
13202                        builder.append(" but is calling from user ");
13203                        builder.append(UserHandle.getUserId(callingUid));
13204                        builder.append("; this requires ");
13205                        builder.append(INTERACT_ACROSS_USERS_FULL);
13206                        if (!requireFull) {
13207                            builder.append(" or ");
13208                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13209                        }
13210                        String msg = builder.toString();
13211                        Slog.w(TAG, msg);
13212                        throw new SecurityException(msg);
13213                    }
13214                }
13215            }
13216            if (userId == UserHandle.USER_CURRENT
13217                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13218                // Note that we may be accessing this outside of a lock...
13219                // shouldn't be a big deal, if this is being called outside
13220                // of a locked context there is intrinsically a race with
13221                // the value the caller will receive and someone else changing it.
13222                userId = mCurrentUserId;
13223            }
13224            if (!allowAll && userId < 0) {
13225                throw new IllegalArgumentException(
13226                        "Call does not support special user #" + userId);
13227            }
13228        }
13229        return userId;
13230    }
13231
13232    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13233            String className, int flags) {
13234        boolean result = false;
13235        // For apps that don't have pre-defined UIDs, check for permission
13236        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13237            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13238                if (ActivityManager.checkUidPermission(
13239                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13240                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13241                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13242                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13243                            + " requests FLAG_SINGLE_USER, but app does not hold "
13244                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13245                    Slog.w(TAG, msg);
13246                    throw new SecurityException(msg);
13247                }
13248                // Permission passed
13249                result = true;
13250            }
13251        } else if ("system".equals(componentProcessName)) {
13252            result = true;
13253        } else {
13254            // App with pre-defined UID, check if it's a persistent app
13255            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13256        }
13257        if (DEBUG_MU) {
13258            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13259                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13260        }
13261        return result;
13262    }
13263
13264    /**
13265     * Checks to see if the caller is in the same app as the singleton
13266     * component, or the component is in a special app. It allows special apps
13267     * to export singleton components but prevents exporting singleton
13268     * components for regular apps.
13269     */
13270    boolean isValidSingletonCall(int callingUid, int componentUid) {
13271        int componentAppId = UserHandle.getAppId(componentUid);
13272        return UserHandle.isSameApp(callingUid, componentUid)
13273                || componentAppId == Process.SYSTEM_UID
13274                || componentAppId == Process.PHONE_UID
13275                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13276                        == PackageManager.PERMISSION_GRANTED;
13277    }
13278
13279    public int bindService(IApplicationThread caller, IBinder token,
13280            Intent service, String resolvedType,
13281            IServiceConnection connection, int flags, int userId) {
13282        enforceNotIsolatedCaller("bindService");
13283        // Refuse possible leaked file descriptors
13284        if (service != null && service.hasFileDescriptors() == true) {
13285            throw new IllegalArgumentException("File descriptors passed in Intent");
13286        }
13287
13288        synchronized(this) {
13289            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13290                    connection, flags, userId);
13291        }
13292    }
13293
13294    public boolean unbindService(IServiceConnection connection) {
13295        synchronized (this) {
13296            return mServices.unbindServiceLocked(connection);
13297        }
13298    }
13299
13300    public void publishService(IBinder token, Intent intent, IBinder service) {
13301        // Refuse possible leaked file descriptors
13302        if (intent != null && intent.hasFileDescriptors() == true) {
13303            throw new IllegalArgumentException("File descriptors passed in Intent");
13304        }
13305
13306        synchronized(this) {
13307            if (!(token instanceof ServiceRecord)) {
13308                throw new IllegalArgumentException("Invalid service token");
13309            }
13310            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13311        }
13312    }
13313
13314    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13315        // Refuse possible leaked file descriptors
13316        if (intent != null && intent.hasFileDescriptors() == true) {
13317            throw new IllegalArgumentException("File descriptors passed in Intent");
13318        }
13319
13320        synchronized(this) {
13321            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13322        }
13323    }
13324
13325    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13326        synchronized(this) {
13327            if (!(token instanceof ServiceRecord)) {
13328                throw new IllegalArgumentException("Invalid service token");
13329            }
13330            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13331        }
13332    }
13333
13334    // =========================================================
13335    // BACKUP AND RESTORE
13336    // =========================================================
13337
13338    // Cause the target app to be launched if necessary and its backup agent
13339    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13340    // activity manager to announce its creation.
13341    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13342        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13343        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13344
13345        synchronized(this) {
13346            // !!! TODO: currently no check here that we're already bound
13347            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13348            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13349            synchronized (stats) {
13350                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13351            }
13352
13353            // Backup agent is now in use, its package can't be stopped.
13354            try {
13355                AppGlobals.getPackageManager().setPackageStoppedState(
13356                        app.packageName, false, UserHandle.getUserId(app.uid));
13357            } catch (RemoteException e) {
13358            } catch (IllegalArgumentException e) {
13359                Slog.w(TAG, "Failed trying to unstop package "
13360                        + app.packageName + ": " + e);
13361            }
13362
13363            BackupRecord r = new BackupRecord(ss, app, backupMode);
13364            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13365                    ? new ComponentName(app.packageName, app.backupAgentName)
13366                    : new ComponentName("android", "FullBackupAgent");
13367            // startProcessLocked() returns existing proc's record if it's already running
13368            ProcessRecord proc = startProcessLocked(app.processName, app,
13369                    false, 0, "backup", hostingName, false, false, false);
13370            if (proc == null) {
13371                Slog.e(TAG, "Unable to start backup agent process " + r);
13372                return false;
13373            }
13374
13375            r.app = proc;
13376            mBackupTarget = r;
13377            mBackupAppName = app.packageName;
13378
13379            // Try not to kill the process during backup
13380            updateOomAdjLocked(proc);
13381
13382            // If the process is already attached, schedule the creation of the backup agent now.
13383            // If it is not yet live, this will be done when it attaches to the framework.
13384            if (proc.thread != null) {
13385                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13386                try {
13387                    proc.thread.scheduleCreateBackupAgent(app,
13388                            compatibilityInfoForPackageLocked(app), backupMode);
13389                } catch (RemoteException e) {
13390                    // Will time out on the backup manager side
13391                }
13392            } else {
13393                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13394            }
13395            // Invariants: at this point, the target app process exists and the application
13396            // is either already running or in the process of coming up.  mBackupTarget and
13397            // mBackupAppName describe the app, so that when it binds back to the AM we
13398            // know that it's scheduled for a backup-agent operation.
13399        }
13400
13401        return true;
13402    }
13403
13404    @Override
13405    public void clearPendingBackup() {
13406        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13407        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13408
13409        synchronized (this) {
13410            mBackupTarget = null;
13411            mBackupAppName = null;
13412        }
13413    }
13414
13415    // A backup agent has just come up
13416    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13417        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13418                + " = " + agent);
13419
13420        synchronized(this) {
13421            if (!agentPackageName.equals(mBackupAppName)) {
13422                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13423                return;
13424            }
13425        }
13426
13427        long oldIdent = Binder.clearCallingIdentity();
13428        try {
13429            IBackupManager bm = IBackupManager.Stub.asInterface(
13430                    ServiceManager.getService(Context.BACKUP_SERVICE));
13431            bm.agentConnected(agentPackageName, agent);
13432        } catch (RemoteException e) {
13433            // can't happen; the backup manager service is local
13434        } catch (Exception e) {
13435            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13436            e.printStackTrace();
13437        } finally {
13438            Binder.restoreCallingIdentity(oldIdent);
13439        }
13440    }
13441
13442    // done with this agent
13443    public void unbindBackupAgent(ApplicationInfo appInfo) {
13444        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13445        if (appInfo == null) {
13446            Slog.w(TAG, "unbind backup agent for null app");
13447            return;
13448        }
13449
13450        synchronized(this) {
13451            try {
13452                if (mBackupAppName == null) {
13453                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13454                    return;
13455                }
13456
13457                if (!mBackupAppName.equals(appInfo.packageName)) {
13458                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13459                    return;
13460                }
13461
13462                // Not backing this app up any more; reset its OOM adjustment
13463                final ProcessRecord proc = mBackupTarget.app;
13464                updateOomAdjLocked(proc);
13465
13466                // If the app crashed during backup, 'thread' will be null here
13467                if (proc.thread != null) {
13468                    try {
13469                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13470                                compatibilityInfoForPackageLocked(appInfo));
13471                    } catch (Exception e) {
13472                        Slog.e(TAG, "Exception when unbinding backup agent:");
13473                        e.printStackTrace();
13474                    }
13475                }
13476            } finally {
13477                mBackupTarget = null;
13478                mBackupAppName = null;
13479            }
13480        }
13481    }
13482    // =========================================================
13483    // BROADCASTS
13484    // =========================================================
13485
13486    private final List getStickiesLocked(String action, IntentFilter filter,
13487            List cur, int userId) {
13488        final ContentResolver resolver = mContext.getContentResolver();
13489        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13490        if (stickies == null) {
13491            return cur;
13492        }
13493        final ArrayList<Intent> list = stickies.get(action);
13494        if (list == null) {
13495            return cur;
13496        }
13497        int N = list.size();
13498        for (int i=0; i<N; i++) {
13499            Intent intent = list.get(i);
13500            if (filter.match(resolver, intent, true, TAG) >= 0) {
13501                if (cur == null) {
13502                    cur = new ArrayList<Intent>();
13503                }
13504                cur.add(intent);
13505            }
13506        }
13507        return cur;
13508    }
13509
13510    boolean isPendingBroadcastProcessLocked(int pid) {
13511        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13512                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13513    }
13514
13515    void skipPendingBroadcastLocked(int pid) {
13516            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13517            for (BroadcastQueue queue : mBroadcastQueues) {
13518                queue.skipPendingBroadcastLocked(pid);
13519            }
13520    }
13521
13522    // The app just attached; send any pending broadcasts that it should receive
13523    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13524        boolean didSomething = false;
13525        for (BroadcastQueue queue : mBroadcastQueues) {
13526            didSomething |= queue.sendPendingBroadcastsLocked(app);
13527        }
13528        return didSomething;
13529    }
13530
13531    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13532            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13533        enforceNotIsolatedCaller("registerReceiver");
13534        int callingUid;
13535        int callingPid;
13536        synchronized(this) {
13537            ProcessRecord callerApp = null;
13538            if (caller != null) {
13539                callerApp = getRecordForAppLocked(caller);
13540                if (callerApp == null) {
13541                    throw new SecurityException(
13542                            "Unable to find app for caller " + caller
13543                            + " (pid=" + Binder.getCallingPid()
13544                            + ") when registering receiver " + receiver);
13545                }
13546                if (callerApp.info.uid != Process.SYSTEM_UID &&
13547                        !callerApp.pkgList.containsKey(callerPackage) &&
13548                        !"android".equals(callerPackage)) {
13549                    throw new SecurityException("Given caller package " + callerPackage
13550                            + " is not running in process " + callerApp);
13551                }
13552                callingUid = callerApp.info.uid;
13553                callingPid = callerApp.pid;
13554            } else {
13555                callerPackage = null;
13556                callingUid = Binder.getCallingUid();
13557                callingPid = Binder.getCallingPid();
13558            }
13559
13560            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13561                    true, true, "registerReceiver", callerPackage);
13562
13563            List allSticky = null;
13564
13565            // Look for any matching sticky broadcasts...
13566            Iterator actions = filter.actionsIterator();
13567            if (actions != null) {
13568                while (actions.hasNext()) {
13569                    String action = (String)actions.next();
13570                    allSticky = getStickiesLocked(action, filter, allSticky,
13571                            UserHandle.USER_ALL);
13572                    allSticky = getStickiesLocked(action, filter, allSticky,
13573                            UserHandle.getUserId(callingUid));
13574                }
13575            } else {
13576                allSticky = getStickiesLocked(null, filter, allSticky,
13577                        UserHandle.USER_ALL);
13578                allSticky = getStickiesLocked(null, filter, allSticky,
13579                        UserHandle.getUserId(callingUid));
13580            }
13581
13582            // The first sticky in the list is returned directly back to
13583            // the client.
13584            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13585
13586            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13587                    + ": " + sticky);
13588
13589            if (receiver == null) {
13590                return sticky;
13591            }
13592
13593            ReceiverList rl
13594                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13595            if (rl == null) {
13596                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13597                        userId, receiver);
13598                if (rl.app != null) {
13599                    rl.app.receivers.add(rl);
13600                } else {
13601                    try {
13602                        receiver.asBinder().linkToDeath(rl, 0);
13603                    } catch (RemoteException e) {
13604                        return sticky;
13605                    }
13606                    rl.linkedToDeath = true;
13607                }
13608                mRegisteredReceivers.put(receiver.asBinder(), rl);
13609            } else if (rl.uid != callingUid) {
13610                throw new IllegalArgumentException(
13611                        "Receiver requested to register for uid " + callingUid
13612                        + " was previously registered for uid " + rl.uid);
13613            } else if (rl.pid != callingPid) {
13614                throw new IllegalArgumentException(
13615                        "Receiver requested to register for pid " + callingPid
13616                        + " was previously registered for pid " + rl.pid);
13617            } else if (rl.userId != userId) {
13618                throw new IllegalArgumentException(
13619                        "Receiver requested to register for user " + userId
13620                        + " was previously registered for user " + rl.userId);
13621            }
13622            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13623                    permission, callingUid, userId);
13624            rl.add(bf);
13625            if (!bf.debugCheck()) {
13626                Slog.w(TAG, "==> For Dynamic broadast");
13627            }
13628            mReceiverResolver.addFilter(bf);
13629
13630            // Enqueue broadcasts for all existing stickies that match
13631            // this filter.
13632            if (allSticky != null) {
13633                ArrayList receivers = new ArrayList();
13634                receivers.add(bf);
13635
13636                int N = allSticky.size();
13637                for (int i=0; i<N; i++) {
13638                    Intent intent = (Intent)allSticky.get(i);
13639                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13640                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13641                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13642                            null, null, false, true, true, -1);
13643                    queue.enqueueParallelBroadcastLocked(r);
13644                    queue.scheduleBroadcastsLocked();
13645                }
13646            }
13647
13648            return sticky;
13649        }
13650    }
13651
13652    public void unregisterReceiver(IIntentReceiver receiver) {
13653        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13654
13655        final long origId = Binder.clearCallingIdentity();
13656        try {
13657            boolean doTrim = false;
13658
13659            synchronized(this) {
13660                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13661                if (rl != null) {
13662                    if (rl.curBroadcast != null) {
13663                        BroadcastRecord r = rl.curBroadcast;
13664                        final boolean doNext = finishReceiverLocked(
13665                                receiver.asBinder(), r.resultCode, r.resultData,
13666                                r.resultExtras, r.resultAbort);
13667                        if (doNext) {
13668                            doTrim = true;
13669                            r.queue.processNextBroadcast(false);
13670                        }
13671                    }
13672
13673                    if (rl.app != null) {
13674                        rl.app.receivers.remove(rl);
13675                    }
13676                    removeReceiverLocked(rl);
13677                    if (rl.linkedToDeath) {
13678                        rl.linkedToDeath = false;
13679                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13680                    }
13681                }
13682            }
13683
13684            // If we actually concluded any broadcasts, we might now be able
13685            // to trim the recipients' apps from our working set
13686            if (doTrim) {
13687                trimApplications();
13688                return;
13689            }
13690
13691        } finally {
13692            Binder.restoreCallingIdentity(origId);
13693        }
13694    }
13695
13696    void removeReceiverLocked(ReceiverList rl) {
13697        mRegisteredReceivers.remove(rl.receiver.asBinder());
13698        int N = rl.size();
13699        for (int i=0; i<N; i++) {
13700            mReceiverResolver.removeFilter(rl.get(i));
13701        }
13702    }
13703
13704    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13705        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13706            ProcessRecord r = mLruProcesses.get(i);
13707            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13708                try {
13709                    r.thread.dispatchPackageBroadcast(cmd, packages);
13710                } catch (RemoteException ex) {
13711                }
13712            }
13713        }
13714    }
13715
13716    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13717            int[] users) {
13718        List<ResolveInfo> receivers = null;
13719        try {
13720            HashSet<ComponentName> singleUserReceivers = null;
13721            boolean scannedFirstReceivers = false;
13722            for (int user : users) {
13723                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13724                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13725                if (user != 0 && newReceivers != null) {
13726                    // If this is not the primary user, we need to check for
13727                    // any receivers that should be filtered out.
13728                    for (int i=0; i<newReceivers.size(); i++) {
13729                        ResolveInfo ri = newReceivers.get(i);
13730                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13731                            newReceivers.remove(i);
13732                            i--;
13733                        }
13734                    }
13735                }
13736                if (newReceivers != null && newReceivers.size() == 0) {
13737                    newReceivers = null;
13738                }
13739                if (receivers == null) {
13740                    receivers = newReceivers;
13741                } else if (newReceivers != null) {
13742                    // We need to concatenate the additional receivers
13743                    // found with what we have do far.  This would be easy,
13744                    // but we also need to de-dup any receivers that are
13745                    // singleUser.
13746                    if (!scannedFirstReceivers) {
13747                        // Collect any single user receivers we had already retrieved.
13748                        scannedFirstReceivers = true;
13749                        for (int i=0; i<receivers.size(); i++) {
13750                            ResolveInfo ri = receivers.get(i);
13751                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13752                                ComponentName cn = new ComponentName(
13753                                        ri.activityInfo.packageName, ri.activityInfo.name);
13754                                if (singleUserReceivers == null) {
13755                                    singleUserReceivers = new HashSet<ComponentName>();
13756                                }
13757                                singleUserReceivers.add(cn);
13758                            }
13759                        }
13760                    }
13761                    // Add the new results to the existing results, tracking
13762                    // and de-dupping single user receivers.
13763                    for (int i=0; i<newReceivers.size(); i++) {
13764                        ResolveInfo ri = newReceivers.get(i);
13765                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13766                            ComponentName cn = new ComponentName(
13767                                    ri.activityInfo.packageName, ri.activityInfo.name);
13768                            if (singleUserReceivers == null) {
13769                                singleUserReceivers = new HashSet<ComponentName>();
13770                            }
13771                            if (!singleUserReceivers.contains(cn)) {
13772                                singleUserReceivers.add(cn);
13773                                receivers.add(ri);
13774                            }
13775                        } else {
13776                            receivers.add(ri);
13777                        }
13778                    }
13779                }
13780            }
13781        } catch (RemoteException ex) {
13782            // pm is in same process, this will never happen.
13783        }
13784        return receivers;
13785    }
13786
13787    private final int broadcastIntentLocked(ProcessRecord callerApp,
13788            String callerPackage, Intent intent, String resolvedType,
13789            IIntentReceiver resultTo, int resultCode, String resultData,
13790            Bundle map, String requiredPermission, int appOp,
13791            boolean ordered, boolean sticky, int callingPid, int callingUid,
13792            int userId) {
13793        intent = new Intent(intent);
13794
13795        // By default broadcasts do not go to stopped apps.
13796        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13797
13798        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13799            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13800            + " ordered=" + ordered + " userid=" + userId);
13801        if ((resultTo != null) && !ordered) {
13802            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13803        }
13804
13805        userId = handleIncomingUser(callingPid, callingUid, userId,
13806                true, false, "broadcast", callerPackage);
13807
13808        // Make sure that the user who is receiving this broadcast is started.
13809        // If not, we will just skip it.
13810        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13811            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13812                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13813                Slog.w(TAG, "Skipping broadcast of " + intent
13814                        + ": user " + userId + " is stopped");
13815                return ActivityManager.BROADCAST_SUCCESS;
13816            }
13817        }
13818
13819        /*
13820         * Prevent non-system code (defined here to be non-persistent
13821         * processes) from sending protected broadcasts.
13822         */
13823        int callingAppId = UserHandle.getAppId(callingUid);
13824        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13825                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13826                || callingUid == 0) {
13827            // Always okay.
13828        } else if (callerApp == null || !callerApp.persistent) {
13829            try {
13830                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13831                        intent.getAction())) {
13832                    String msg = "Permission Denial: not allowed to send broadcast "
13833                            + intent.getAction() + " from pid="
13834                            + callingPid + ", uid=" + callingUid;
13835                    Slog.w(TAG, msg);
13836                    throw new SecurityException(msg);
13837                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13838                    // Special case for compatibility: we don't want apps to send this,
13839                    // but historically it has not been protected and apps may be using it
13840                    // to poke their own app widget.  So, instead of making it protected,
13841                    // just limit it to the caller.
13842                    if (callerApp == null) {
13843                        String msg = "Permission Denial: not allowed to send broadcast "
13844                                + intent.getAction() + " from unknown caller.";
13845                        Slog.w(TAG, msg);
13846                        throw new SecurityException(msg);
13847                    } else if (intent.getComponent() != null) {
13848                        // They are good enough to send to an explicit component...  verify
13849                        // it is being sent to the calling app.
13850                        if (!intent.getComponent().getPackageName().equals(
13851                                callerApp.info.packageName)) {
13852                            String msg = "Permission Denial: not allowed to send broadcast "
13853                                    + intent.getAction() + " to "
13854                                    + intent.getComponent().getPackageName() + " from "
13855                                    + callerApp.info.packageName;
13856                            Slog.w(TAG, msg);
13857                            throw new SecurityException(msg);
13858                        }
13859                    } else {
13860                        // Limit broadcast to their own package.
13861                        intent.setPackage(callerApp.info.packageName);
13862                    }
13863                }
13864            } catch (RemoteException e) {
13865                Slog.w(TAG, "Remote exception", e);
13866                return ActivityManager.BROADCAST_SUCCESS;
13867            }
13868        }
13869
13870        // Handle special intents: if this broadcast is from the package
13871        // manager about a package being removed, we need to remove all of
13872        // its activities from the history stack.
13873        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13874                intent.getAction());
13875        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13876                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13877                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13878                || uidRemoved) {
13879            if (checkComponentPermission(
13880                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13881                    callingPid, callingUid, -1, true)
13882                    == PackageManager.PERMISSION_GRANTED) {
13883                if (uidRemoved) {
13884                    final Bundle intentExtras = intent.getExtras();
13885                    final int uid = intentExtras != null
13886                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13887                    if (uid >= 0) {
13888                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13889                        synchronized (bs) {
13890                            bs.removeUidStatsLocked(uid);
13891                        }
13892                        mAppOpsService.uidRemoved(uid);
13893                    }
13894                } else {
13895                    // If resources are unavailable just force stop all
13896                    // those packages and flush the attribute cache as well.
13897                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13898                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13899                        if (list != null && (list.length > 0)) {
13900                            for (String pkg : list) {
13901                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13902                                        "storage unmount");
13903                            }
13904                            sendPackageBroadcastLocked(
13905                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13906                        }
13907                    } else {
13908                        Uri data = intent.getData();
13909                        String ssp;
13910                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13911                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13912                                    intent.getAction());
13913                            boolean fullUninstall = removed &&
13914                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13915                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13916                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13917                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13918                                        false, fullUninstall, userId,
13919                                        removed ? "pkg removed" : "pkg changed");
13920                            }
13921                            if (removed) {
13922                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13923                                        new String[] {ssp}, userId);
13924                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13925                                    mAppOpsService.packageRemoved(
13926                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13927
13928                                    // Remove all permissions granted from/to this package
13929                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13930                                }
13931                            }
13932                        }
13933                    }
13934                }
13935            } else {
13936                String msg = "Permission Denial: " + intent.getAction()
13937                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13938                        + ", uid=" + callingUid + ")"
13939                        + " requires "
13940                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13941                Slog.w(TAG, msg);
13942                throw new SecurityException(msg);
13943            }
13944
13945        // Special case for adding a package: by default turn on compatibility
13946        // mode.
13947        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13948            Uri data = intent.getData();
13949            String ssp;
13950            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13951                mCompatModePackages.handlePackageAddedLocked(ssp,
13952                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13953            }
13954        }
13955
13956        /*
13957         * If this is the time zone changed action, queue up a message that will reset the timezone
13958         * of all currently running processes. This message will get queued up before the broadcast
13959         * happens.
13960         */
13961        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13962            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13963        }
13964
13965        /*
13966         * If the user set the time, let all running processes know.
13967         */
13968        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13969            final int is24Hour = intent.getBooleanExtra(
13970                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13971            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13972        }
13973
13974        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13975            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13976        }
13977
13978        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13979            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13980            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13981        }
13982
13983        // Add to the sticky list if requested.
13984        if (sticky) {
13985            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13986                    callingPid, callingUid)
13987                    != PackageManager.PERMISSION_GRANTED) {
13988                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13989                        + callingPid + ", uid=" + callingUid
13990                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13991                Slog.w(TAG, msg);
13992                throw new SecurityException(msg);
13993            }
13994            if (requiredPermission != null) {
13995                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13996                        + " and enforce permission " + requiredPermission);
13997                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13998            }
13999            if (intent.getComponent() != null) {
14000                throw new SecurityException(
14001                        "Sticky broadcasts can't target a specific component");
14002            }
14003            // We use userId directly here, since the "all" target is maintained
14004            // as a separate set of sticky broadcasts.
14005            if (userId != UserHandle.USER_ALL) {
14006                // But first, if this is not a broadcast to all users, then
14007                // make sure it doesn't conflict with an existing broadcast to
14008                // all users.
14009                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14010                        UserHandle.USER_ALL);
14011                if (stickies != null) {
14012                    ArrayList<Intent> list = stickies.get(intent.getAction());
14013                    if (list != null) {
14014                        int N = list.size();
14015                        int i;
14016                        for (i=0; i<N; i++) {
14017                            if (intent.filterEquals(list.get(i))) {
14018                                throw new IllegalArgumentException(
14019                                        "Sticky broadcast " + intent + " for user "
14020                                        + userId + " conflicts with existing global broadcast");
14021                            }
14022                        }
14023                    }
14024                }
14025            }
14026            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14027            if (stickies == null) {
14028                stickies = new ArrayMap<String, ArrayList<Intent>>();
14029                mStickyBroadcasts.put(userId, stickies);
14030            }
14031            ArrayList<Intent> list = stickies.get(intent.getAction());
14032            if (list == null) {
14033                list = new ArrayList<Intent>();
14034                stickies.put(intent.getAction(), list);
14035            }
14036            int N = list.size();
14037            int i;
14038            for (i=0; i<N; i++) {
14039                if (intent.filterEquals(list.get(i))) {
14040                    // This sticky already exists, replace it.
14041                    list.set(i, new Intent(intent));
14042                    break;
14043                }
14044            }
14045            if (i >= N) {
14046                list.add(new Intent(intent));
14047            }
14048        }
14049
14050        int[] users;
14051        if (userId == UserHandle.USER_ALL) {
14052            // Caller wants broadcast to go to all started users.
14053            users = mStartedUserArray;
14054        } else {
14055            // Caller wants broadcast to go to one specific user.
14056            users = new int[] {userId};
14057        }
14058
14059        // Figure out who all will receive this broadcast.
14060        List receivers = null;
14061        List<BroadcastFilter> registeredReceivers = null;
14062        // Need to resolve the intent to interested receivers...
14063        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14064                 == 0) {
14065            receivers = collectReceiverComponents(intent, resolvedType, users);
14066        }
14067        if (intent.getComponent() == null) {
14068            registeredReceivers = mReceiverResolver.queryIntent(intent,
14069                    resolvedType, false, userId);
14070        }
14071
14072        final boolean replacePending =
14073                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14074
14075        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14076                + " replacePending=" + replacePending);
14077
14078        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14079        if (!ordered && NR > 0) {
14080            // If we are not serializing this broadcast, then send the
14081            // registered receivers separately so they don't wait for the
14082            // components to be launched.
14083            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14084            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14085                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14086                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14087                    ordered, sticky, false, userId);
14088            if (DEBUG_BROADCAST) Slog.v(
14089                    TAG, "Enqueueing parallel broadcast " + r);
14090            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14091            if (!replaced) {
14092                queue.enqueueParallelBroadcastLocked(r);
14093                queue.scheduleBroadcastsLocked();
14094            }
14095            registeredReceivers = null;
14096            NR = 0;
14097        }
14098
14099        // Merge into one list.
14100        int ir = 0;
14101        if (receivers != null) {
14102            // A special case for PACKAGE_ADDED: do not allow the package
14103            // being added to see this broadcast.  This prevents them from
14104            // using this as a back door to get run as soon as they are
14105            // installed.  Maybe in the future we want to have a special install
14106            // broadcast or such for apps, but we'd like to deliberately make
14107            // this decision.
14108            String skipPackages[] = null;
14109            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14110                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14111                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14112                Uri data = intent.getData();
14113                if (data != null) {
14114                    String pkgName = data.getSchemeSpecificPart();
14115                    if (pkgName != null) {
14116                        skipPackages = new String[] { pkgName };
14117                    }
14118                }
14119            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14120                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14121            }
14122            if (skipPackages != null && (skipPackages.length > 0)) {
14123                for (String skipPackage : skipPackages) {
14124                    if (skipPackage != null) {
14125                        int NT = receivers.size();
14126                        for (int it=0; it<NT; it++) {
14127                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14128                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14129                                receivers.remove(it);
14130                                it--;
14131                                NT--;
14132                            }
14133                        }
14134                    }
14135                }
14136            }
14137
14138            int NT = receivers != null ? receivers.size() : 0;
14139            int it = 0;
14140            ResolveInfo curt = null;
14141            BroadcastFilter curr = null;
14142            while (it < NT && ir < NR) {
14143                if (curt == null) {
14144                    curt = (ResolveInfo)receivers.get(it);
14145                }
14146                if (curr == null) {
14147                    curr = registeredReceivers.get(ir);
14148                }
14149                if (curr.getPriority() >= curt.priority) {
14150                    // Insert this broadcast record into the final list.
14151                    receivers.add(it, curr);
14152                    ir++;
14153                    curr = null;
14154                    it++;
14155                    NT++;
14156                } else {
14157                    // Skip to the next ResolveInfo in the final list.
14158                    it++;
14159                    curt = null;
14160                }
14161            }
14162        }
14163        while (ir < NR) {
14164            if (receivers == null) {
14165                receivers = new ArrayList();
14166            }
14167            receivers.add(registeredReceivers.get(ir));
14168            ir++;
14169        }
14170
14171        if ((receivers != null && receivers.size() > 0)
14172                || resultTo != null) {
14173            BroadcastQueue queue = broadcastQueueForIntent(intent);
14174            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14175                    callerPackage, callingPid, callingUid, resolvedType,
14176                    requiredPermission, appOp, receivers, resultTo, resultCode,
14177                    resultData, map, ordered, sticky, false, userId);
14178            if (DEBUG_BROADCAST) Slog.v(
14179                    TAG, "Enqueueing ordered broadcast " + r
14180                    + ": prev had " + queue.mOrderedBroadcasts.size());
14181            if (DEBUG_BROADCAST) {
14182                int seq = r.intent.getIntExtra("seq", -1);
14183                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14184            }
14185            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14186            if (!replaced) {
14187                queue.enqueueOrderedBroadcastLocked(r);
14188                queue.scheduleBroadcastsLocked();
14189            }
14190        }
14191
14192        return ActivityManager.BROADCAST_SUCCESS;
14193    }
14194
14195    final Intent verifyBroadcastLocked(Intent intent) {
14196        // Refuse possible leaked file descriptors
14197        if (intent != null && intent.hasFileDescriptors() == true) {
14198            throw new IllegalArgumentException("File descriptors passed in Intent");
14199        }
14200
14201        int flags = intent.getFlags();
14202
14203        if (!mProcessesReady) {
14204            // if the caller really truly claims to know what they're doing, go
14205            // ahead and allow the broadcast without launching any receivers
14206            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14207                intent = new Intent(intent);
14208                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14209            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14210                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14211                        + " before boot completion");
14212                throw new IllegalStateException("Cannot broadcast before boot completed");
14213            }
14214        }
14215
14216        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14217            throw new IllegalArgumentException(
14218                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14219        }
14220
14221        return intent;
14222    }
14223
14224    public final int broadcastIntent(IApplicationThread caller,
14225            Intent intent, String resolvedType, IIntentReceiver resultTo,
14226            int resultCode, String resultData, Bundle map,
14227            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14228        enforceNotIsolatedCaller("broadcastIntent");
14229        synchronized(this) {
14230            intent = verifyBroadcastLocked(intent);
14231
14232            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14233            final int callingPid = Binder.getCallingPid();
14234            final int callingUid = Binder.getCallingUid();
14235            final long origId = Binder.clearCallingIdentity();
14236            int res = broadcastIntentLocked(callerApp,
14237                    callerApp != null ? callerApp.info.packageName : null,
14238                    intent, resolvedType, resultTo,
14239                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14240                    callingPid, callingUid, userId);
14241            Binder.restoreCallingIdentity(origId);
14242            return res;
14243        }
14244    }
14245
14246    int broadcastIntentInPackage(String packageName, int uid,
14247            Intent intent, String resolvedType, IIntentReceiver resultTo,
14248            int resultCode, String resultData, Bundle map,
14249            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14250        synchronized(this) {
14251            intent = verifyBroadcastLocked(intent);
14252
14253            final long origId = Binder.clearCallingIdentity();
14254            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14255                    resultTo, resultCode, resultData, map, requiredPermission,
14256                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14257            Binder.restoreCallingIdentity(origId);
14258            return res;
14259        }
14260    }
14261
14262    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14263        // Refuse possible leaked file descriptors
14264        if (intent != null && intent.hasFileDescriptors() == true) {
14265            throw new IllegalArgumentException("File descriptors passed in Intent");
14266        }
14267
14268        userId = handleIncomingUser(Binder.getCallingPid(),
14269                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14270
14271        synchronized(this) {
14272            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14273                    != PackageManager.PERMISSION_GRANTED) {
14274                String msg = "Permission Denial: unbroadcastIntent() from pid="
14275                        + Binder.getCallingPid()
14276                        + ", uid=" + Binder.getCallingUid()
14277                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14278                Slog.w(TAG, msg);
14279                throw new SecurityException(msg);
14280            }
14281            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14282            if (stickies != null) {
14283                ArrayList<Intent> list = stickies.get(intent.getAction());
14284                if (list != null) {
14285                    int N = list.size();
14286                    int i;
14287                    for (i=0; i<N; i++) {
14288                        if (intent.filterEquals(list.get(i))) {
14289                            list.remove(i);
14290                            break;
14291                        }
14292                    }
14293                    if (list.size() <= 0) {
14294                        stickies.remove(intent.getAction());
14295                    }
14296                }
14297                if (stickies.size() <= 0) {
14298                    mStickyBroadcasts.remove(userId);
14299                }
14300            }
14301        }
14302    }
14303
14304    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14305            String resultData, Bundle resultExtras, boolean resultAbort) {
14306        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14307        if (r == null) {
14308            Slog.w(TAG, "finishReceiver called but not found on queue");
14309            return false;
14310        }
14311
14312        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14313    }
14314
14315    void backgroundServicesFinishedLocked(int userId) {
14316        for (BroadcastQueue queue : mBroadcastQueues) {
14317            queue.backgroundServicesFinishedLocked(userId);
14318        }
14319    }
14320
14321    public void finishReceiver(IBinder who, int resultCode, String resultData,
14322            Bundle resultExtras, boolean resultAbort) {
14323        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14324
14325        // Refuse possible leaked file descriptors
14326        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14327            throw new IllegalArgumentException("File descriptors passed in Bundle");
14328        }
14329
14330        final long origId = Binder.clearCallingIdentity();
14331        try {
14332            boolean doNext = false;
14333            BroadcastRecord r;
14334
14335            synchronized(this) {
14336                r = broadcastRecordForReceiverLocked(who);
14337                if (r != null) {
14338                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14339                        resultData, resultExtras, resultAbort, true);
14340                }
14341            }
14342
14343            if (doNext) {
14344                r.queue.processNextBroadcast(false);
14345            }
14346            trimApplications();
14347        } finally {
14348            Binder.restoreCallingIdentity(origId);
14349        }
14350    }
14351
14352    // =========================================================
14353    // INSTRUMENTATION
14354    // =========================================================
14355
14356    public boolean startInstrumentation(ComponentName className,
14357            String profileFile, int flags, Bundle arguments,
14358            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14359            int userId, String abiOverride) {
14360        enforceNotIsolatedCaller("startInstrumentation");
14361        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14362                userId, false, true, "startInstrumentation", null);
14363        // Refuse possible leaked file descriptors
14364        if (arguments != null && arguments.hasFileDescriptors()) {
14365            throw new IllegalArgumentException("File descriptors passed in Bundle");
14366        }
14367
14368        synchronized(this) {
14369            InstrumentationInfo ii = null;
14370            ApplicationInfo ai = null;
14371            try {
14372                ii = mContext.getPackageManager().getInstrumentationInfo(
14373                    className, STOCK_PM_FLAGS);
14374                ai = AppGlobals.getPackageManager().getApplicationInfo(
14375                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14376            } catch (PackageManager.NameNotFoundException e) {
14377            } catch (RemoteException e) {
14378            }
14379            if (ii == null) {
14380                reportStartInstrumentationFailure(watcher, className,
14381                        "Unable to find instrumentation info for: " + className);
14382                return false;
14383            }
14384            if (ai == null) {
14385                reportStartInstrumentationFailure(watcher, className,
14386                        "Unable to find instrumentation target package: " + ii.targetPackage);
14387                return false;
14388            }
14389
14390            int match = mContext.getPackageManager().checkSignatures(
14391                    ii.targetPackage, ii.packageName);
14392            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14393                String msg = "Permission Denial: starting instrumentation "
14394                        + className + " from pid="
14395                        + Binder.getCallingPid()
14396                        + ", uid=" + Binder.getCallingPid()
14397                        + " not allowed because package " + ii.packageName
14398                        + " does not have a signature matching the target "
14399                        + ii.targetPackage;
14400                reportStartInstrumentationFailure(watcher, className, msg);
14401                throw new SecurityException(msg);
14402            }
14403
14404            final long origId = Binder.clearCallingIdentity();
14405            // Instrumentation can kill and relaunch even persistent processes
14406            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14407                    "start instr");
14408            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14409            app.instrumentationClass = className;
14410            app.instrumentationInfo = ai;
14411            app.instrumentationProfileFile = profileFile;
14412            app.instrumentationArguments = arguments;
14413            app.instrumentationWatcher = watcher;
14414            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14415            app.instrumentationResultClass = className;
14416            Binder.restoreCallingIdentity(origId);
14417        }
14418
14419        return true;
14420    }
14421
14422    /**
14423     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14424     * error to the logs, but if somebody is watching, send the report there too.  This enables
14425     * the "am" command to report errors with more information.
14426     *
14427     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14428     * @param cn The component name of the instrumentation.
14429     * @param report The error report.
14430     */
14431    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14432            ComponentName cn, String report) {
14433        Slog.w(TAG, report);
14434        try {
14435            if (watcher != null) {
14436                Bundle results = new Bundle();
14437                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14438                results.putString("Error", report);
14439                watcher.instrumentationStatus(cn, -1, results);
14440            }
14441        } catch (RemoteException e) {
14442            Slog.w(TAG, e);
14443        }
14444    }
14445
14446    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14447        if (app.instrumentationWatcher != null) {
14448            try {
14449                // NOTE:  IInstrumentationWatcher *must* be oneway here
14450                app.instrumentationWatcher.instrumentationFinished(
14451                    app.instrumentationClass,
14452                    resultCode,
14453                    results);
14454            } catch (RemoteException e) {
14455            }
14456        }
14457        if (app.instrumentationUiAutomationConnection != null) {
14458            try {
14459                app.instrumentationUiAutomationConnection.shutdown();
14460            } catch (RemoteException re) {
14461                /* ignore */
14462            }
14463            // Only a UiAutomation can set this flag and now that
14464            // it is finished we make sure it is reset to its default.
14465            mUserIsMonkey = false;
14466        }
14467        app.instrumentationWatcher = null;
14468        app.instrumentationUiAutomationConnection = null;
14469        app.instrumentationClass = null;
14470        app.instrumentationInfo = null;
14471        app.instrumentationProfileFile = null;
14472        app.instrumentationArguments = null;
14473
14474        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14475                "finished inst");
14476    }
14477
14478    public void finishInstrumentation(IApplicationThread target,
14479            int resultCode, Bundle results) {
14480        int userId = UserHandle.getCallingUserId();
14481        // Refuse possible leaked file descriptors
14482        if (results != null && results.hasFileDescriptors()) {
14483            throw new IllegalArgumentException("File descriptors passed in Intent");
14484        }
14485
14486        synchronized(this) {
14487            ProcessRecord app = getRecordForAppLocked(target);
14488            if (app == null) {
14489                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14490                return;
14491            }
14492            final long origId = Binder.clearCallingIdentity();
14493            finishInstrumentationLocked(app, resultCode, results);
14494            Binder.restoreCallingIdentity(origId);
14495        }
14496    }
14497
14498    // =========================================================
14499    // CONFIGURATION
14500    // =========================================================
14501
14502    public ConfigurationInfo getDeviceConfigurationInfo() {
14503        ConfigurationInfo config = new ConfigurationInfo();
14504        synchronized (this) {
14505            config.reqTouchScreen = mConfiguration.touchscreen;
14506            config.reqKeyboardType = mConfiguration.keyboard;
14507            config.reqNavigation = mConfiguration.navigation;
14508            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14509                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14510                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14511            }
14512            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14513                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14514                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14515            }
14516            config.reqGlEsVersion = GL_ES_VERSION;
14517        }
14518        return config;
14519    }
14520
14521    ActivityStack getFocusedStack() {
14522        return mStackSupervisor.getFocusedStack();
14523    }
14524
14525    public Configuration getConfiguration() {
14526        Configuration ci;
14527        synchronized(this) {
14528            ci = new Configuration(mConfiguration);
14529        }
14530        return ci;
14531    }
14532
14533    public void updatePersistentConfiguration(Configuration values) {
14534        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14535                "updateConfiguration()");
14536        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14537                "updateConfiguration()");
14538        if (values == null) {
14539            throw new NullPointerException("Configuration must not be null");
14540        }
14541
14542        synchronized(this) {
14543            final long origId = Binder.clearCallingIdentity();
14544            updateConfigurationLocked(values, null, true, false);
14545            Binder.restoreCallingIdentity(origId);
14546        }
14547    }
14548
14549    public void updateConfiguration(Configuration values) {
14550        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14551                "updateConfiguration()");
14552
14553        synchronized(this) {
14554            if (values == null && mWindowManager != null) {
14555                // sentinel: fetch the current configuration from the window manager
14556                values = mWindowManager.computeNewConfiguration();
14557            }
14558
14559            if (mWindowManager != null) {
14560                mProcessList.applyDisplaySize(mWindowManager);
14561            }
14562
14563            final long origId = Binder.clearCallingIdentity();
14564            if (values != null) {
14565                Settings.System.clearConfiguration(values);
14566            }
14567            updateConfigurationLocked(values, null, false, false);
14568            Binder.restoreCallingIdentity(origId);
14569        }
14570    }
14571
14572    /**
14573     * Do either or both things: (1) change the current configuration, and (2)
14574     * make sure the given activity is running with the (now) current
14575     * configuration.  Returns true if the activity has been left running, or
14576     * false if <var>starting</var> is being destroyed to match the new
14577     * configuration.
14578     * @param persistent TODO
14579     */
14580    boolean updateConfigurationLocked(Configuration values,
14581            ActivityRecord starting, boolean persistent, boolean initLocale) {
14582        int changes = 0;
14583
14584        if (values != null) {
14585            Configuration newConfig = new Configuration(mConfiguration);
14586            changes = newConfig.updateFrom(values);
14587            if (changes != 0) {
14588                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14589                    Slog.i(TAG, "Updating configuration to: " + values);
14590                }
14591
14592                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14593
14594                if (values.locale != null && !initLocale) {
14595                    saveLocaleLocked(values.locale,
14596                                     !values.locale.equals(mConfiguration.locale),
14597                                     values.userSetLocale);
14598                }
14599
14600                mConfigurationSeq++;
14601                if (mConfigurationSeq <= 0) {
14602                    mConfigurationSeq = 1;
14603                }
14604                newConfig.seq = mConfigurationSeq;
14605                mConfiguration = newConfig;
14606                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14607                mUsageStatsService.noteStartConfig(newConfig);
14608
14609                final Configuration configCopy = new Configuration(mConfiguration);
14610
14611                // TODO: If our config changes, should we auto dismiss any currently
14612                // showing dialogs?
14613                mShowDialogs = shouldShowDialogs(newConfig);
14614
14615                AttributeCache ac = AttributeCache.instance();
14616                if (ac != null) {
14617                    ac.updateConfiguration(configCopy);
14618                }
14619
14620                // Make sure all resources in our process are updated
14621                // right now, so that anyone who is going to retrieve
14622                // resource values after we return will be sure to get
14623                // the new ones.  This is especially important during
14624                // boot, where the first config change needs to guarantee
14625                // all resources have that config before following boot
14626                // code is executed.
14627                mSystemThread.applyConfigurationToResources(configCopy);
14628
14629                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14630                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14631                    msg.obj = new Configuration(configCopy);
14632                    mHandler.sendMessage(msg);
14633                }
14634
14635                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14636                    ProcessRecord app = mLruProcesses.get(i);
14637                    try {
14638                        if (app.thread != null) {
14639                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14640                                    + app.processName + " new config " + mConfiguration);
14641                            app.thread.scheduleConfigurationChanged(configCopy);
14642                        }
14643                    } catch (Exception e) {
14644                    }
14645                }
14646                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14647                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14648                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14649                        | Intent.FLAG_RECEIVER_FOREGROUND);
14650                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14651                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14652                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14653                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14654                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14655                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14656                    broadcastIntentLocked(null, null, intent,
14657                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14658                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14659                }
14660            }
14661        }
14662
14663        boolean kept = true;
14664        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14665        // mainStack is null during startup.
14666        if (mainStack != null) {
14667            if (changes != 0 && starting == null) {
14668                // If the configuration changed, and the caller is not already
14669                // in the process of starting an activity, then find the top
14670                // activity to check if its configuration needs to change.
14671                starting = mainStack.topRunningActivityLocked(null);
14672            }
14673
14674            if (starting != null) {
14675                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14676                // And we need to make sure at this point that all other activities
14677                // are made visible with the correct configuration.
14678                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14679            }
14680        }
14681
14682        if (values != null && mWindowManager != null) {
14683            mWindowManager.setNewConfiguration(mConfiguration);
14684        }
14685
14686        return kept;
14687    }
14688
14689    /**
14690     * Decide based on the configuration whether we should shouw the ANR,
14691     * crash, etc dialogs.  The idea is that if there is no affordnace to
14692     * press the on-screen buttons, we shouldn't show the dialog.
14693     *
14694     * A thought: SystemUI might also want to get told about this, the Power
14695     * dialog / global actions also might want different behaviors.
14696     */
14697    private static final boolean shouldShowDialogs(Configuration config) {
14698        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14699                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14700    }
14701
14702    /**
14703     * Save the locale.  You must be inside a synchronized (this) block.
14704     */
14705    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14706        if(isDiff) {
14707            SystemProperties.set("user.language", l.getLanguage());
14708            SystemProperties.set("user.region", l.getCountry());
14709        }
14710
14711        if(isPersist) {
14712            SystemProperties.set("persist.sys.language", l.getLanguage());
14713            SystemProperties.set("persist.sys.country", l.getCountry());
14714            SystemProperties.set("persist.sys.localevar", l.getVariant());
14715        }
14716    }
14717
14718    @Override
14719    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14720        ActivityRecord srec = ActivityRecord.forToken(token);
14721        return srec != null && srec.task.affinity != null &&
14722                srec.task.affinity.equals(destAffinity);
14723    }
14724
14725    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14726            Intent resultData) {
14727
14728        synchronized (this) {
14729            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14730            if (stack != null) {
14731                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14732            }
14733            return false;
14734        }
14735    }
14736
14737    public int getLaunchedFromUid(IBinder activityToken) {
14738        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14739        if (srec == null) {
14740            return -1;
14741        }
14742        return srec.launchedFromUid;
14743    }
14744
14745    public String getLaunchedFromPackage(IBinder activityToken) {
14746        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14747        if (srec == null) {
14748            return null;
14749        }
14750        return srec.launchedFromPackage;
14751    }
14752
14753    // =========================================================
14754    // LIFETIME MANAGEMENT
14755    // =========================================================
14756
14757    // Returns which broadcast queue the app is the current [or imminent] receiver
14758    // on, or 'null' if the app is not an active broadcast recipient.
14759    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14760        BroadcastRecord r = app.curReceiver;
14761        if (r != null) {
14762            return r.queue;
14763        }
14764
14765        // It's not the current receiver, but it might be starting up to become one
14766        synchronized (this) {
14767            for (BroadcastQueue queue : mBroadcastQueues) {
14768                r = queue.mPendingBroadcast;
14769                if (r != null && r.curApp == app) {
14770                    // found it; report which queue it's in
14771                    return queue;
14772                }
14773            }
14774        }
14775
14776        return null;
14777    }
14778
14779    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14780            boolean doingAll, long now) {
14781        if (mAdjSeq == app.adjSeq) {
14782            // This adjustment has already been computed.
14783            return app.curRawAdj;
14784        }
14785
14786        if (app.thread == null) {
14787            app.adjSeq = mAdjSeq;
14788            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14789            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14790            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14791        }
14792
14793        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14794        app.adjSource = null;
14795        app.adjTarget = null;
14796        app.empty = false;
14797        app.cached = false;
14798
14799        final int activitiesSize = app.activities.size();
14800
14801        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14802            // The max adjustment doesn't allow this app to be anything
14803            // below foreground, so it is not worth doing work for it.
14804            app.adjType = "fixed";
14805            app.adjSeq = mAdjSeq;
14806            app.curRawAdj = app.maxAdj;
14807            app.foregroundActivities = false;
14808            app.keeping = true;
14809            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14810            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14811            // System processes can do UI, and when they do we want to have
14812            // them trim their memory after the user leaves the UI.  To
14813            // facilitate this, here we need to determine whether or not it
14814            // is currently showing UI.
14815            app.systemNoUi = true;
14816            if (app == TOP_APP) {
14817                app.systemNoUi = false;
14818            } else if (activitiesSize > 0) {
14819                for (int j = 0; j < activitiesSize; j++) {
14820                    final ActivityRecord r = app.activities.get(j);
14821                    if (r.visible) {
14822                        app.systemNoUi = false;
14823                    }
14824                }
14825            }
14826            if (!app.systemNoUi) {
14827                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14828            }
14829            return (app.curAdj=app.maxAdj);
14830        }
14831
14832        app.keeping = false;
14833        app.systemNoUi = false;
14834
14835        // Determine the importance of the process, starting with most
14836        // important to least, and assign an appropriate OOM adjustment.
14837        int adj;
14838        int schedGroup;
14839        int procState;
14840        boolean foregroundActivities = false;
14841        boolean interesting = false;
14842        BroadcastQueue queue;
14843        if (app == TOP_APP) {
14844            // The last app on the list is the foreground app.
14845            adj = ProcessList.FOREGROUND_APP_ADJ;
14846            schedGroup = Process.THREAD_GROUP_DEFAULT;
14847            app.adjType = "top-activity";
14848            foregroundActivities = true;
14849            interesting = true;
14850            procState = ActivityManager.PROCESS_STATE_TOP;
14851        } else if (app.instrumentationClass != null) {
14852            // Don't want to kill running instrumentation.
14853            adj = ProcessList.FOREGROUND_APP_ADJ;
14854            schedGroup = Process.THREAD_GROUP_DEFAULT;
14855            app.adjType = "instrumentation";
14856            interesting = true;
14857            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14858        } else if ((queue = isReceivingBroadcast(app)) != null) {
14859            // An app that is currently receiving a broadcast also
14860            // counts as being in the foreground for OOM killer purposes.
14861            // It's placed in a sched group based on the nature of the
14862            // broadcast as reflected by which queue it's active in.
14863            adj = ProcessList.FOREGROUND_APP_ADJ;
14864            schedGroup = (queue == mFgBroadcastQueue)
14865                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14866            app.adjType = "broadcast";
14867            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14868        } else if (app.executingServices.size() > 0) {
14869            // An app that is currently executing a service callback also
14870            // counts as being in the foreground.
14871            adj = ProcessList.FOREGROUND_APP_ADJ;
14872            schedGroup = app.execServicesFg ?
14873                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14874            app.adjType = "exec-service";
14875            procState = ActivityManager.PROCESS_STATE_SERVICE;
14876            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14877        } else {
14878            // As far as we know the process is empty.  We may change our mind later.
14879            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14880            // At this point we don't actually know the adjustment.  Use the cached adj
14881            // value that the caller wants us to.
14882            adj = cachedAdj;
14883            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14884            app.cached = true;
14885            app.empty = true;
14886            app.adjType = "cch-empty";
14887        }
14888
14889        // Examine all activities if not already foreground.
14890        if (!foregroundActivities && activitiesSize > 0) {
14891            for (int j = 0; j < activitiesSize; j++) {
14892                final ActivityRecord r = app.activities.get(j);
14893                if (r.app != app) {
14894                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14895                            + app + "?!?");
14896                    continue;
14897                }
14898                if (r.visible) {
14899                    // App has a visible activity; only upgrade adjustment.
14900                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14901                        adj = ProcessList.VISIBLE_APP_ADJ;
14902                        app.adjType = "visible";
14903                    }
14904                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14905                        procState = ActivityManager.PROCESS_STATE_TOP;
14906                    }
14907                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14908                    app.cached = false;
14909                    app.empty = false;
14910                    foregroundActivities = true;
14911                    break;
14912                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14913                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14914                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14915                        app.adjType = "pausing";
14916                    }
14917                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14918                        procState = ActivityManager.PROCESS_STATE_TOP;
14919                    }
14920                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14921                    app.cached = false;
14922                    app.empty = false;
14923                    foregroundActivities = true;
14924                } else if (r.state == ActivityState.STOPPING) {
14925                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14926                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14927                        app.adjType = "stopping";
14928                    }
14929                    // For the process state, we will at this point consider the
14930                    // process to be cached.  It will be cached either as an activity
14931                    // or empty depending on whether the activity is finishing.  We do
14932                    // this so that we can treat the process as cached for purposes of
14933                    // memory trimming (determing current memory level, trim command to
14934                    // send to process) since there can be an arbitrary number of stopping
14935                    // processes and they should soon all go into the cached state.
14936                    if (!r.finishing) {
14937                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14938                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14939                        }
14940                    }
14941                    app.cached = false;
14942                    app.empty = false;
14943                    foregroundActivities = true;
14944                } else {
14945                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14946                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14947                        app.adjType = "cch-act";
14948                    }
14949                }
14950            }
14951        }
14952
14953        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14954            if (app.foregroundServices) {
14955                // The user is aware of this app, so make it visible.
14956                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14957                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14958                app.cached = false;
14959                app.adjType = "fg-service";
14960                schedGroup = Process.THREAD_GROUP_DEFAULT;
14961            } else if (app.forcingToForeground != null) {
14962                // The user is aware of this app, so make it visible.
14963                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14964                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14965                app.cached = false;
14966                app.adjType = "force-fg";
14967                app.adjSource = app.forcingToForeground;
14968                schedGroup = Process.THREAD_GROUP_DEFAULT;
14969            }
14970        }
14971
14972        if (app.foregroundServices) {
14973            interesting = true;
14974        }
14975
14976        if (app == mHeavyWeightProcess) {
14977            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14978                // We don't want to kill the current heavy-weight process.
14979                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14980                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14981                app.cached = false;
14982                app.adjType = "heavy";
14983            }
14984            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14985                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14986            }
14987        }
14988
14989        if (app == mHomeProcess) {
14990            if (adj > ProcessList.HOME_APP_ADJ) {
14991                // This process is hosting what we currently consider to be the
14992                // home app, so we don't want to let it go into the background.
14993                adj = ProcessList.HOME_APP_ADJ;
14994                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14995                app.cached = false;
14996                app.adjType = "home";
14997            }
14998            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14999                procState = ActivityManager.PROCESS_STATE_HOME;
15000            }
15001        }
15002
15003        if (app == mPreviousProcess && app.activities.size() > 0) {
15004            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15005                // This was the previous process that showed UI to the user.
15006                // We want to try to keep it around more aggressively, to give
15007                // a good experience around switching between two apps.
15008                adj = ProcessList.PREVIOUS_APP_ADJ;
15009                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15010                app.cached = false;
15011                app.adjType = "previous";
15012            }
15013            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15014                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15015            }
15016        }
15017
15018        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15019                + " reason=" + app.adjType);
15020
15021        // By default, we use the computed adjustment.  It may be changed if
15022        // there are applications dependent on our services or providers, but
15023        // this gives us a baseline and makes sure we don't get into an
15024        // infinite recursion.
15025        app.adjSeq = mAdjSeq;
15026        app.curRawAdj = adj;
15027        app.hasStartedServices = false;
15028
15029        if (mBackupTarget != null && app == mBackupTarget.app) {
15030            // If possible we want to avoid killing apps while they're being backed up
15031            if (adj > ProcessList.BACKUP_APP_ADJ) {
15032                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15033                adj = ProcessList.BACKUP_APP_ADJ;
15034                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15035                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15036                }
15037                app.adjType = "backup";
15038                app.cached = false;
15039            }
15040            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15041                procState = ActivityManager.PROCESS_STATE_BACKUP;
15042            }
15043        }
15044
15045        boolean mayBeTop = false;
15046
15047        for (int is = app.services.size()-1;
15048                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15049                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15050                        || procState > ActivityManager.PROCESS_STATE_TOP);
15051                is--) {
15052            ServiceRecord s = app.services.valueAt(is);
15053            if (s.startRequested) {
15054                app.hasStartedServices = true;
15055                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15056                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15057                }
15058                if (app.hasShownUi && app != mHomeProcess) {
15059                    // If this process has shown some UI, let it immediately
15060                    // go to the LRU list because it may be pretty heavy with
15061                    // UI stuff.  We'll tag it with a label just to help
15062                    // debug and understand what is going on.
15063                    if (adj > ProcessList.SERVICE_ADJ) {
15064                        app.adjType = "cch-started-ui-services";
15065                    }
15066                } else {
15067                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15068                        // This service has seen some activity within
15069                        // recent memory, so we will keep its process ahead
15070                        // of the background processes.
15071                        if (adj > ProcessList.SERVICE_ADJ) {
15072                            adj = ProcessList.SERVICE_ADJ;
15073                            app.adjType = "started-services";
15074                            app.cached = false;
15075                        }
15076                    }
15077                    // If we have let the service slide into the background
15078                    // state, still have some text describing what it is doing
15079                    // even though the service no longer has an impact.
15080                    if (adj > ProcessList.SERVICE_ADJ) {
15081                        app.adjType = "cch-started-services";
15082                    }
15083                }
15084                // Don't kill this process because it is doing work; it
15085                // has said it is doing work.
15086                app.keeping = true;
15087            }
15088            for (int conni = s.connections.size()-1;
15089                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15090                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15091                            || procState > ActivityManager.PROCESS_STATE_TOP);
15092                    conni--) {
15093                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15094                for (int i = 0;
15095                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15096                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15097                                || procState > ActivityManager.PROCESS_STATE_TOP);
15098                        i++) {
15099                    // XXX should compute this based on the max of
15100                    // all connected clients.
15101                    ConnectionRecord cr = clist.get(i);
15102                    if (cr.binding.client == app) {
15103                        // Binding to ourself is not interesting.
15104                        continue;
15105                    }
15106                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15107                        ProcessRecord client = cr.binding.client;
15108                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15109                                TOP_APP, doingAll, now);
15110                        int clientProcState = client.curProcState;
15111                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15112                            // If the other app is cached for any reason, for purposes here
15113                            // we are going to consider it empty.  The specific cached state
15114                            // doesn't propagate except under certain conditions.
15115                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15116                        }
15117                        String adjType = null;
15118                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15119                            // Not doing bind OOM management, so treat
15120                            // this guy more like a started service.
15121                            if (app.hasShownUi && app != mHomeProcess) {
15122                                // If this process has shown some UI, let it immediately
15123                                // go to the LRU list because it may be pretty heavy with
15124                                // UI stuff.  We'll tag it with a label just to help
15125                                // debug and understand what is going on.
15126                                if (adj > clientAdj) {
15127                                    adjType = "cch-bound-ui-services";
15128                                }
15129                                app.cached = false;
15130                                clientAdj = adj;
15131                                clientProcState = procState;
15132                            } else {
15133                                if (now >= (s.lastActivity
15134                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15135                                    // This service has not seen activity within
15136                                    // recent memory, so allow it to drop to the
15137                                    // LRU list if there is no other reason to keep
15138                                    // it around.  We'll also tag it with a label just
15139                                    // to help debug and undertand what is going on.
15140                                    if (adj > clientAdj) {
15141                                        adjType = "cch-bound-services";
15142                                    }
15143                                    clientAdj = adj;
15144                                }
15145                            }
15146                        }
15147                        if (adj > clientAdj) {
15148                            // If this process has recently shown UI, and
15149                            // the process that is binding to it is less
15150                            // important than being visible, then we don't
15151                            // care about the binding as much as we care
15152                            // about letting this process get into the LRU
15153                            // list to be killed and restarted if needed for
15154                            // memory.
15155                            if (app.hasShownUi && app != mHomeProcess
15156                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15157                                adjType = "cch-bound-ui-services";
15158                            } else {
15159                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15160                                        |Context.BIND_IMPORTANT)) != 0) {
15161                                    adj = clientAdj;
15162                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15163                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15164                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15165                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15166                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15167                                    adj = clientAdj;
15168                                } else {
15169                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15170                                        adj = ProcessList.VISIBLE_APP_ADJ;
15171                                    }
15172                                }
15173                                if (!client.cached) {
15174                                    app.cached = false;
15175                                }
15176                                if (client.keeping) {
15177                                    app.keeping = true;
15178                                }
15179                                adjType = "service";
15180                            }
15181                        }
15182                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15183                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15184                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15185                            }
15186                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15187                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15188                                    // Special handling of clients who are in the top state.
15189                                    // We *may* want to consider this process to be in the
15190                                    // top state as well, but only if there is not another
15191                                    // reason for it to be running.  Being on the top is a
15192                                    // special state, meaning you are specifically running
15193                                    // for the current top app.  If the process is already
15194                                    // running in the background for some other reason, it
15195                                    // is more important to continue considering it to be
15196                                    // in the background state.
15197                                    mayBeTop = true;
15198                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15199                                } else {
15200                                    // Special handling for above-top states (persistent
15201                                    // processes).  These should not bring the current process
15202                                    // into the top state, since they are not on top.  Instead
15203                                    // give them the best state after that.
15204                                    clientProcState =
15205                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15206                                }
15207                            }
15208                        } else {
15209                            if (clientProcState <
15210                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15211                                clientProcState =
15212                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15213                            }
15214                        }
15215                        if (procState > clientProcState) {
15216                            procState = clientProcState;
15217                        }
15218                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15219                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15220                            app.pendingUiClean = true;
15221                        }
15222                        if (adjType != null) {
15223                            app.adjType = adjType;
15224                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15225                                    .REASON_SERVICE_IN_USE;
15226                            app.adjSource = cr.binding.client;
15227                            app.adjSourceOom = clientAdj;
15228                            app.adjTarget = s.name;
15229                        }
15230                    }
15231                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15232                        app.treatLikeActivity = true;
15233                    }
15234                    final ActivityRecord a = cr.activity;
15235                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15236                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15237                                (a.visible || a.state == ActivityState.RESUMED
15238                                 || a.state == ActivityState.PAUSING)) {
15239                            adj = ProcessList.FOREGROUND_APP_ADJ;
15240                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15241                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15242                            }
15243                            app.cached = false;
15244                            app.adjType = "service";
15245                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15246                                    .REASON_SERVICE_IN_USE;
15247                            app.adjSource = a;
15248                            app.adjSourceOom = adj;
15249                            app.adjTarget = s.name;
15250                        }
15251                    }
15252                }
15253            }
15254        }
15255
15256        for (int provi = app.pubProviders.size()-1;
15257                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15258                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15259                        || procState > ActivityManager.PROCESS_STATE_TOP);
15260                provi--) {
15261            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15262            for (int i = cpr.connections.size()-1;
15263                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15264                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15265                            || procState > ActivityManager.PROCESS_STATE_TOP);
15266                    i--) {
15267                ContentProviderConnection conn = cpr.connections.get(i);
15268                ProcessRecord client = conn.client;
15269                if (client == app) {
15270                    // Being our own client is not interesting.
15271                    continue;
15272                }
15273                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15274                int clientProcState = client.curProcState;
15275                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15276                    // If the other app is cached for any reason, for purposes here
15277                    // we are going to consider it empty.
15278                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15279                }
15280                if (adj > clientAdj) {
15281                    if (app.hasShownUi && app != mHomeProcess
15282                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15283                        app.adjType = "cch-ui-provider";
15284                    } else {
15285                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15286                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15287                        app.adjType = "provider";
15288                    }
15289                    app.cached &= client.cached;
15290                    app.keeping |= client.keeping;
15291                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15292                            .REASON_PROVIDER_IN_USE;
15293                    app.adjSource = client;
15294                    app.adjSourceOom = clientAdj;
15295                    app.adjTarget = cpr.name;
15296                }
15297                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15298                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15299                        // Special handling of clients who are in the top state.
15300                        // We *may* want to consider this process to be in the
15301                        // top state as well, but only if there is not another
15302                        // reason for it to be running.  Being on the top is a
15303                        // special state, meaning you are specifically running
15304                        // for the current top app.  If the process is already
15305                        // running in the background for some other reason, it
15306                        // is more important to continue considering it to be
15307                        // in the background state.
15308                        mayBeTop = true;
15309                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15310                    } else {
15311                        // Special handling for above-top states (persistent
15312                        // processes).  These should not bring the current process
15313                        // into the top state, since they are not on top.  Instead
15314                        // give them the best state after that.
15315                        clientProcState =
15316                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15317                    }
15318                }
15319                if (procState > clientProcState) {
15320                    procState = clientProcState;
15321                }
15322                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15323                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15324                }
15325            }
15326            // If the provider has external (non-framework) process
15327            // dependencies, ensure that its adjustment is at least
15328            // FOREGROUND_APP_ADJ.
15329            if (cpr.hasExternalProcessHandles()) {
15330                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15331                    adj = ProcessList.FOREGROUND_APP_ADJ;
15332                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15333                    app.cached = false;
15334                    app.keeping = true;
15335                    app.adjType = "provider";
15336                    app.adjTarget = cpr.name;
15337                }
15338                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15339                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15340                }
15341            }
15342        }
15343
15344        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15345            // A client of one of our services or providers is in the top state.  We
15346            // *may* want to be in the top state, but not if we are already running in
15347            // the background for some other reason.  For the decision here, we are going
15348            // to pick out a few specific states that we want to remain in when a client
15349            // is top (states that tend to be longer-term) and otherwise allow it to go
15350            // to the top state.
15351            switch (procState) {
15352                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15353                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15354                case ActivityManager.PROCESS_STATE_SERVICE:
15355                    // These all are longer-term states, so pull them up to the top
15356                    // of the background states, but not all the way to the top state.
15357                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15358                    break;
15359                default:
15360                    // Otherwise, top is a better choice, so take it.
15361                    procState = ActivityManager.PROCESS_STATE_TOP;
15362                    break;
15363            }
15364        }
15365
15366        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15367            if (app.hasClientActivities) {
15368                // This is a cached process, but with client activities.  Mark it so.
15369                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15370                app.adjType = "cch-client-act";
15371            } else if (app.treatLikeActivity) {
15372                // This is a cached process, but somebody wants us to treat it like it has
15373                // an activity, okay!
15374                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15375                app.adjType = "cch-as-act";
15376            }
15377        }
15378
15379        if (adj == ProcessList.SERVICE_ADJ) {
15380            if (doingAll) {
15381                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15382                mNewNumServiceProcs++;
15383                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15384                if (!app.serviceb) {
15385                    // This service isn't far enough down on the LRU list to
15386                    // normally be a B service, but if we are low on RAM and it
15387                    // is large we want to force it down since we would prefer to
15388                    // keep launcher over it.
15389                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15390                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15391                        app.serviceHighRam = true;
15392                        app.serviceb = true;
15393                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15394                    } else {
15395                        mNewNumAServiceProcs++;
15396                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15397                    }
15398                } else {
15399                    app.serviceHighRam = false;
15400                }
15401            }
15402            if (app.serviceb) {
15403                adj = ProcessList.SERVICE_B_ADJ;
15404            }
15405        }
15406
15407        app.curRawAdj = adj;
15408
15409        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15410        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15411        if (adj > app.maxAdj) {
15412            adj = app.maxAdj;
15413            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15414                schedGroup = Process.THREAD_GROUP_DEFAULT;
15415            }
15416        }
15417        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15418            app.keeping = true;
15419        }
15420
15421        // Do final modification to adj.  Everything we do between here and applying
15422        // the final setAdj must be done in this function, because we will also use
15423        // it when computing the final cached adj later.  Note that we don't need to
15424        // worry about this for max adj above, since max adj will always be used to
15425        // keep it out of the cached vaues.
15426        app.curAdj = app.modifyRawOomAdj(adj);
15427        app.curSchedGroup = schedGroup;
15428        app.curProcState = procState;
15429        app.foregroundActivities = foregroundActivities;
15430
15431        return app.curRawAdj;
15432    }
15433
15434    /**
15435     * Schedule PSS collection of a process.
15436     */
15437    void requestPssLocked(ProcessRecord proc, int procState) {
15438        if (mPendingPssProcesses.contains(proc)) {
15439            return;
15440        }
15441        if (mPendingPssProcesses.size() == 0) {
15442            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15443        }
15444        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15445        proc.pssProcState = procState;
15446        mPendingPssProcesses.add(proc);
15447    }
15448
15449    /**
15450     * Schedule PSS collection of all processes.
15451     */
15452    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15453        if (!always) {
15454            if (now < (mLastFullPssTime +
15455                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15456                return;
15457            }
15458        }
15459        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15460        mLastFullPssTime = now;
15461        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15462        mPendingPssProcesses.clear();
15463        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15464            ProcessRecord app = mLruProcesses.get(i);
15465            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15466                app.pssProcState = app.setProcState;
15467                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15468                        isSleeping(), now);
15469                mPendingPssProcesses.add(app);
15470            }
15471        }
15472        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15473    }
15474
15475    /**
15476     * Ask a given process to GC right now.
15477     */
15478    final void performAppGcLocked(ProcessRecord app) {
15479        try {
15480            app.lastRequestedGc = SystemClock.uptimeMillis();
15481            if (app.thread != null) {
15482                if (app.reportLowMemory) {
15483                    app.reportLowMemory = false;
15484                    app.thread.scheduleLowMemory();
15485                } else {
15486                    app.thread.processInBackground();
15487                }
15488            }
15489        } catch (Exception e) {
15490            // whatever.
15491        }
15492    }
15493
15494    /**
15495     * Returns true if things are idle enough to perform GCs.
15496     */
15497    private final boolean canGcNowLocked() {
15498        boolean processingBroadcasts = false;
15499        for (BroadcastQueue q : mBroadcastQueues) {
15500            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15501                processingBroadcasts = true;
15502            }
15503        }
15504        return !processingBroadcasts
15505                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15506    }
15507
15508    /**
15509     * Perform GCs on all processes that are waiting for it, but only
15510     * if things are idle.
15511     */
15512    final void performAppGcsLocked() {
15513        final int N = mProcessesToGc.size();
15514        if (N <= 0) {
15515            return;
15516        }
15517        if (canGcNowLocked()) {
15518            while (mProcessesToGc.size() > 0) {
15519                ProcessRecord proc = mProcessesToGc.remove(0);
15520                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15521                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15522                            <= SystemClock.uptimeMillis()) {
15523                        // To avoid spamming the system, we will GC processes one
15524                        // at a time, waiting a few seconds between each.
15525                        performAppGcLocked(proc);
15526                        scheduleAppGcsLocked();
15527                        return;
15528                    } else {
15529                        // It hasn't been long enough since we last GCed this
15530                        // process...  put it in the list to wait for its time.
15531                        addProcessToGcListLocked(proc);
15532                        break;
15533                    }
15534                }
15535            }
15536
15537            scheduleAppGcsLocked();
15538        }
15539    }
15540
15541    /**
15542     * If all looks good, perform GCs on all processes waiting for them.
15543     */
15544    final void performAppGcsIfAppropriateLocked() {
15545        if (canGcNowLocked()) {
15546            performAppGcsLocked();
15547            return;
15548        }
15549        // Still not idle, wait some more.
15550        scheduleAppGcsLocked();
15551    }
15552
15553    /**
15554     * Schedule the execution of all pending app GCs.
15555     */
15556    final void scheduleAppGcsLocked() {
15557        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15558
15559        if (mProcessesToGc.size() > 0) {
15560            // Schedule a GC for the time to the next process.
15561            ProcessRecord proc = mProcessesToGc.get(0);
15562            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15563
15564            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15565            long now = SystemClock.uptimeMillis();
15566            if (when < (now+GC_TIMEOUT)) {
15567                when = now + GC_TIMEOUT;
15568            }
15569            mHandler.sendMessageAtTime(msg, when);
15570        }
15571    }
15572
15573    /**
15574     * Add a process to the array of processes waiting to be GCed.  Keeps the
15575     * list in sorted order by the last GC time.  The process can't already be
15576     * on the list.
15577     */
15578    final void addProcessToGcListLocked(ProcessRecord proc) {
15579        boolean added = false;
15580        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15581            if (mProcessesToGc.get(i).lastRequestedGc <
15582                    proc.lastRequestedGc) {
15583                added = true;
15584                mProcessesToGc.add(i+1, proc);
15585                break;
15586            }
15587        }
15588        if (!added) {
15589            mProcessesToGc.add(0, proc);
15590        }
15591    }
15592
15593    /**
15594     * Set up to ask a process to GC itself.  This will either do it
15595     * immediately, or put it on the list of processes to gc the next
15596     * time things are idle.
15597     */
15598    final void scheduleAppGcLocked(ProcessRecord app) {
15599        long now = SystemClock.uptimeMillis();
15600        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15601            return;
15602        }
15603        if (!mProcessesToGc.contains(app)) {
15604            addProcessToGcListLocked(app);
15605            scheduleAppGcsLocked();
15606        }
15607    }
15608
15609    final void checkExcessivePowerUsageLocked(boolean doKills) {
15610        updateCpuStatsNow();
15611
15612        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15613        boolean doWakeKills = doKills;
15614        boolean doCpuKills = doKills;
15615        if (mLastPowerCheckRealtime == 0) {
15616            doWakeKills = false;
15617        }
15618        if (mLastPowerCheckUptime == 0) {
15619            doCpuKills = false;
15620        }
15621        if (stats.isScreenOn()) {
15622            doWakeKills = false;
15623        }
15624        final long curRealtime = SystemClock.elapsedRealtime();
15625        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15626        final long curUptime = SystemClock.uptimeMillis();
15627        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15628        mLastPowerCheckRealtime = curRealtime;
15629        mLastPowerCheckUptime = curUptime;
15630        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15631            doWakeKills = false;
15632        }
15633        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15634            doCpuKills = false;
15635        }
15636        int i = mLruProcesses.size();
15637        while (i > 0) {
15638            i--;
15639            ProcessRecord app = mLruProcesses.get(i);
15640            if (!app.keeping) {
15641                long wtime;
15642                synchronized (stats) {
15643                    wtime = stats.getProcessWakeTime(app.info.uid,
15644                            app.pid, curRealtime);
15645                }
15646                long wtimeUsed = wtime - app.lastWakeTime;
15647                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15648                if (DEBUG_POWER) {
15649                    StringBuilder sb = new StringBuilder(128);
15650                    sb.append("Wake for ");
15651                    app.toShortString(sb);
15652                    sb.append(": over ");
15653                    TimeUtils.formatDuration(realtimeSince, sb);
15654                    sb.append(" used ");
15655                    TimeUtils.formatDuration(wtimeUsed, sb);
15656                    sb.append(" (");
15657                    sb.append((wtimeUsed*100)/realtimeSince);
15658                    sb.append("%)");
15659                    Slog.i(TAG, sb.toString());
15660                    sb.setLength(0);
15661                    sb.append("CPU for ");
15662                    app.toShortString(sb);
15663                    sb.append(": over ");
15664                    TimeUtils.formatDuration(uptimeSince, sb);
15665                    sb.append(" used ");
15666                    TimeUtils.formatDuration(cputimeUsed, sb);
15667                    sb.append(" (");
15668                    sb.append((cputimeUsed*100)/uptimeSince);
15669                    sb.append("%)");
15670                    Slog.i(TAG, sb.toString());
15671                }
15672                // If a process has held a wake lock for more
15673                // than 50% of the time during this period,
15674                // that sounds bad.  Kill!
15675                if (doWakeKills && realtimeSince > 0
15676                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15677                    synchronized (stats) {
15678                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15679                                realtimeSince, wtimeUsed);
15680                    }
15681                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15682                            + " during " + realtimeSince);
15683                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15684                } else if (doCpuKills && uptimeSince > 0
15685                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15686                    synchronized (stats) {
15687                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15688                                uptimeSince, cputimeUsed);
15689                    }
15690                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15691                            + " during " + uptimeSince);
15692                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15693                } else {
15694                    app.lastWakeTime = wtime;
15695                    app.lastCpuTime = app.curCpuTime;
15696                }
15697            }
15698        }
15699    }
15700
15701    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15702            ProcessRecord TOP_APP, boolean doingAll, long now) {
15703        boolean success = true;
15704
15705        if (app.curRawAdj != app.setRawAdj) {
15706            if (wasKeeping && !app.keeping) {
15707                // This app is no longer something we want to keep.  Note
15708                // its current wake lock time to later know to kill it if
15709                // it is not behaving well.
15710                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15711                synchronized (stats) {
15712                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15713                            app.pid, SystemClock.elapsedRealtime());
15714                }
15715                app.lastCpuTime = app.curCpuTime;
15716            }
15717
15718            app.setRawAdj = app.curRawAdj;
15719        }
15720
15721        int changes = 0;
15722
15723        if (app.curAdj != app.setAdj) {
15724            ProcessList.setOomAdj(app.pid, app.curAdj);
15725            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15726                TAG, "Set " + app.pid + " " + app.processName +
15727                " adj " + app.curAdj + ": " + app.adjType);
15728            app.setAdj = app.curAdj;
15729        }
15730
15731        if (app.setSchedGroup != app.curSchedGroup) {
15732            app.setSchedGroup = app.curSchedGroup;
15733            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15734                    "Setting process group of " + app.processName
15735                    + " to " + app.curSchedGroup);
15736            if (app.waitingToKill != null &&
15737                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15738                killUnneededProcessLocked(app, app.waitingToKill);
15739                success = false;
15740            } else {
15741                if (true) {
15742                    long oldId = Binder.clearCallingIdentity();
15743                    try {
15744                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15745                    } catch (Exception e) {
15746                        Slog.w(TAG, "Failed setting process group of " + app.pid
15747                                + " to " + app.curSchedGroup);
15748                        e.printStackTrace();
15749                    } finally {
15750                        Binder.restoreCallingIdentity(oldId);
15751                    }
15752                } else {
15753                    if (app.thread != null) {
15754                        try {
15755                            app.thread.setSchedulingGroup(app.curSchedGroup);
15756                        } catch (RemoteException e) {
15757                        }
15758                    }
15759                }
15760                Process.setSwappiness(app.pid,
15761                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15762            }
15763        }
15764        if (app.repForegroundActivities != app.foregroundActivities) {
15765            app.repForegroundActivities = app.foregroundActivities;
15766            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15767        }
15768        if (app.repProcState != app.curProcState) {
15769            app.repProcState = app.curProcState;
15770            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15771            if (app.thread != null) {
15772                try {
15773                    if (false) {
15774                        //RuntimeException h = new RuntimeException("here");
15775                        Slog.i(TAG, "Sending new process state " + app.repProcState
15776                                + " to " + app /*, h*/);
15777                    }
15778                    app.thread.setProcessState(app.repProcState);
15779                } catch (RemoteException e) {
15780                }
15781            }
15782        }
15783        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15784                app.setProcState)) {
15785            app.lastStateTime = now;
15786            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15787                    isSleeping(), now);
15788            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15789                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15790                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15791                    + (app.nextPssTime-now) + ": " + app);
15792        } else {
15793            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15794                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15795                requestPssLocked(app, app.setProcState);
15796                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15797                        isSleeping(), now);
15798            } else if (false && DEBUG_PSS) {
15799                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15800            }
15801        }
15802        if (app.setProcState != app.curProcState) {
15803            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15804                    "Proc state change of " + app.processName
15805                    + " to " + app.curProcState);
15806            app.setProcState = app.curProcState;
15807            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15808                app.notCachedSinceIdle = false;
15809            }
15810            if (!doingAll) {
15811                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15812            } else {
15813                app.procStateChanged = true;
15814            }
15815        }
15816
15817        if (changes != 0) {
15818            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15819            int i = mPendingProcessChanges.size()-1;
15820            ProcessChangeItem item = null;
15821            while (i >= 0) {
15822                item = mPendingProcessChanges.get(i);
15823                if (item.pid == app.pid) {
15824                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15825                    break;
15826                }
15827                i--;
15828            }
15829            if (i < 0) {
15830                // No existing item in pending changes; need a new one.
15831                final int NA = mAvailProcessChanges.size();
15832                if (NA > 0) {
15833                    item = mAvailProcessChanges.remove(NA-1);
15834                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15835                } else {
15836                    item = new ProcessChangeItem();
15837                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15838                }
15839                item.changes = 0;
15840                item.pid = app.pid;
15841                item.uid = app.info.uid;
15842                if (mPendingProcessChanges.size() == 0) {
15843                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15844                            "*** Enqueueing dispatch processes changed!");
15845                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15846                }
15847                mPendingProcessChanges.add(item);
15848            }
15849            item.changes |= changes;
15850            item.processState = app.repProcState;
15851            item.foregroundActivities = app.repForegroundActivities;
15852            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15853                    + Integer.toHexString(System.identityHashCode(item))
15854                    + " " + app.toShortString() + ": changes=" + item.changes
15855                    + " procState=" + item.processState
15856                    + " foreground=" + item.foregroundActivities
15857                    + " type=" + app.adjType + " source=" + app.adjSource
15858                    + " target=" + app.adjTarget);
15859        }
15860
15861        return success;
15862    }
15863
15864    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15865        if (proc.thread != null && proc.baseProcessTracker != null) {
15866            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15867        }
15868    }
15869
15870    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15871            ProcessRecord TOP_APP, boolean doingAll, long now) {
15872        if (app.thread == null) {
15873            return false;
15874        }
15875
15876        final boolean wasKeeping = app.keeping;
15877
15878        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15879
15880        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15881    }
15882
15883    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15884            boolean oomAdj) {
15885        if (isForeground != proc.foregroundServices) {
15886            proc.foregroundServices = isForeground;
15887            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15888                    proc.info.uid);
15889            if (isForeground) {
15890                if (curProcs == null) {
15891                    curProcs = new ArrayList<ProcessRecord>();
15892                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15893                }
15894                if (!curProcs.contains(proc)) {
15895                    curProcs.add(proc);
15896                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15897                            proc.info.packageName, proc.info.uid);
15898                }
15899            } else {
15900                if (curProcs != null) {
15901                    if (curProcs.remove(proc)) {
15902                        mBatteryStatsService.noteEvent(
15903                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15904                                proc.info.packageName, proc.info.uid);
15905                        if (curProcs.size() <= 0) {
15906                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15907                        }
15908                    }
15909                }
15910            }
15911            if (oomAdj) {
15912                updateOomAdjLocked();
15913            }
15914        }
15915    }
15916
15917    private final ActivityRecord resumedAppLocked() {
15918        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15919        String pkg;
15920        int uid;
15921        if (act != null && !act.sleeping) {
15922            pkg = act.packageName;
15923            uid = act.info.applicationInfo.uid;
15924        } else {
15925            pkg = null;
15926            uid = -1;
15927        }
15928        // Has the UID or resumed package name changed?
15929        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15930                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15931            if (mCurResumedPackage != null) {
15932                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15933                        mCurResumedPackage, mCurResumedUid);
15934            }
15935            mCurResumedPackage = pkg;
15936            mCurResumedUid = uid;
15937            if (mCurResumedPackage != null) {
15938                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15939                        mCurResumedPackage, mCurResumedUid);
15940            }
15941        }
15942        return act;
15943    }
15944
15945    final boolean updateOomAdjLocked(ProcessRecord app) {
15946        final ActivityRecord TOP_ACT = resumedAppLocked();
15947        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15948        final boolean wasCached = app.cached;
15949
15950        mAdjSeq++;
15951
15952        // This is the desired cached adjusment we want to tell it to use.
15953        // If our app is currently cached, we know it, and that is it.  Otherwise,
15954        // we don't know it yet, and it needs to now be cached we will then
15955        // need to do a complete oom adj.
15956        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15957                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15958        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15959                SystemClock.uptimeMillis());
15960        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15961            // Changed to/from cached state, so apps after it in the LRU
15962            // list may also be changed.
15963            updateOomAdjLocked();
15964        }
15965        return success;
15966    }
15967
15968    final void updateOomAdjLocked() {
15969        final ActivityRecord TOP_ACT = resumedAppLocked();
15970        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15971        final long now = SystemClock.uptimeMillis();
15972        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15973        final int N = mLruProcesses.size();
15974
15975        if (false) {
15976            RuntimeException e = new RuntimeException();
15977            e.fillInStackTrace();
15978            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15979        }
15980
15981        mAdjSeq++;
15982        mNewNumServiceProcs = 0;
15983        mNewNumAServiceProcs = 0;
15984
15985        final int emptyProcessLimit;
15986        final int cachedProcessLimit;
15987        if (mProcessLimit <= 0) {
15988            emptyProcessLimit = cachedProcessLimit = 0;
15989        } else if (mProcessLimit == 1) {
15990            emptyProcessLimit = 1;
15991            cachedProcessLimit = 0;
15992        } else {
15993            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15994            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15995        }
15996
15997        // Let's determine how many processes we have running vs.
15998        // how many slots we have for background processes; we may want
15999        // to put multiple processes in a slot of there are enough of
16000        // them.
16001        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16002                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16003        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16004        if (numEmptyProcs > cachedProcessLimit) {
16005            // If there are more empty processes than our limit on cached
16006            // processes, then use the cached process limit for the factor.
16007            // This ensures that the really old empty processes get pushed
16008            // down to the bottom, so if we are running low on memory we will
16009            // have a better chance at keeping around more cached processes
16010            // instead of a gazillion empty processes.
16011            numEmptyProcs = cachedProcessLimit;
16012        }
16013        int emptyFactor = numEmptyProcs/numSlots;
16014        if (emptyFactor < 1) emptyFactor = 1;
16015        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16016        if (cachedFactor < 1) cachedFactor = 1;
16017        int stepCached = 0;
16018        int stepEmpty = 0;
16019        int numCached = 0;
16020        int numEmpty = 0;
16021        int numTrimming = 0;
16022
16023        mNumNonCachedProcs = 0;
16024        mNumCachedHiddenProcs = 0;
16025
16026        // First update the OOM adjustment for each of the
16027        // application processes based on their current state.
16028        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16029        int nextCachedAdj = curCachedAdj+1;
16030        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16031        int nextEmptyAdj = curEmptyAdj+2;
16032        for (int i=N-1; i>=0; i--) {
16033            ProcessRecord app = mLruProcesses.get(i);
16034            if (!app.killedByAm && app.thread != null) {
16035                app.procStateChanged = false;
16036                final boolean wasKeeping = app.keeping;
16037                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16038
16039                // If we haven't yet assigned the final cached adj
16040                // to the process, do that now.
16041                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16042                    switch (app.curProcState) {
16043                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16044                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16045                            // This process is a cached process holding activities...
16046                            // assign it the next cached value for that type, and then
16047                            // step that cached level.
16048                            app.curRawAdj = curCachedAdj;
16049                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16050                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16051                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16052                                    + ")");
16053                            if (curCachedAdj != nextCachedAdj) {
16054                                stepCached++;
16055                                if (stepCached >= cachedFactor) {
16056                                    stepCached = 0;
16057                                    curCachedAdj = nextCachedAdj;
16058                                    nextCachedAdj += 2;
16059                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16060                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16061                                    }
16062                                }
16063                            }
16064                            break;
16065                        default:
16066                            // For everything else, assign next empty cached process
16067                            // level and bump that up.  Note that this means that
16068                            // long-running services that have dropped down to the
16069                            // cached level will be treated as empty (since their process
16070                            // state is still as a service), which is what we want.
16071                            app.curRawAdj = curEmptyAdj;
16072                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16073                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16074                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16075                                    + ")");
16076                            if (curEmptyAdj != nextEmptyAdj) {
16077                                stepEmpty++;
16078                                if (stepEmpty >= emptyFactor) {
16079                                    stepEmpty = 0;
16080                                    curEmptyAdj = nextEmptyAdj;
16081                                    nextEmptyAdj += 2;
16082                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16083                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16084                                    }
16085                                }
16086                            }
16087                            break;
16088                    }
16089                }
16090
16091                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16092
16093                // Count the number of process types.
16094                switch (app.curProcState) {
16095                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16096                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16097                        mNumCachedHiddenProcs++;
16098                        numCached++;
16099                        if (numCached > cachedProcessLimit) {
16100                            killUnneededProcessLocked(app, "cached #" + numCached);
16101                        }
16102                        break;
16103                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16104                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16105                                && app.lastActivityTime < oldTime) {
16106                            killUnneededProcessLocked(app, "empty for "
16107                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16108                                    / 1000) + "s");
16109                        } else {
16110                            numEmpty++;
16111                            if (numEmpty > emptyProcessLimit) {
16112                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16113                            }
16114                        }
16115                        break;
16116                    default:
16117                        mNumNonCachedProcs++;
16118                        break;
16119                }
16120
16121                if (app.isolated && app.services.size() <= 0) {
16122                    // If this is an isolated process, and there are no
16123                    // services running in it, then the process is no longer
16124                    // needed.  We agressively kill these because we can by
16125                    // definition not re-use the same process again, and it is
16126                    // good to avoid having whatever code was running in them
16127                    // left sitting around after no longer needed.
16128                    killUnneededProcessLocked(app, "isolated not needed");
16129                }
16130
16131                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16132                        && !app.killedByAm) {
16133                    numTrimming++;
16134                }
16135            }
16136        }
16137
16138        mNumServiceProcs = mNewNumServiceProcs;
16139
16140        // Now determine the memory trimming level of background processes.
16141        // Unfortunately we need to start at the back of the list to do this
16142        // properly.  We only do this if the number of background apps we
16143        // are managing to keep around is less than half the maximum we desire;
16144        // if we are keeping a good number around, we'll let them use whatever
16145        // memory they want.
16146        final int numCachedAndEmpty = numCached + numEmpty;
16147        int memFactor;
16148        if (numCached <= ProcessList.TRIM_CACHED_APPS
16149                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16150            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16151                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16152            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16153                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16154            } else {
16155                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16156            }
16157        } else {
16158            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16159        }
16160        // We always allow the memory level to go up (better).  We only allow it to go
16161        // down if we are in a state where that is allowed, *and* the total number of processes
16162        // has gone down since last time.
16163        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16164                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16165                + " last=" + mLastNumProcesses);
16166        if (memFactor > mLastMemoryLevel) {
16167            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16168                memFactor = mLastMemoryLevel;
16169                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16170            }
16171        }
16172        mLastMemoryLevel = memFactor;
16173        mLastNumProcesses = mLruProcesses.size();
16174        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16175        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16176        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16177            if (mLowRamStartTime == 0) {
16178                mLowRamStartTime = now;
16179            }
16180            int step = 0;
16181            int fgTrimLevel;
16182            switch (memFactor) {
16183                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16184                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16185                    break;
16186                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16187                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16188                    break;
16189                default:
16190                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16191                    break;
16192            }
16193            int factor = numTrimming/3;
16194            int minFactor = 2;
16195            if (mHomeProcess != null) minFactor++;
16196            if (mPreviousProcess != null) minFactor++;
16197            if (factor < minFactor) factor = minFactor;
16198            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16199            for (int i=N-1; i>=0; i--) {
16200                ProcessRecord app = mLruProcesses.get(i);
16201                if (allChanged || app.procStateChanged) {
16202                    setProcessTrackerState(app, trackerMemFactor, now);
16203                    app.procStateChanged = false;
16204                }
16205                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16206                        && !app.killedByAm) {
16207                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16208                        try {
16209                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16210                                    "Trimming memory of " + app.processName
16211                                    + " to " + curLevel);
16212                            app.thread.scheduleTrimMemory(curLevel);
16213                        } catch (RemoteException e) {
16214                        }
16215                        if (false) {
16216                            // For now we won't do this; our memory trimming seems
16217                            // to be good enough at this point that destroying
16218                            // activities causes more harm than good.
16219                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16220                                    && app != mHomeProcess && app != mPreviousProcess) {
16221                                // Need to do this on its own message because the stack may not
16222                                // be in a consistent state at this point.
16223                                // For these apps we will also finish their activities
16224                                // to help them free memory.
16225                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16226                            }
16227                        }
16228                    }
16229                    app.trimMemoryLevel = curLevel;
16230                    step++;
16231                    if (step >= factor) {
16232                        step = 0;
16233                        switch (curLevel) {
16234                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16235                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16236                                break;
16237                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16238                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16239                                break;
16240                        }
16241                    }
16242                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16243                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16244                            && app.thread != null) {
16245                        try {
16246                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16247                                    "Trimming memory of heavy-weight " + app.processName
16248                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16249                            app.thread.scheduleTrimMemory(
16250                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16251                        } catch (RemoteException e) {
16252                        }
16253                    }
16254                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16255                } else {
16256                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16257                            || app.systemNoUi) && app.pendingUiClean) {
16258                        // If this application is now in the background and it
16259                        // had done UI, then give it the special trim level to
16260                        // have it free UI resources.
16261                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16262                        if (app.trimMemoryLevel < level && app.thread != null) {
16263                            try {
16264                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16265                                        "Trimming memory of bg-ui " + app.processName
16266                                        + " to " + level);
16267                                app.thread.scheduleTrimMemory(level);
16268                            } catch (RemoteException e) {
16269                            }
16270                        }
16271                        app.pendingUiClean = false;
16272                    }
16273                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16274                        try {
16275                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16276                                    "Trimming memory of fg " + app.processName
16277                                    + " to " + fgTrimLevel);
16278                            app.thread.scheduleTrimMemory(fgTrimLevel);
16279                        } catch (RemoteException e) {
16280                        }
16281                    }
16282                    app.trimMemoryLevel = fgTrimLevel;
16283                }
16284            }
16285        } else {
16286            if (mLowRamStartTime != 0) {
16287                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16288                mLowRamStartTime = 0;
16289            }
16290            for (int i=N-1; i>=0; i--) {
16291                ProcessRecord app = mLruProcesses.get(i);
16292                if (allChanged || app.procStateChanged) {
16293                    setProcessTrackerState(app, trackerMemFactor, now);
16294                    app.procStateChanged = false;
16295                }
16296                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16297                        || app.systemNoUi) && app.pendingUiClean) {
16298                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16299                            && app.thread != null) {
16300                        try {
16301                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16302                                    "Trimming memory of ui hidden " + app.processName
16303                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16304                            app.thread.scheduleTrimMemory(
16305                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16306                        } catch (RemoteException e) {
16307                        }
16308                    }
16309                    app.pendingUiClean = false;
16310                }
16311                app.trimMemoryLevel = 0;
16312            }
16313        }
16314
16315        if (mAlwaysFinishActivities) {
16316            // Need to do this on its own message because the stack may not
16317            // be in a consistent state at this point.
16318            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16319        }
16320
16321        if (allChanged) {
16322            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16323        }
16324
16325        if (mProcessStats.shouldWriteNowLocked(now)) {
16326            mHandler.post(new Runnable() {
16327                @Override public void run() {
16328                    synchronized (ActivityManagerService.this) {
16329                        mProcessStats.writeStateAsyncLocked();
16330                    }
16331                }
16332            });
16333        }
16334
16335        if (DEBUG_OOM_ADJ) {
16336            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16337        }
16338    }
16339
16340    final void trimApplications() {
16341        synchronized (this) {
16342            int i;
16343
16344            // First remove any unused application processes whose package
16345            // has been removed.
16346            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16347                final ProcessRecord app = mRemovedProcesses.get(i);
16348                if (app.activities.size() == 0
16349                        && app.curReceiver == null && app.services.size() == 0) {
16350                    Slog.i(
16351                        TAG, "Exiting empty application process "
16352                        + app.processName + " ("
16353                        + (app.thread != null ? app.thread.asBinder() : null)
16354                        + ")\n");
16355                    if (app.pid > 0 && app.pid != MY_PID) {
16356                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16357                                app.processName, app.setAdj, "empty");
16358                        app.killedByAm = true;
16359                        Process.killProcessQuiet(app.pid);
16360                    } else {
16361                        try {
16362                            app.thread.scheduleExit();
16363                        } catch (Exception e) {
16364                            // Ignore exceptions.
16365                        }
16366                    }
16367                    cleanUpApplicationRecordLocked(app, false, true, -1);
16368                    mRemovedProcesses.remove(i);
16369
16370                    if (app.persistent) {
16371                        if (app.persistent) {
16372                            addAppLocked(app.info, false, null /* ABI override */);
16373                        }
16374                    }
16375                }
16376            }
16377
16378            // Now update the oom adj for all processes.
16379            updateOomAdjLocked();
16380        }
16381    }
16382
16383    /** This method sends the specified signal to each of the persistent apps */
16384    public void signalPersistentProcesses(int sig) throws RemoteException {
16385        if (sig != Process.SIGNAL_USR1) {
16386            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16387        }
16388
16389        synchronized (this) {
16390            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16391                    != PackageManager.PERMISSION_GRANTED) {
16392                throw new SecurityException("Requires permission "
16393                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16394            }
16395
16396            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16397                ProcessRecord r = mLruProcesses.get(i);
16398                if (r.thread != null && r.persistent) {
16399                    Process.sendSignal(r.pid, sig);
16400                }
16401            }
16402        }
16403    }
16404
16405    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16406        if (proc == null || proc == mProfileProc) {
16407            proc = mProfileProc;
16408            path = mProfileFile;
16409            profileType = mProfileType;
16410            clearProfilerLocked();
16411        }
16412        if (proc == null) {
16413            return;
16414        }
16415        try {
16416            proc.thread.profilerControl(false, path, null, profileType);
16417        } catch (RemoteException e) {
16418            throw new IllegalStateException("Process disappeared");
16419        }
16420    }
16421
16422    private void clearProfilerLocked() {
16423        if (mProfileFd != null) {
16424            try {
16425                mProfileFd.close();
16426            } catch (IOException e) {
16427            }
16428        }
16429        mProfileApp = null;
16430        mProfileProc = null;
16431        mProfileFile = null;
16432        mProfileType = 0;
16433        mAutoStopProfiler = false;
16434    }
16435
16436    public boolean profileControl(String process, int userId, boolean start,
16437            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16438
16439        try {
16440            synchronized (this) {
16441                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16442                // its own permission.
16443                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16444                        != PackageManager.PERMISSION_GRANTED) {
16445                    throw new SecurityException("Requires permission "
16446                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16447                }
16448
16449                if (start && fd == null) {
16450                    throw new IllegalArgumentException("null fd");
16451                }
16452
16453                ProcessRecord proc = null;
16454                if (process != null) {
16455                    proc = findProcessLocked(process, userId, "profileControl");
16456                }
16457
16458                if (start && (proc == null || proc.thread == null)) {
16459                    throw new IllegalArgumentException("Unknown process: " + process);
16460                }
16461
16462                if (start) {
16463                    stopProfilerLocked(null, null, 0);
16464                    setProfileApp(proc.info, proc.processName, path, fd, false);
16465                    mProfileProc = proc;
16466                    mProfileType = profileType;
16467                    try {
16468                        fd = fd.dup();
16469                    } catch (IOException e) {
16470                        fd = null;
16471                    }
16472                    proc.thread.profilerControl(start, path, fd, profileType);
16473                    fd = null;
16474                    mProfileFd = null;
16475                } else {
16476                    stopProfilerLocked(proc, path, profileType);
16477                    if (fd != null) {
16478                        try {
16479                            fd.close();
16480                        } catch (IOException e) {
16481                        }
16482                    }
16483                }
16484
16485                return true;
16486            }
16487        } catch (RemoteException e) {
16488            throw new IllegalStateException("Process disappeared");
16489        } finally {
16490            if (fd != null) {
16491                try {
16492                    fd.close();
16493                } catch (IOException e) {
16494                }
16495            }
16496        }
16497    }
16498
16499    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16500        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16501                userId, true, true, callName, null);
16502        ProcessRecord proc = null;
16503        try {
16504            int pid = Integer.parseInt(process);
16505            synchronized (mPidsSelfLocked) {
16506                proc = mPidsSelfLocked.get(pid);
16507            }
16508        } catch (NumberFormatException e) {
16509        }
16510
16511        if (proc == null) {
16512            ArrayMap<String, SparseArray<ProcessRecord>> all
16513                    = mProcessNames.getMap();
16514            SparseArray<ProcessRecord> procs = all.get(process);
16515            if (procs != null && procs.size() > 0) {
16516                proc = procs.valueAt(0);
16517                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16518                    for (int i=1; i<procs.size(); i++) {
16519                        ProcessRecord thisProc = procs.valueAt(i);
16520                        if (thisProc.userId == userId) {
16521                            proc = thisProc;
16522                            break;
16523                        }
16524                    }
16525                }
16526            }
16527        }
16528
16529        return proc;
16530    }
16531
16532    public boolean dumpHeap(String process, int userId, boolean managed,
16533            String path, ParcelFileDescriptor fd) throws RemoteException {
16534
16535        try {
16536            synchronized (this) {
16537                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16538                // its own permission (same as profileControl).
16539                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16540                        != PackageManager.PERMISSION_GRANTED) {
16541                    throw new SecurityException("Requires permission "
16542                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16543                }
16544
16545                if (fd == null) {
16546                    throw new IllegalArgumentException("null fd");
16547                }
16548
16549                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16550                if (proc == null || proc.thread == null) {
16551                    throw new IllegalArgumentException("Unknown process: " + process);
16552                }
16553
16554                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16555                if (!isDebuggable) {
16556                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16557                        throw new SecurityException("Process not debuggable: " + proc);
16558                    }
16559                }
16560
16561                proc.thread.dumpHeap(managed, path, fd);
16562                fd = null;
16563                return true;
16564            }
16565        } catch (RemoteException e) {
16566            throw new IllegalStateException("Process disappeared");
16567        } finally {
16568            if (fd != null) {
16569                try {
16570                    fd.close();
16571                } catch (IOException e) {
16572                }
16573            }
16574        }
16575    }
16576
16577    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16578    public void monitor() {
16579        synchronized (this) { }
16580    }
16581
16582    void onCoreSettingsChange(Bundle settings) {
16583        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16584            ProcessRecord processRecord = mLruProcesses.get(i);
16585            try {
16586                if (processRecord.thread != null) {
16587                    processRecord.thread.setCoreSettings(settings);
16588                }
16589            } catch (RemoteException re) {
16590                /* ignore */
16591            }
16592        }
16593    }
16594
16595    // Multi-user methods
16596
16597    /**
16598     * Start user, if its not already running, but don't bring it to foreground.
16599     */
16600    @Override
16601    public boolean startUserInBackground(final int userId) {
16602        return startUser(userId, /* foreground */ false);
16603    }
16604
16605    /**
16606     * Refreshes the list of users related to the current user when either a
16607     * user switch happens or when a new related user is started in the
16608     * background.
16609     */
16610    private void updateCurrentProfileIdsLocked() {
16611        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16612                mCurrentUserId, false /* enabledOnly */);
16613        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16614        for (int i = 0; i < currentProfileIds.length; i++) {
16615            currentProfileIds[i] = profiles.get(i).id;
16616        }
16617        mCurrentProfileIds = currentProfileIds;
16618    }
16619
16620    private Set getProfileIdsLocked(int userId) {
16621        Set userIds = new HashSet<Integer>();
16622        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16623                userId, false /* enabledOnly */);
16624        for (UserInfo user : profiles) {
16625            userIds.add(Integer.valueOf(user.id));
16626        }
16627        return userIds;
16628    }
16629
16630    @Override
16631    public boolean switchUser(final int userId) {
16632        return startUser(userId, /* foregound */ true);
16633    }
16634
16635    private boolean startUser(final int userId, boolean foreground) {
16636        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16637                != PackageManager.PERMISSION_GRANTED) {
16638            String msg = "Permission Denial: switchUser() from pid="
16639                    + Binder.getCallingPid()
16640                    + ", uid=" + Binder.getCallingUid()
16641                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16642            Slog.w(TAG, msg);
16643            throw new SecurityException(msg);
16644        }
16645
16646        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16647
16648        final long ident = Binder.clearCallingIdentity();
16649        try {
16650            synchronized (this) {
16651                final int oldUserId = mCurrentUserId;
16652                if (oldUserId == userId) {
16653                    return true;
16654                }
16655
16656                mStackSupervisor.setLockTaskModeLocked(null);
16657
16658                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16659                if (userInfo == null) {
16660                    Slog.w(TAG, "No user info for user #" + userId);
16661                    return false;
16662                }
16663
16664                if (foreground) {
16665                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16666                            R.anim.screen_user_enter);
16667                }
16668
16669                boolean needStart = false;
16670
16671                // If the user we are switching to is not currently started, then
16672                // we need to start it now.
16673                if (mStartedUsers.get(userId) == null) {
16674                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16675                    updateStartedUserArrayLocked();
16676                    needStart = true;
16677                }
16678
16679                final Integer userIdInt = Integer.valueOf(userId);
16680                mUserLru.remove(userIdInt);
16681                mUserLru.add(userIdInt);
16682
16683                if (foreground) {
16684                    mCurrentUserId = userId;
16685                    updateCurrentProfileIdsLocked();
16686                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16687                    // Once the internal notion of the active user has switched, we lock the device
16688                    // with the option to show the user switcher on the keyguard.
16689                    mWindowManager.lockNow(null);
16690                } else {
16691                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16692                    updateCurrentProfileIdsLocked();
16693                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16694                    mUserLru.remove(currentUserIdInt);
16695                    mUserLru.add(currentUserIdInt);
16696                }
16697
16698                final UserStartedState uss = mStartedUsers.get(userId);
16699
16700                // Make sure user is in the started state.  If it is currently
16701                // stopping, we need to knock that off.
16702                if (uss.mState == UserStartedState.STATE_STOPPING) {
16703                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16704                    // so we can just fairly silently bring the user back from
16705                    // the almost-dead.
16706                    uss.mState = UserStartedState.STATE_RUNNING;
16707                    updateStartedUserArrayLocked();
16708                    needStart = true;
16709                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16710                    // This means ACTION_SHUTDOWN has been sent, so we will
16711                    // need to treat this as a new boot of the user.
16712                    uss.mState = UserStartedState.STATE_BOOTING;
16713                    updateStartedUserArrayLocked();
16714                    needStart = true;
16715                }
16716
16717                if (uss.mState == UserStartedState.STATE_BOOTING) {
16718                    // Booting up a new user, need to tell system services about it.
16719                    // Note that this is on the same handler as scheduling of broadcasts,
16720                    // which is important because it needs to go first.
16721                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16722                }
16723
16724                if (foreground) {
16725                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16726                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16727                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16728                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16729                            oldUserId, userId, uss));
16730                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16731                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16732                }
16733
16734                if (needStart) {
16735                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16736                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16737                            | Intent.FLAG_RECEIVER_FOREGROUND);
16738                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16739                    broadcastIntentLocked(null, null, intent,
16740                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16741                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16742                }
16743
16744                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16745                    if (userId != UserHandle.USER_OWNER) {
16746                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16747                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16748                        broadcastIntentLocked(null, null, intent, null,
16749                                new IIntentReceiver.Stub() {
16750                                    public void performReceive(Intent intent, int resultCode,
16751                                            String data, Bundle extras, boolean ordered,
16752                                            boolean sticky, int sendingUser) {
16753                                        userInitialized(uss, userId);
16754                                    }
16755                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16756                                true, false, MY_PID, Process.SYSTEM_UID,
16757                                userId);
16758                        uss.initializing = true;
16759                    } else {
16760                        getUserManagerLocked().makeInitialized(userInfo.id);
16761                    }
16762                }
16763
16764                if (foreground) {
16765                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16766                    if (homeInFront) {
16767                        startHomeActivityLocked(userId);
16768                    } else {
16769                        mStackSupervisor.resumeTopActivitiesLocked();
16770                    }
16771                    EventLogTags.writeAmSwitchUser(userId);
16772                    getUserManagerLocked().userForeground(userId);
16773                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16774                } else {
16775                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16776                }
16777
16778                if (needStart) {
16779                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16780                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16781                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16782                    broadcastIntentLocked(null, null, intent,
16783                            null, new IIntentReceiver.Stub() {
16784                                @Override
16785                                public void performReceive(Intent intent, int resultCode, String data,
16786                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16787                                        throws RemoteException {
16788                                }
16789                            }, 0, null, null,
16790                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16791                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16792                }
16793            }
16794        } finally {
16795            Binder.restoreCallingIdentity(ident);
16796        }
16797
16798        return true;
16799    }
16800
16801    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16802        long ident = Binder.clearCallingIdentity();
16803        try {
16804            Intent intent;
16805            if (oldUserId >= 0) {
16806                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16807                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16808                        | Intent.FLAG_RECEIVER_FOREGROUND);
16809                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16810                broadcastIntentLocked(null, null, intent,
16811                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16812                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16813            }
16814            if (newUserId >= 0) {
16815                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16816                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16817                        | Intent.FLAG_RECEIVER_FOREGROUND);
16818                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16819                broadcastIntentLocked(null, null, intent,
16820                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16821                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16822                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16823                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16824                        | Intent.FLAG_RECEIVER_FOREGROUND);
16825                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16826                broadcastIntentLocked(null, null, intent,
16827                        null, null, 0, null, null,
16828                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16829                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16830            }
16831        } finally {
16832            Binder.restoreCallingIdentity(ident);
16833        }
16834    }
16835
16836    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16837            final int newUserId) {
16838        final int N = mUserSwitchObservers.beginBroadcast();
16839        if (N > 0) {
16840            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16841                int mCount = 0;
16842                @Override
16843                public void sendResult(Bundle data) throws RemoteException {
16844                    synchronized (ActivityManagerService.this) {
16845                        if (mCurUserSwitchCallback == this) {
16846                            mCount++;
16847                            if (mCount == N) {
16848                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16849                            }
16850                        }
16851                    }
16852                }
16853            };
16854            synchronized (this) {
16855                uss.switching = true;
16856                mCurUserSwitchCallback = callback;
16857            }
16858            for (int i=0; i<N; i++) {
16859                try {
16860                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16861                            newUserId, callback);
16862                } catch (RemoteException e) {
16863                }
16864            }
16865        } else {
16866            synchronized (this) {
16867                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16868            }
16869        }
16870        mUserSwitchObservers.finishBroadcast();
16871    }
16872
16873    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16874        synchronized (this) {
16875            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16876            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16877        }
16878    }
16879
16880    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16881        mCurUserSwitchCallback = null;
16882        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16883        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16884                oldUserId, newUserId, uss));
16885    }
16886
16887    void userInitialized(UserStartedState uss, int newUserId) {
16888        completeSwitchAndInitalize(uss, newUserId, true, false);
16889    }
16890
16891    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16892        completeSwitchAndInitalize(uss, newUserId, false, true);
16893    }
16894
16895    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16896            boolean clearInitializing, boolean clearSwitching) {
16897        boolean unfrozen = false;
16898        synchronized (this) {
16899            if (clearInitializing) {
16900                uss.initializing = false;
16901                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16902            }
16903            if (clearSwitching) {
16904                uss.switching = false;
16905            }
16906            if (!uss.switching && !uss.initializing) {
16907                mWindowManager.stopFreezingScreen();
16908                unfrozen = true;
16909            }
16910        }
16911        if (unfrozen) {
16912            final int N = mUserSwitchObservers.beginBroadcast();
16913            for (int i=0; i<N; i++) {
16914                try {
16915                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16916                } catch (RemoteException e) {
16917                }
16918            }
16919            mUserSwitchObservers.finishBroadcast();
16920        }
16921    }
16922
16923    void scheduleStartProfilesLocked() {
16924        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16925            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16926                    DateUtils.SECOND_IN_MILLIS);
16927        }
16928    }
16929
16930    void startProfilesLocked() {
16931        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16932        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16933                mCurrentUserId, false /* enabledOnly */);
16934        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16935        for (UserInfo user : profiles) {
16936            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16937                    && user.id != mCurrentUserId) {
16938                toStart.add(user);
16939            }
16940        }
16941        final int n = toStart.size();
16942        int i = 0;
16943        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16944            startUserInBackground(toStart.get(i).id);
16945        }
16946        if (i < n) {
16947            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16948        }
16949    }
16950
16951    void finishUserBoot(UserStartedState uss) {
16952        synchronized (this) {
16953            if (uss.mState == UserStartedState.STATE_BOOTING
16954                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16955                uss.mState = UserStartedState.STATE_RUNNING;
16956                final int userId = uss.mHandle.getIdentifier();
16957                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16958                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16959                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16960                broadcastIntentLocked(null, null, intent,
16961                        null, null, 0, null, null,
16962                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16963                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16964            }
16965        }
16966    }
16967
16968    void finishUserSwitch(UserStartedState uss) {
16969        synchronized (this) {
16970            finishUserBoot(uss);
16971
16972            startProfilesLocked();
16973
16974            int num = mUserLru.size();
16975            int i = 0;
16976            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16977                Integer oldUserId = mUserLru.get(i);
16978                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16979                if (oldUss == null) {
16980                    // Shouldn't happen, but be sane if it does.
16981                    mUserLru.remove(i);
16982                    num--;
16983                    continue;
16984                }
16985                if (oldUss.mState == UserStartedState.STATE_STOPPING
16986                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16987                    // This user is already stopping, doesn't count.
16988                    num--;
16989                    i++;
16990                    continue;
16991                }
16992                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16993                    // Owner and current can't be stopped, but count as running.
16994                    i++;
16995                    continue;
16996                }
16997                // This is a user to be stopped.
16998                stopUserLocked(oldUserId, null);
16999                num--;
17000                i++;
17001            }
17002        }
17003    }
17004
17005    @Override
17006    public int stopUser(final int userId, final IStopUserCallback callback) {
17007        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17008                != PackageManager.PERMISSION_GRANTED) {
17009            String msg = "Permission Denial: switchUser() from pid="
17010                    + Binder.getCallingPid()
17011                    + ", uid=" + Binder.getCallingUid()
17012                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17013            Slog.w(TAG, msg);
17014            throw new SecurityException(msg);
17015        }
17016        if (userId <= 0) {
17017            throw new IllegalArgumentException("Can't stop primary user " + userId);
17018        }
17019        synchronized (this) {
17020            return stopUserLocked(userId, callback);
17021        }
17022    }
17023
17024    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17025        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17026        if (mCurrentUserId == userId) {
17027            return ActivityManager.USER_OP_IS_CURRENT;
17028        }
17029
17030        final UserStartedState uss = mStartedUsers.get(userId);
17031        if (uss == null) {
17032            // User is not started, nothing to do...  but we do need to
17033            // callback if requested.
17034            if (callback != null) {
17035                mHandler.post(new Runnable() {
17036                    @Override
17037                    public void run() {
17038                        try {
17039                            callback.userStopped(userId);
17040                        } catch (RemoteException e) {
17041                        }
17042                    }
17043                });
17044            }
17045            return ActivityManager.USER_OP_SUCCESS;
17046        }
17047
17048        if (callback != null) {
17049            uss.mStopCallbacks.add(callback);
17050        }
17051
17052        if (uss.mState != UserStartedState.STATE_STOPPING
17053                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17054            uss.mState = UserStartedState.STATE_STOPPING;
17055            updateStartedUserArrayLocked();
17056
17057            long ident = Binder.clearCallingIdentity();
17058            try {
17059                // We are going to broadcast ACTION_USER_STOPPING and then
17060                // once that is done send a final ACTION_SHUTDOWN and then
17061                // stop the user.
17062                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17063                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17064                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17065                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17066                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17067                // This is the result receiver for the final shutdown broadcast.
17068                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17069                    @Override
17070                    public void performReceive(Intent intent, int resultCode, String data,
17071                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17072                        finishUserStop(uss);
17073                    }
17074                };
17075                // This is the result receiver for the initial stopping broadcast.
17076                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17077                    @Override
17078                    public void performReceive(Intent intent, int resultCode, String data,
17079                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17080                        // On to the next.
17081                        synchronized (ActivityManagerService.this) {
17082                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17083                                // Whoops, we are being started back up.  Abort, abort!
17084                                return;
17085                            }
17086                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17087                        }
17088                        mSystemServiceManager.stopUser(userId);
17089                        broadcastIntentLocked(null, null, shutdownIntent,
17090                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17091                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17092                    }
17093                };
17094                // Kick things off.
17095                broadcastIntentLocked(null, null, stoppingIntent,
17096                        null, stoppingReceiver, 0, null, null,
17097                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17098                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17099            } finally {
17100                Binder.restoreCallingIdentity(ident);
17101            }
17102        }
17103
17104        return ActivityManager.USER_OP_SUCCESS;
17105    }
17106
17107    void finishUserStop(UserStartedState uss) {
17108        final int userId = uss.mHandle.getIdentifier();
17109        boolean stopped;
17110        ArrayList<IStopUserCallback> callbacks;
17111        synchronized (this) {
17112            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17113            if (mStartedUsers.get(userId) != uss) {
17114                stopped = false;
17115            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17116                stopped = false;
17117            } else {
17118                stopped = true;
17119                // User can no longer run.
17120                mStartedUsers.remove(userId);
17121                mUserLru.remove(Integer.valueOf(userId));
17122                updateStartedUserArrayLocked();
17123
17124                // Clean up all state and processes associated with the user.
17125                // Kill all the processes for the user.
17126                forceStopUserLocked(userId, "finish user");
17127            }
17128        }
17129
17130        for (int i=0; i<callbacks.size(); i++) {
17131            try {
17132                if (stopped) callbacks.get(i).userStopped(userId);
17133                else callbacks.get(i).userStopAborted(userId);
17134            } catch (RemoteException e) {
17135            }
17136        }
17137
17138        if (stopped) {
17139            mSystemServiceManager.cleanupUser(userId);
17140            synchronized (this) {
17141                mStackSupervisor.removeUserLocked(userId);
17142            }
17143        }
17144    }
17145
17146    @Override
17147    public UserInfo getCurrentUser() {
17148        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17149                != PackageManager.PERMISSION_GRANTED) && (
17150                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17151                != PackageManager.PERMISSION_GRANTED)) {
17152            String msg = "Permission Denial: getCurrentUser() from pid="
17153                    + Binder.getCallingPid()
17154                    + ", uid=" + Binder.getCallingUid()
17155                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17156            Slog.w(TAG, msg);
17157            throw new SecurityException(msg);
17158        }
17159        synchronized (this) {
17160            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17161        }
17162    }
17163
17164    int getCurrentUserIdLocked() {
17165        return mCurrentUserId;
17166    }
17167
17168    @Override
17169    public boolean isUserRunning(int userId, boolean orStopped) {
17170        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17171                != PackageManager.PERMISSION_GRANTED) {
17172            String msg = "Permission Denial: isUserRunning() from pid="
17173                    + Binder.getCallingPid()
17174                    + ", uid=" + Binder.getCallingUid()
17175                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17176            Slog.w(TAG, msg);
17177            throw new SecurityException(msg);
17178        }
17179        synchronized (this) {
17180            return isUserRunningLocked(userId, orStopped);
17181        }
17182    }
17183
17184    boolean isUserRunningLocked(int userId, boolean orStopped) {
17185        UserStartedState state = mStartedUsers.get(userId);
17186        if (state == null) {
17187            return false;
17188        }
17189        if (orStopped) {
17190            return true;
17191        }
17192        return state.mState != UserStartedState.STATE_STOPPING
17193                && state.mState != UserStartedState.STATE_SHUTDOWN;
17194    }
17195
17196    @Override
17197    public int[] getRunningUserIds() {
17198        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17199                != PackageManager.PERMISSION_GRANTED) {
17200            String msg = "Permission Denial: isUserRunning() from pid="
17201                    + Binder.getCallingPid()
17202                    + ", uid=" + Binder.getCallingUid()
17203                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17204            Slog.w(TAG, msg);
17205            throw new SecurityException(msg);
17206        }
17207        synchronized (this) {
17208            return mStartedUserArray;
17209        }
17210    }
17211
17212    private void updateStartedUserArrayLocked() {
17213        int num = 0;
17214        for (int i=0; i<mStartedUsers.size();  i++) {
17215            UserStartedState uss = mStartedUsers.valueAt(i);
17216            // This list does not include stopping users.
17217            if (uss.mState != UserStartedState.STATE_STOPPING
17218                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17219                num++;
17220            }
17221        }
17222        mStartedUserArray = new int[num];
17223        num = 0;
17224        for (int i=0; i<mStartedUsers.size();  i++) {
17225            UserStartedState uss = mStartedUsers.valueAt(i);
17226            if (uss.mState != UserStartedState.STATE_STOPPING
17227                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17228                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17229                num++;
17230            }
17231        }
17232    }
17233
17234    @Override
17235    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17236        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17237                != PackageManager.PERMISSION_GRANTED) {
17238            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17239                    + Binder.getCallingPid()
17240                    + ", uid=" + Binder.getCallingUid()
17241                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17242            Slog.w(TAG, msg);
17243            throw new SecurityException(msg);
17244        }
17245
17246        mUserSwitchObservers.register(observer);
17247    }
17248
17249    @Override
17250    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17251        mUserSwitchObservers.unregister(observer);
17252    }
17253
17254    private boolean userExists(int userId) {
17255        if (userId == 0) {
17256            return true;
17257        }
17258        UserManagerService ums = getUserManagerLocked();
17259        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17260    }
17261
17262    int[] getUsersLocked() {
17263        UserManagerService ums = getUserManagerLocked();
17264        return ums != null ? ums.getUserIds() : new int[] { 0 };
17265    }
17266
17267    UserManagerService getUserManagerLocked() {
17268        if (mUserManager == null) {
17269            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17270            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17271        }
17272        return mUserManager;
17273    }
17274
17275    private int applyUserId(int uid, int userId) {
17276        return UserHandle.getUid(userId, uid);
17277    }
17278
17279    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17280        if (info == null) return null;
17281        ApplicationInfo newInfo = new ApplicationInfo(info);
17282        newInfo.uid = applyUserId(info.uid, userId);
17283        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17284                + info.packageName;
17285        return newInfo;
17286    }
17287
17288    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17289        if (aInfo == null
17290                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17291            return aInfo;
17292        }
17293
17294        ActivityInfo info = new ActivityInfo(aInfo);
17295        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17296        return info;
17297    }
17298
17299    private final class LocalService extends ActivityManagerInternal {
17300        @Override
17301        public void goingToSleep() {
17302            ActivityManagerService.this.goingToSleep();
17303        }
17304
17305        @Override
17306        public void wakingUp() {
17307            ActivityManagerService.this.wakingUp();
17308        }
17309    }
17310
17311    /**
17312     * An implementation of IAppTask, that allows an app to manage its own tasks via
17313     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17314     * only the process that calls getAppTasks() can call the AppTask methods.
17315     */
17316    class AppTaskImpl extends IAppTask.Stub {
17317        private int mTaskId;
17318        private int mCallingUid;
17319
17320        public AppTaskImpl(int taskId, int callingUid) {
17321            mTaskId = taskId;
17322            mCallingUid = callingUid;
17323        }
17324
17325        @Override
17326        public void finishAndRemoveTask() {
17327            // Ensure that we are called from the same process that created this AppTask
17328            if (mCallingUid != Binder.getCallingUid()) {
17329                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17330                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17331                return;
17332            }
17333
17334            synchronized (ActivityManagerService.this) {
17335                long origId = Binder.clearCallingIdentity();
17336                try {
17337                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17338                    if (tr != null) {
17339                        // Only kill the process if we are not a new document
17340                        int flags = tr.getBaseIntent().getFlags();
17341                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17342                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17343                        removeTaskByIdLocked(mTaskId,
17344                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17345                    }
17346                } finally {
17347                    Binder.restoreCallingIdentity(origId);
17348                }
17349            }
17350        }
17351
17352        @Override
17353        public ActivityManager.RecentTaskInfo getTaskInfo() {
17354            // Ensure that we are called from the same process that created this AppTask
17355            if (mCallingUid != Binder.getCallingUid()) {
17356                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17357                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17358                return null;
17359            }
17360
17361            synchronized (ActivityManagerService.this) {
17362                long origId = Binder.clearCallingIdentity();
17363                try {
17364                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17365                    if (tr != null) {
17366                        return createRecentTaskInfoFromTaskRecord(tr);
17367                    }
17368                } finally {
17369                    Binder.restoreCallingIdentity(origId);
17370                }
17371                return null;
17372            }
17373        }
17374    }
17375}
17376