ActivityManagerService.java revision 4b9d79c30eccb61645d98a4f0d49b7769e8c7ccc
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
274
275    // Amount of time after a call to stopAppSwitches() during which we will
276    // prevent further untrusted switches from happening.
277    static final long APP_SWITCH_DELAY_TIME = 5*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real.
281    static final int PROC_START_TIMEOUT = 10*1000;
282
283    // How long we wait for a launched process to attach to the activity manager
284    // before we decide it's never going to come up for real, when the process was
285    // started with a wrapper for instrumentation (such as Valgrind) because it
286    // could take much longer than usual.
287    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
288
289    // How long to wait after going idle before forcing apps to GC.
290    static final int GC_TIMEOUT = 5*1000;
291
292    // The minimum amount of time between successive GC requests for a process.
293    static final int GC_MIN_INTERVAL = 60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process.
296    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process
299    // when the request is due to the memory state being lowered.
300    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
301
302    // The rate at which we check for apps using excessive power -- 15 mins.
303    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on wake locks to start killing things.
307    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // The minimum sample duration we will allow before deciding we have
310    // enough data on CPU usage to start killing things.
311    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
312
313    // How long we allow a receiver to run before giving up on it.
314    static final int BROADCAST_FG_TIMEOUT = 10*1000;
315    static final int BROADCAST_BG_TIMEOUT = 60*1000;
316
317    // How long we wait until we timeout on key dispatching.
318    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
319
320    // How long we wait until we timeout on key dispatching during instrumentation.
321    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
322
323    // Amount of time we wait for observers to handle a user switch before
324    // giving up on them and unfreezing the screen.
325    static final int USER_SWITCH_TIMEOUT = 2*1000;
326
327    // Maximum number of users we allow to be running at a time.
328    static final int MAX_RUNNING_USERS = 3;
329
330    // How long to wait in getAssistContextExtras for the activity and foreground services
331    // to respond with the result.
332    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
333
334    // Maximum number of persisted Uri grants a package is allowed
335    static final int MAX_PERSISTED_URI_GRANTS = 128;
336
337    static final int MY_PID = Process.myPid();
338
339    static final String[] EMPTY_STRING_ARRAY = new String[0];
340
341    // How many bytes to write into the dropbox log before truncating
342    static final int DROPBOX_MAX_SIZE = 256 * 1024;
343
344    /** All system services */
345    SystemServiceManager mSystemServiceManager;
346
347    /** Run all ActivityStacks through this */
348    ActivityStackSupervisor mStackSupervisor;
349
350    public IntentFirewall mIntentFirewall;
351
352    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
353    // default actuion automatically.  Important for devices without direct input
354    // devices.
355    private boolean mShowDialogs = true;
356
357    /**
358     * Description of a request to start a new activity, which has been held
359     * due to app switches being disabled.
360     */
361    static class PendingActivityLaunch {
362        final ActivityRecord r;
363        final ActivityRecord sourceRecord;
364        final int startFlags;
365        final ActivityStack stack;
366
367        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
368                int _startFlags, ActivityStack _stack) {
369            r = _r;
370            sourceRecord = _sourceRecord;
371            startFlags = _startFlags;
372            stack = _stack;
373        }
374    }
375
376    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
377            = new ArrayList<PendingActivityLaunch>();
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414
415    public class PendingAssistExtras extends Binder implements Runnable {
416        public final ActivityRecord activity;
417        public boolean haveResult = false;
418        public Bundle result = null;
419        public PendingAssistExtras(ActivityRecord _activity) {
420            activity = _activity;
421        }
422        @Override
423        public void run() {
424            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
425            synchronized (this) {
426                haveResult = true;
427                notifyAll();
428            }
429        }
430    }
431
432    final ArrayList<PendingAssistExtras> mPendingAssistExtras
433            = new ArrayList<PendingAssistExtras>();
434
435    /**
436     * Process management.
437     */
438    final ProcessList mProcessList = new ProcessList();
439
440    /**
441     * All of the applications we currently have running organized by name.
442     * The keys are strings of the application package name (as
443     * returned by the package manager), and the keys are ApplicationRecord
444     * objects.
445     */
446    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
447
448    /**
449     * Tracking long-term execution of processes to look for abuse and other
450     * bad app behavior.
451     */
452    final ProcessStatsService mProcessStats;
453
454    /**
455     * The currently running isolated processes.
456     */
457    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
458
459    /**
460     * Counter for assigning isolated process uids, to avoid frequently reusing the
461     * same ones.
462     */
463    int mNextIsolatedProcessUid = 0;
464
465    /**
466     * The currently running heavy-weight process, if any.
467     */
468    ProcessRecord mHeavyWeightProcess = null;
469
470    /**
471     * The last time that various processes have crashed.
472     */
473    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
474
475    /**
476     * Information about a process that is currently marked as bad.
477     */
478    static final class BadProcessInfo {
479        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
480            this.time = time;
481            this.shortMsg = shortMsg;
482            this.longMsg = longMsg;
483            this.stack = stack;
484        }
485
486        final long time;
487        final String shortMsg;
488        final String longMsg;
489        final String stack;
490    }
491
492    /**
493     * Set of applications that we consider to be bad, and will reject
494     * incoming broadcasts from (which the user has no control over).
495     * Processes are added to this set when they have crashed twice within
496     * a minimum amount of time; they are removed from it when they are
497     * later restarted (hopefully due to some user action).  The value is the
498     * time it was added to the list.
499     */
500    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
501
502    /**
503     * All of the processes we currently have running organized by pid.
504     * The keys are the pid running the application.
505     *
506     * <p>NOTE: This object is protected by its own lock, NOT the global
507     * activity manager lock!
508     */
509    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
510
511    /**
512     * All of the processes that have been forced to be foreground.  The key
513     * is the pid of the caller who requested it (we hold a death
514     * link on it).
515     */
516    abstract class ForegroundToken implements IBinder.DeathRecipient {
517        int pid;
518        IBinder token;
519    }
520    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
521
522    /**
523     * List of records for processes that someone had tried to start before the
524     * system was ready.  We don't start them at that point, but ensure they
525     * are started by the time booting is complete.
526     */
527    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
528
529    /**
530     * List of persistent applications that are in the process
531     * of being started.
532     */
533    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
534
535    /**
536     * Processes that are being forcibly torn down.
537     */
538    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
539
540    /**
541     * List of running applications, sorted by recent usage.
542     * The first entry in the list is the least recently used.
543     */
544    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
545
546    /**
547     * Where in mLruProcesses that the processes hosting activities start.
548     */
549    int mLruProcessActivityStart = 0;
550
551    /**
552     * Where in mLruProcesses that the processes hosting services start.
553     * This is after (lower index) than mLruProcessesActivityStart.
554     */
555    int mLruProcessServiceStart = 0;
556
557    /**
558     * List of processes that should gc as soon as things are idle.
559     */
560    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
561
562    /**
563     * Processes we want to collect PSS data from.
564     */
565    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Last time we requested PSS data of all processes.
569     */
570    long mLastFullPssTime = SystemClock.uptimeMillis();
571
572    /**
573     * This is the process holding what we currently consider to be
574     * the "home" activity.
575     */
576    ProcessRecord mHomeProcess;
577
578    /**
579     * This is the process holding the activity the user last visited that
580     * is in a different process from the one they are currently in.
581     */
582    ProcessRecord mPreviousProcess;
583
584    /**
585     * The time at which the previous process was last visible.
586     */
587    long mPreviousProcessVisibleTime;
588
589    /**
590     * Which uses have been started, so are allowed to run code.
591     */
592    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
593
594    /**
595     * LRU list of history of current users.  Most recently current is at the end.
596     */
597    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
598
599    /**
600     * Constant array of the users that are currently started.
601     */
602    int[] mStartedUserArray = new int[] { 0 };
603
604    /**
605     * Registered observers of the user switching mechanics.
606     */
607    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
608            = new RemoteCallbackList<IUserSwitchObserver>();
609
610    /**
611     * Currently active user switch.
612     */
613    Object mCurUserSwitchCallback;
614
615    /**
616     * Packages that the user has asked to have run in screen size
617     * compatibility mode instead of filling the screen.
618     */
619    final CompatModePackages mCompatModePackages;
620
621    /**
622     * Set of IntentSenderRecord objects that are currently active.
623     */
624    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
625            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
626
627    /**
628     * Fingerprints (hashCode()) of stack traces that we've
629     * already logged DropBox entries for.  Guarded by itself.  If
630     * something (rogue user app) forces this over
631     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
632     */
633    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
634    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
635
636    /**
637     * Strict Mode background batched logging state.
638     *
639     * The string buffer is guarded by itself, and its lock is also
640     * used to determine if another batched write is already
641     * in-flight.
642     */
643    private final StringBuilder mStrictModeBuffer = new StringBuilder();
644
645    /**
646     * Keeps track of all IIntentReceivers that have been registered for
647     * broadcasts.  Hash keys are the receiver IBinder, hash value is
648     * a ReceiverList.
649     */
650    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
651            new HashMap<IBinder, ReceiverList>();
652
653    /**
654     * Resolver for broadcast intents to registered receivers.
655     * Holds BroadcastFilter (subclass of IntentFilter).
656     */
657    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
658            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
659        @Override
660        protected boolean allowFilterResult(
661                BroadcastFilter filter, List<BroadcastFilter> dest) {
662            IBinder target = filter.receiverList.receiver.asBinder();
663            for (int i=dest.size()-1; i>=0; i--) {
664                if (dest.get(i).receiverList.receiver.asBinder() == target) {
665                    return false;
666                }
667            }
668            return true;
669        }
670
671        @Override
672        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
673            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
674                    || userId == filter.owningUserId) {
675                return super.newResult(filter, match, userId);
676            }
677            return null;
678        }
679
680        @Override
681        protected BroadcastFilter[] newArray(int size) {
682            return new BroadcastFilter[size];
683        }
684
685        @Override
686        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
687            return packageName.equals(filter.packageName);
688        }
689    };
690
691    /**
692     * State of all active sticky broadcasts per user.  Keys are the action of the
693     * sticky Intent, values are an ArrayList of all broadcasted intents with
694     * that action (which should usually be one).  The SparseArray is keyed
695     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
696     * for stickies that are sent to all users.
697     */
698    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
699            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
700
701    final ActiveServices mServices;
702
703    /**
704     * Backup/restore process management
705     */
706    String mBackupAppName = null;
707    BackupRecord mBackupTarget = null;
708
709    final ProviderMap mProviderMap;
710
711    /**
712     * List of content providers who have clients waiting for them.  The
713     * application is currently being launched and the provider will be
714     * removed from this list once it is published.
715     */
716    final ArrayList<ContentProviderRecord> mLaunchingProviders
717            = new ArrayList<ContentProviderRecord>();
718
719    /**
720     * File storing persisted {@link #mGrantedUriPermissions}.
721     */
722    private final AtomicFile mGrantFile;
723
724    /** XML constants used in {@link #mGrantFile} */
725    private static final String TAG_URI_GRANTS = "uri-grants";
726    private static final String TAG_URI_GRANT = "uri-grant";
727    private static final String ATTR_USER_HANDLE = "userHandle";
728    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
729    private static final String ATTR_TARGET_USER_ID = "targetUserId";
730    private static final String ATTR_SOURCE_PKG = "sourcePkg";
731    private static final String ATTR_TARGET_PKG = "targetPkg";
732    private static final String ATTR_URI = "uri";
733    private static final String ATTR_MODE_FLAGS = "modeFlags";
734    private static final String ATTR_CREATED_TIME = "createdTime";
735    private static final String ATTR_PREFIX = "prefix";
736
737    /**
738     * Global set of specific {@link Uri} permissions that have been granted.
739     * This optimized lookup structure maps from {@link UriPermission#targetUid}
740     * to {@link UriPermission#uri} to {@link UriPermission}.
741     */
742    @GuardedBy("this")
743    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
744            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
745
746    public static class GrantUri {
747        public final int sourceUserId;
748        public final Uri uri;
749        public boolean prefix;
750
751        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
752            this.sourceUserId = sourceUserId;
753            this.uri = uri;
754            this.prefix = prefix;
755        }
756
757        @Override
758        public int hashCode() {
759            return toString().hashCode();
760        }
761
762        @Override
763        public boolean equals(Object o) {
764            if (o instanceof GrantUri) {
765                GrantUri other = (GrantUri) o;
766                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
767                        && prefix == other.prefix;
768            }
769            return false;
770        }
771
772        @Override
773        public String toString() {
774            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
775            if (prefix) result += " [prefix]";
776            return result;
777        }
778
779        public String toSafeString() {
780            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
781            if (prefix) result += " [prefix]";
782            return result;
783        }
784
785        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
786            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
787                    ContentProvider.getUriWithoutUserId(uri), false);
788        }
789    }
790
791    CoreSettingsObserver mCoreSettingsObserver;
792
793    /**
794     * Thread-local storage used to carry caller permissions over through
795     * indirect content-provider access.
796     */
797    private class Identity {
798        public int pid;
799        public int uid;
800
801        Identity(int _pid, int _uid) {
802            pid = _pid;
803            uid = _uid;
804        }
805    }
806
807    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
808
809    /**
810     * All information we have collected about the runtime performance of
811     * any user id that can impact battery performance.
812     */
813    final BatteryStatsService mBatteryStatsService;
814
815    /**
816     * Information about component usage
817     */
818    final UsageStatsService mUsageStatsService;
819
820    /**
821     * Information about and control over application operations
822     */
823    final AppOpsService mAppOpsService;
824
825    /**
826     * Save recent tasks information across reboots.
827     */
828    final TaskPersister mTaskPersister;
829
830    /**
831     * Current configuration information.  HistoryRecord objects are given
832     * a reference to this object to indicate which configuration they are
833     * currently running in, so this object must be kept immutable.
834     */
835    Configuration mConfiguration = new Configuration();
836
837    /**
838     * Current sequencing integer of the configuration, for skipping old
839     * configurations.
840     */
841    int mConfigurationSeq = 0;
842
843    /**
844     * Hardware-reported OpenGLES version.
845     */
846    final int GL_ES_VERSION;
847
848    /**
849     * List of initialization arguments to pass to all processes when binding applications to them.
850     * For example, references to the commonly used services.
851     */
852    HashMap<String, IBinder> mAppBindArgs;
853
854    /**
855     * Temporary to avoid allocations.  Protected by main lock.
856     */
857    final StringBuilder mStringBuilder = new StringBuilder(256);
858
859    /**
860     * Used to control how we initialize the service.
861     */
862    ComponentName mTopComponent;
863    String mTopAction = Intent.ACTION_MAIN;
864    String mTopData;
865    boolean mProcessesReady = false;
866    boolean mSystemReady = false;
867    boolean mBooting = false;
868    boolean mWaitingUpdate = false;
869    boolean mDidUpdate = false;
870    boolean mOnBattery = false;
871    boolean mLaunchWarningShown = false;
872
873    Context mContext;
874
875    int mFactoryTest;
876
877    boolean mCheckedForSetup;
878
879    /**
880     * The time at which we will allow normal application switches again,
881     * after a call to {@link #stopAppSwitches()}.
882     */
883    long mAppSwitchesAllowedTime;
884
885    /**
886     * This is set to true after the first switch after mAppSwitchesAllowedTime
887     * is set; any switches after that will clear the time.
888     */
889    boolean mDidAppSwitch;
890
891    /**
892     * Last time (in realtime) at which we checked for power usage.
893     */
894    long mLastPowerCheckRealtime;
895
896    /**
897     * Last time (in uptime) at which we checked for power usage.
898     */
899    long mLastPowerCheckUptime;
900
901    /**
902     * Set while we are wanting to sleep, to prevent any
903     * activities from being started/resumed.
904     */
905    private boolean mSleeping = false;
906
907    /**
908     * Set while we are running a voice interaction.  This overrides
909     * sleeping while it is active.
910     */
911    private boolean mRunningVoice = false;
912
913    /**
914     * State of external calls telling us if the device is asleep.
915     */
916    private boolean mWentToSleep = false;
917
918    /**
919     * State of external call telling us if the lock screen is shown.
920     */
921    private boolean mLockScreenShown = false;
922
923    /**
924     * Set if we are shutting down the system, similar to sleeping.
925     */
926    boolean mShuttingDown = false;
927
928    /**
929     * Current sequence id for oom_adj computation traversal.
930     */
931    int mAdjSeq = 0;
932
933    /**
934     * Current sequence id for process LRU updating.
935     */
936    int mLruSeq = 0;
937
938    /**
939     * Keep track of the non-cached/empty process we last found, to help
940     * determine how to distribute cached/empty processes next time.
941     */
942    int mNumNonCachedProcs = 0;
943
944    /**
945     * Keep track of the number of cached hidden procs, to balance oom adj
946     * distribution between those and empty procs.
947     */
948    int mNumCachedHiddenProcs = 0;
949
950    /**
951     * Keep track of the number of service processes we last found, to
952     * determine on the next iteration which should be B services.
953     */
954    int mNumServiceProcs = 0;
955    int mNewNumAServiceProcs = 0;
956    int mNewNumServiceProcs = 0;
957
958    /**
959     * Allow the current computed overall memory level of the system to go down?
960     * This is set to false when we are killing processes for reasons other than
961     * memory management, so that the now smaller process list will not be taken as
962     * an indication that memory is tighter.
963     */
964    boolean mAllowLowerMemLevel = false;
965
966    /**
967     * The last computed memory level, for holding when we are in a state that
968     * processes are going away for other reasons.
969     */
970    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
971
972    /**
973     * The last total number of process we have, to determine if changes actually look
974     * like a shrinking number of process due to lower RAM.
975     */
976    int mLastNumProcesses;
977
978    /**
979     * The uptime of the last time we performed idle maintenance.
980     */
981    long mLastIdleTime = SystemClock.uptimeMillis();
982
983    /**
984     * Total time spent with RAM that has been added in the past since the last idle time.
985     */
986    long mLowRamTimeSinceLastIdle = 0;
987
988    /**
989     * If RAM is currently low, when that horrible situation started.
990     */
991    long mLowRamStartTime = 0;
992
993    /**
994     * For reporting to battery stats the current top application.
995     */
996    private String mCurResumedPackage = null;
997    private int mCurResumedUid = -1;
998
999    /**
1000     * For reporting to battery stats the apps currently running foreground
1001     * service.  The ProcessMap is package/uid tuples; each of these contain
1002     * an array of the currently foreground processes.
1003     */
1004    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1005            = new ProcessMap<ArrayList<ProcessRecord>>();
1006
1007    /**
1008     * This is set if we had to do a delayed dexopt of an app before launching
1009     * it, to increase the ANR timeouts in that case.
1010     */
1011    boolean mDidDexOpt;
1012
1013    /**
1014     * Set if the systemServer made a call to enterSafeMode.
1015     */
1016    boolean mSafeMode;
1017
1018    String mDebugApp = null;
1019    boolean mWaitForDebugger = false;
1020    boolean mDebugTransient = false;
1021    String mOrigDebugApp = null;
1022    boolean mOrigWaitForDebugger = false;
1023    boolean mAlwaysFinishActivities = false;
1024    IActivityController mController = null;
1025    String mProfileApp = null;
1026    ProcessRecord mProfileProc = null;
1027    String mProfileFile;
1028    ParcelFileDescriptor mProfileFd;
1029    int mProfileType = 0;
1030    boolean mAutoStopProfiler = false;
1031    String mOpenGlTraceApp = null;
1032
1033    static class ProcessChangeItem {
1034        static final int CHANGE_ACTIVITIES = 1<<0;
1035        static final int CHANGE_PROCESS_STATE = 1<<1;
1036        int changes;
1037        int uid;
1038        int pid;
1039        int processState;
1040        boolean foregroundActivities;
1041    }
1042
1043    final RemoteCallbackList<IProcessObserver> mProcessObservers
1044            = new RemoteCallbackList<IProcessObserver>();
1045    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1046
1047    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1048            = new ArrayList<ProcessChangeItem>();
1049    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1050            = new ArrayList<ProcessChangeItem>();
1051
1052    /**
1053     * Runtime CPU use collection thread.  This object's lock is used to
1054     * protect all related state.
1055     */
1056    final Thread mProcessCpuThread;
1057
1058    /**
1059     * Used to collect process stats when showing not responding dialog.
1060     * Protected by mProcessCpuThread.
1061     */
1062    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1063            MONITOR_THREAD_CPU_USAGE);
1064    final AtomicLong mLastCpuTime = new AtomicLong(0);
1065    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1066
1067    long mLastWriteTime = 0;
1068
1069    /**
1070     * Used to retain an update lock when the foreground activity is in
1071     * immersive mode.
1072     */
1073    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1074
1075    /**
1076     * Set to true after the system has finished booting.
1077     */
1078    boolean mBooted = false;
1079
1080    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1081    int mProcessLimitOverride = -1;
1082
1083    WindowManagerService mWindowManager;
1084
1085    final ActivityThread mSystemThread;
1086
1087    int mCurrentUserId = 0;
1088    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1089    private UserManagerService mUserManager;
1090
1091    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1092        final ProcessRecord mApp;
1093        final int mPid;
1094        final IApplicationThread mAppThread;
1095
1096        AppDeathRecipient(ProcessRecord app, int pid,
1097                IApplicationThread thread) {
1098            if (localLOGV) Slog.v(
1099                TAG, "New death recipient " + this
1100                + " for thread " + thread.asBinder());
1101            mApp = app;
1102            mPid = pid;
1103            mAppThread = thread;
1104        }
1105
1106        @Override
1107        public void binderDied() {
1108            if (localLOGV) Slog.v(
1109                TAG, "Death received in " + this
1110                + " for thread " + mAppThread.asBinder());
1111            synchronized(ActivityManagerService.this) {
1112                appDiedLocked(mApp, mPid, mAppThread);
1113            }
1114        }
1115    }
1116
1117    static final int SHOW_ERROR_MSG = 1;
1118    static final int SHOW_NOT_RESPONDING_MSG = 2;
1119    static final int SHOW_FACTORY_ERROR_MSG = 3;
1120    static final int UPDATE_CONFIGURATION_MSG = 4;
1121    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1122    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1123    static final int SERVICE_TIMEOUT_MSG = 12;
1124    static final int UPDATE_TIME_ZONE = 13;
1125    static final int SHOW_UID_ERROR_MSG = 14;
1126    static final int IM_FEELING_LUCKY_MSG = 15;
1127    static final int PROC_START_TIMEOUT_MSG = 20;
1128    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1129    static final int KILL_APPLICATION_MSG = 22;
1130    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1131    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1132    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1133    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1134    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1135    static final int CLEAR_DNS_CACHE_MSG = 28;
1136    static final int UPDATE_HTTP_PROXY_MSG = 29;
1137    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1138    static final int DISPATCH_PROCESSES_CHANGED = 31;
1139    static final int DISPATCH_PROCESS_DIED = 32;
1140    static final int REPORT_MEM_USAGE_MSG = 33;
1141    static final int REPORT_USER_SWITCH_MSG = 34;
1142    static final int CONTINUE_USER_SWITCH_MSG = 35;
1143    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1144    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1145    static final int PERSIST_URI_GRANTS_MSG = 38;
1146    static final int REQUEST_ALL_PSS_MSG = 39;
1147    static final int START_PROFILES_MSG = 40;
1148    static final int UPDATE_TIME = 41;
1149    static final int SYSTEM_USER_START_MSG = 42;
1150    static final int SYSTEM_USER_CURRENT_MSG = 43;
1151
1152    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1153    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1154    static final int FIRST_COMPAT_MODE_MSG = 300;
1155    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1156
1157    AlertDialog mUidAlert;
1158    CompatModeDialog mCompatModeDialog;
1159    long mLastMemUsageReportTime = 0;
1160
1161    /**
1162     * Flag whether the current user is a "monkey", i.e. whether
1163     * the UI is driven by a UI automation tool.
1164     */
1165    private boolean mUserIsMonkey;
1166
1167    final ServiceThread mHandlerThread;
1168    final MainHandler mHandler;
1169
1170    final class MainHandler extends Handler {
1171        public MainHandler(Looper looper) {
1172            super(looper, null, true);
1173        }
1174
1175        @Override
1176        public void handleMessage(Message msg) {
1177            switch (msg.what) {
1178            case SHOW_ERROR_MSG: {
1179                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1180                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1181                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1182                synchronized (ActivityManagerService.this) {
1183                    ProcessRecord proc = (ProcessRecord)data.get("app");
1184                    AppErrorResult res = (AppErrorResult) data.get("result");
1185                    if (proc != null && proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has crash dialog: " + proc);
1187                        if (res != null) {
1188                            res.set(0);
1189                        }
1190                        return;
1191                    }
1192                    if (!showBackground && UserHandle.getAppId(proc.uid)
1193                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1194                            && proc.pid != MY_PID) {
1195                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1196                        if (res != null) {
1197                            res.set(0);
1198                        }
1199                        return;
1200                    }
1201                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1202                        Dialog d = new AppErrorDialog(mContext,
1203                                ActivityManagerService.this, res, proc);
1204                        d.show();
1205                        proc.crashDialog = d;
1206                    } else {
1207                        // The device is asleep, so just pretend that the user
1208                        // saw a crash dialog and hit "force quit".
1209                        if (res != null) {
1210                            res.set(0);
1211                        }
1212                    }
1213                }
1214
1215                ensureBootCompleted();
1216            } break;
1217            case SHOW_NOT_RESPONDING_MSG: {
1218                synchronized (ActivityManagerService.this) {
1219                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1220                    ProcessRecord proc = (ProcessRecord)data.get("app");
1221                    if (proc != null && proc.anrDialog != null) {
1222                        Slog.e(TAG, "App already has anr dialog: " + proc);
1223                        return;
1224                    }
1225
1226                    Intent intent = new Intent("android.intent.action.ANR");
1227                    if (!mProcessesReady) {
1228                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1229                                | Intent.FLAG_RECEIVER_FOREGROUND);
1230                    }
1231                    broadcastIntentLocked(null, null, intent,
1232                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1233                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1234
1235                    if (mShowDialogs) {
1236                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1237                                mContext, proc, (ActivityRecord)data.get("activity"),
1238                                msg.arg1 != 0);
1239                        d.show();
1240                        proc.anrDialog = d;
1241                    } else {
1242                        // Just kill the app if there is no dialog to be shown.
1243                        killAppAtUsersRequest(proc, null);
1244                    }
1245                }
1246
1247                ensureBootCompleted();
1248            } break;
1249            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1250                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1251                synchronized (ActivityManagerService.this) {
1252                    ProcessRecord proc = (ProcessRecord) data.get("app");
1253                    if (proc == null) {
1254                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1255                        break;
1256                    }
1257                    if (proc.crashDialog != null) {
1258                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1259                        return;
1260                    }
1261                    AppErrorResult res = (AppErrorResult) data.get("result");
1262                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1263                        Dialog d = new StrictModeViolationDialog(mContext,
1264                                ActivityManagerService.this, res, proc);
1265                        d.show();
1266                        proc.crashDialog = d;
1267                    } else {
1268                        // The device is asleep, so just pretend that the user
1269                        // saw a crash dialog and hit "force quit".
1270                        res.set(0);
1271                    }
1272                }
1273                ensureBootCompleted();
1274            } break;
1275            case SHOW_FACTORY_ERROR_MSG: {
1276                Dialog d = new FactoryErrorDialog(
1277                    mContext, msg.getData().getCharSequence("msg"));
1278                d.show();
1279                ensureBootCompleted();
1280            } break;
1281            case UPDATE_CONFIGURATION_MSG: {
1282                final ContentResolver resolver = mContext.getContentResolver();
1283                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1284            } break;
1285            case GC_BACKGROUND_PROCESSES_MSG: {
1286                synchronized (ActivityManagerService.this) {
1287                    performAppGcsIfAppropriateLocked();
1288                }
1289            } break;
1290            case WAIT_FOR_DEBUGGER_MSG: {
1291                synchronized (ActivityManagerService.this) {
1292                    ProcessRecord app = (ProcessRecord)msg.obj;
1293                    if (msg.arg1 != 0) {
1294                        if (!app.waitedForDebugger) {
1295                            Dialog d = new AppWaitingForDebuggerDialog(
1296                                    ActivityManagerService.this,
1297                                    mContext, app);
1298                            app.waitDialog = d;
1299                            app.waitedForDebugger = true;
1300                            d.show();
1301                        }
1302                    } else {
1303                        if (app.waitDialog != null) {
1304                            app.waitDialog.dismiss();
1305                            app.waitDialog = null;
1306                        }
1307                    }
1308                }
1309            } break;
1310            case SERVICE_TIMEOUT_MSG: {
1311                if (mDidDexOpt) {
1312                    mDidDexOpt = false;
1313                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1314                    nmsg.obj = msg.obj;
1315                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1316                    return;
1317                }
1318                mServices.serviceTimeout((ProcessRecord)msg.obj);
1319            } break;
1320            case UPDATE_TIME_ZONE: {
1321                synchronized (ActivityManagerService.this) {
1322                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1323                        ProcessRecord r = mLruProcesses.get(i);
1324                        if (r.thread != null) {
1325                            try {
1326                                r.thread.updateTimeZone();
1327                            } catch (RemoteException ex) {
1328                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1329                            }
1330                        }
1331                    }
1332                }
1333            } break;
1334            case CLEAR_DNS_CACHE_MSG: {
1335                synchronized (ActivityManagerService.this) {
1336                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1337                        ProcessRecord r = mLruProcesses.get(i);
1338                        if (r.thread != null) {
1339                            try {
1340                                r.thread.clearDnsCache();
1341                            } catch (RemoteException ex) {
1342                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1343                            }
1344                        }
1345                    }
1346                }
1347            } break;
1348            case UPDATE_HTTP_PROXY_MSG: {
1349                ProxyInfo proxy = (ProxyInfo)msg.obj;
1350                String host = "";
1351                String port = "";
1352                String exclList = "";
1353                Uri pacFileUrl = Uri.EMPTY;
1354                if (proxy != null) {
1355                    host = proxy.getHost();
1356                    port = Integer.toString(proxy.getPort());
1357                    exclList = proxy.getExclusionListAsString();
1358                    pacFileUrl = proxy.getPacFileUrl();
1359                }
1360                synchronized (ActivityManagerService.this) {
1361                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1362                        ProcessRecord r = mLruProcesses.get(i);
1363                        if (r.thread != null) {
1364                            try {
1365                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1366                            } catch (RemoteException ex) {
1367                                Slog.w(TAG, "Failed to update http proxy for: " +
1368                                        r.info.processName);
1369                            }
1370                        }
1371                    }
1372                }
1373            } break;
1374            case SHOW_UID_ERROR_MSG: {
1375                String title = "System UIDs Inconsistent";
1376                String text = "UIDs on the system are inconsistent, you need to wipe your"
1377                        + " data partition or your device will be unstable.";
1378                Log.e(TAG, title + ": " + text);
1379                if (mShowDialogs) {
1380                    // XXX This is a temporary dialog, no need to localize.
1381                    AlertDialog d = new BaseErrorDialog(mContext);
1382                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1383                    d.setCancelable(false);
1384                    d.setTitle(title);
1385                    d.setMessage(text);
1386                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1387                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1388                    mUidAlert = d;
1389                    d.show();
1390                }
1391            } break;
1392            case IM_FEELING_LUCKY_MSG: {
1393                if (mUidAlert != null) {
1394                    mUidAlert.dismiss();
1395                    mUidAlert = null;
1396                }
1397            } break;
1398            case PROC_START_TIMEOUT_MSG: {
1399                if (mDidDexOpt) {
1400                    mDidDexOpt = false;
1401                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1402                    nmsg.obj = msg.obj;
1403                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1404                    return;
1405                }
1406                ProcessRecord app = (ProcessRecord)msg.obj;
1407                synchronized (ActivityManagerService.this) {
1408                    processStartTimedOutLocked(app);
1409                }
1410            } break;
1411            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1412                synchronized (ActivityManagerService.this) {
1413                    doPendingActivityLaunchesLocked(true);
1414                }
1415            } break;
1416            case KILL_APPLICATION_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    int appid = msg.arg1;
1419                    boolean restart = (msg.arg2 == 1);
1420                    Bundle bundle = (Bundle)msg.obj;
1421                    String pkg = bundle.getString("pkg");
1422                    String reason = bundle.getString("reason");
1423                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1424                            false, UserHandle.USER_ALL, reason);
1425                }
1426            } break;
1427            case FINALIZE_PENDING_INTENT_MSG: {
1428                ((PendingIntentRecord)msg.obj).completeFinalize();
1429            } break;
1430            case POST_HEAVY_NOTIFICATION_MSG: {
1431                INotificationManager inm = NotificationManager.getService();
1432                if (inm == null) {
1433                    return;
1434                }
1435
1436                ActivityRecord root = (ActivityRecord)msg.obj;
1437                ProcessRecord process = root.app;
1438                if (process == null) {
1439                    return;
1440                }
1441
1442                try {
1443                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1444                    String text = mContext.getString(R.string.heavy_weight_notification,
1445                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1446                    Notification notification = new Notification();
1447                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1448                    notification.when = 0;
1449                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1450                    notification.tickerText = text;
1451                    notification.defaults = 0; // please be quiet
1452                    notification.sound = null;
1453                    notification.vibrate = null;
1454                    notification.setLatestEventInfo(context, text,
1455                            mContext.getText(R.string.heavy_weight_notification_detail),
1456                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1457                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1458                                    new UserHandle(root.userId)));
1459
1460                    try {
1461                        int[] outId = new int[1];
1462                        inm.enqueueNotificationWithTag("android", "android", null,
1463                                R.string.heavy_weight_notification,
1464                                notification, outId, root.userId);
1465                    } catch (RuntimeException e) {
1466                        Slog.w(ActivityManagerService.TAG,
1467                                "Error showing notification for heavy-weight app", e);
1468                    } catch (RemoteException e) {
1469                    }
1470                } catch (NameNotFoundException e) {
1471                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1472                }
1473            } break;
1474            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1475                INotificationManager inm = NotificationManager.getService();
1476                if (inm == null) {
1477                    return;
1478                }
1479                try {
1480                    inm.cancelNotificationWithTag("android", null,
1481                            R.string.heavy_weight_notification,  msg.arg1);
1482                } catch (RuntimeException e) {
1483                    Slog.w(ActivityManagerService.TAG,
1484                            "Error canceling notification for service", e);
1485                } catch (RemoteException e) {
1486                }
1487            } break;
1488            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1489                synchronized (ActivityManagerService.this) {
1490                    checkExcessivePowerUsageLocked(true);
1491                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1492                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1493                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1494                }
1495            } break;
1496            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1497                synchronized (ActivityManagerService.this) {
1498                    ActivityRecord ar = (ActivityRecord)msg.obj;
1499                    if (mCompatModeDialog != null) {
1500                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1501                                ar.info.applicationInfo.packageName)) {
1502                            return;
1503                        }
1504                        mCompatModeDialog.dismiss();
1505                        mCompatModeDialog = null;
1506                    }
1507                    if (ar != null && false) {
1508                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1509                                ar.packageName)) {
1510                            int mode = mCompatModePackages.computeCompatModeLocked(
1511                                    ar.info.applicationInfo);
1512                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1513                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1514                                mCompatModeDialog = new CompatModeDialog(
1515                                        ActivityManagerService.this, mContext,
1516                                        ar.info.applicationInfo);
1517                                mCompatModeDialog.show();
1518                            }
1519                        }
1520                    }
1521                }
1522                break;
1523            }
1524            case DISPATCH_PROCESSES_CHANGED: {
1525                dispatchProcessesChanged();
1526                break;
1527            }
1528            case DISPATCH_PROCESS_DIED: {
1529                final int pid = msg.arg1;
1530                final int uid = msg.arg2;
1531                dispatchProcessDied(pid, uid);
1532                break;
1533            }
1534            case REPORT_MEM_USAGE_MSG: {
1535                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1536                Thread thread = new Thread() {
1537                    @Override public void run() {
1538                        final SparseArray<ProcessMemInfo> infoMap
1539                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1540                        for (int i=0, N=memInfos.size(); i<N; i++) {
1541                            ProcessMemInfo mi = memInfos.get(i);
1542                            infoMap.put(mi.pid, mi);
1543                        }
1544                        updateCpuStatsNow();
1545                        synchronized (mProcessCpuThread) {
1546                            final int N = mProcessCpuTracker.countStats();
1547                            for (int i=0; i<N; i++) {
1548                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1549                                if (st.vsize > 0) {
1550                                    long pss = Debug.getPss(st.pid, null);
1551                                    if (pss > 0) {
1552                                        if (infoMap.indexOfKey(st.pid) < 0) {
1553                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1554                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1555                                            mi.pss = pss;
1556                                            memInfos.add(mi);
1557                                        }
1558                                    }
1559                                }
1560                            }
1561                        }
1562
1563                        long totalPss = 0;
1564                        for (int i=0, N=memInfos.size(); i<N; i++) {
1565                            ProcessMemInfo mi = memInfos.get(i);
1566                            if (mi.pss == 0) {
1567                                mi.pss = Debug.getPss(mi.pid, null);
1568                            }
1569                            totalPss += mi.pss;
1570                        }
1571                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1572                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1573                                if (lhs.oomAdj != rhs.oomAdj) {
1574                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1575                                }
1576                                if (lhs.pss != rhs.pss) {
1577                                    return lhs.pss < rhs.pss ? 1 : -1;
1578                                }
1579                                return 0;
1580                            }
1581                        });
1582
1583                        StringBuilder tag = new StringBuilder(128);
1584                        StringBuilder stack = new StringBuilder(128);
1585                        tag.append("Low on memory -- ");
1586                        appendMemBucket(tag, totalPss, "total", false);
1587                        appendMemBucket(stack, totalPss, "total", true);
1588
1589                        StringBuilder logBuilder = new StringBuilder(1024);
1590                        logBuilder.append("Low on memory:\n");
1591
1592                        boolean firstLine = true;
1593                        int lastOomAdj = Integer.MIN_VALUE;
1594                        for (int i=0, N=memInfos.size(); i<N; i++) {
1595                            ProcessMemInfo mi = memInfos.get(i);
1596
1597                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1598                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1599                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1600                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1601                                if (lastOomAdj != mi.oomAdj) {
1602                                    lastOomAdj = mi.oomAdj;
1603                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1604                                        tag.append(" / ");
1605                                    }
1606                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1607                                        if (firstLine) {
1608                                            stack.append(":");
1609                                            firstLine = false;
1610                                        }
1611                                        stack.append("\n\t at ");
1612                                    } else {
1613                                        stack.append("$");
1614                                    }
1615                                } else {
1616                                    tag.append(" ");
1617                                    stack.append("$");
1618                                }
1619                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                    appendMemBucket(tag, mi.pss, mi.name, false);
1621                                }
1622                                appendMemBucket(stack, mi.pss, mi.name, true);
1623                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1624                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1625                                    stack.append("(");
1626                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1627                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1628                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1629                                            stack.append(":");
1630                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1631                                        }
1632                                    }
1633                                    stack.append(")");
1634                                }
1635                            }
1636
1637                            logBuilder.append("  ");
1638                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1639                            logBuilder.append(' ');
1640                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1641                            logBuilder.append(' ');
1642                            ProcessList.appendRamKb(logBuilder, mi.pss);
1643                            logBuilder.append(" kB: ");
1644                            logBuilder.append(mi.name);
1645                            logBuilder.append(" (");
1646                            logBuilder.append(mi.pid);
1647                            logBuilder.append(") ");
1648                            logBuilder.append(mi.adjType);
1649                            logBuilder.append('\n');
1650                            if (mi.adjReason != null) {
1651                                logBuilder.append("                      ");
1652                                logBuilder.append(mi.adjReason);
1653                                logBuilder.append('\n');
1654                            }
1655                        }
1656
1657                        logBuilder.append("           ");
1658                        ProcessList.appendRamKb(logBuilder, totalPss);
1659                        logBuilder.append(" kB: TOTAL\n");
1660
1661                        long[] infos = new long[Debug.MEMINFO_COUNT];
1662                        Debug.getMemInfo(infos);
1663                        logBuilder.append("  MemInfo: ");
1664                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1667                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1668                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1669                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1670                            logBuilder.append("  ZRAM: ");
1671                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1672                            logBuilder.append(" kB RAM, ");
1673                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1674                            logBuilder.append(" kB swap total, ");
1675                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1676                            logBuilder.append(" kB swap free\n");
1677                        }
1678                        Slog.i(TAG, logBuilder.toString());
1679
1680                        StringBuilder dropBuilder = new StringBuilder(1024);
1681                        /*
1682                        StringWriter oomSw = new StringWriter();
1683                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1684                        StringWriter catSw = new StringWriter();
1685                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1686                        String[] emptyArgs = new String[] { };
1687                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1688                        oomPw.flush();
1689                        String oomString = oomSw.toString();
1690                        */
1691                        dropBuilder.append(stack);
1692                        dropBuilder.append('\n');
1693                        dropBuilder.append('\n');
1694                        dropBuilder.append(logBuilder);
1695                        dropBuilder.append('\n');
1696                        /*
1697                        dropBuilder.append(oomString);
1698                        dropBuilder.append('\n');
1699                        */
1700                        StringWriter catSw = new StringWriter();
1701                        synchronized (ActivityManagerService.this) {
1702                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                            String[] emptyArgs = new String[] { };
1704                            catPw.println();
1705                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1706                            catPw.println();
1707                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1708                                    false, false, null);
1709                            catPw.println();
1710                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1711                            catPw.flush();
1712                        }
1713                        dropBuilder.append(catSw.toString());
1714                        addErrorToDropBox("lowmem", null, "system_server", null,
1715                                null, tag.toString(), dropBuilder.toString(), null, null);
1716                        //Slog.i(TAG, "Sent to dropbox:");
1717                        //Slog.i(TAG, dropBuilder.toString());
1718                        synchronized (ActivityManagerService.this) {
1719                            long now = SystemClock.uptimeMillis();
1720                            if (mLastMemUsageReportTime < now) {
1721                                mLastMemUsageReportTime = now;
1722                            }
1723                        }
1724                    }
1725                };
1726                thread.start();
1727                break;
1728            }
1729            case REPORT_USER_SWITCH_MSG: {
1730                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1731                break;
1732            }
1733            case CONTINUE_USER_SWITCH_MSG: {
1734                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1735                break;
1736            }
1737            case USER_SWITCH_TIMEOUT_MSG: {
1738                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1739                break;
1740            }
1741            case IMMERSIVE_MODE_LOCK_MSG: {
1742                final boolean nextState = (msg.arg1 != 0);
1743                if (mUpdateLock.isHeld() != nextState) {
1744                    if (DEBUG_IMMERSIVE) {
1745                        final ActivityRecord r = (ActivityRecord) msg.obj;
1746                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1747                    }
1748                    if (nextState) {
1749                        mUpdateLock.acquire();
1750                    } else {
1751                        mUpdateLock.release();
1752                    }
1753                }
1754                break;
1755            }
1756            case PERSIST_URI_GRANTS_MSG: {
1757                writeGrantedUriPermissions();
1758                break;
1759            }
1760            case REQUEST_ALL_PSS_MSG: {
1761                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1762                break;
1763            }
1764            case START_PROFILES_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    startProfilesLocked();
1767                }
1768                break;
1769            }
1770            case UPDATE_TIME: {
1771                synchronized (ActivityManagerService.this) {
1772                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1773                        ProcessRecord r = mLruProcesses.get(i);
1774                        if (r.thread != null) {
1775                            try {
1776                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1777                            } catch (RemoteException ex) {
1778                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1779                            }
1780                        }
1781                    }
1782                }
1783                break;
1784            }
1785            case SYSTEM_USER_START_MSG: {
1786                mSystemServiceManager.startUser(msg.arg1);
1787                break;
1788            }
1789            case SYSTEM_USER_CURRENT_MSG: {
1790                mSystemServiceManager.switchUser(msg.arg1);
1791                break;
1792            }
1793            }
1794        }
1795    };
1796
1797    static final int COLLECT_PSS_BG_MSG = 1;
1798
1799    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1800        @Override
1801        public void handleMessage(Message msg) {
1802            switch (msg.what) {
1803            case COLLECT_PSS_BG_MSG: {
1804                int i=0, num=0;
1805                long start = SystemClock.uptimeMillis();
1806                long[] tmp = new long[1];
1807                do {
1808                    ProcessRecord proc;
1809                    int procState;
1810                    int pid;
1811                    synchronized (ActivityManagerService.this) {
1812                        if (i >= mPendingPssProcesses.size()) {
1813                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1814                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1815                            mPendingPssProcesses.clear();
1816                            return;
1817                        }
1818                        proc = mPendingPssProcesses.get(i);
1819                        procState = proc.pssProcState;
1820                        if (proc.thread != null && procState == proc.setProcState) {
1821                            pid = proc.pid;
1822                        } else {
1823                            proc = null;
1824                            pid = 0;
1825                        }
1826                        i++;
1827                    }
1828                    if (proc != null) {
1829                        long pss = Debug.getPss(pid, tmp);
1830                        synchronized (ActivityManagerService.this) {
1831                            if (proc.thread != null && proc.setProcState == procState
1832                                    && proc.pid == pid) {
1833                                num++;
1834                                proc.lastPssTime = SystemClock.uptimeMillis();
1835                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1836                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1837                                        + ": " + pss + " lastPss=" + proc.lastPss
1838                                        + " state=" + ProcessList.makeProcStateString(procState));
1839                                if (proc.initialIdlePss == 0) {
1840                                    proc.initialIdlePss = pss;
1841                                }
1842                                proc.lastPss = pss;
1843                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1844                                    proc.lastCachedPss = pss;
1845                                }
1846                            }
1847                        }
1848                    }
1849                } while (true);
1850            }
1851            }
1852        }
1853    };
1854
1855    /**
1856     * Monitor for package changes and update our internal state.
1857     */
1858    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1859        @Override
1860        public void onPackageRemoved(String packageName, int uid) {
1861            // Remove all tasks with activities in the specified package from the list of recent tasks
1862            synchronized (ActivityManagerService.this) {
1863                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1864                    TaskRecord tr = mRecentTasks.get(i);
1865                    ComponentName cn = tr.intent.getComponent();
1866                    if (cn != null && cn.getPackageName().equals(packageName)) {
1867                        // If the package name matches, remove the task and kill the process
1868                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1869                    }
1870                }
1871            }
1872        }
1873
1874        @Override
1875        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1876            onPackageModified(packageName);
1877            return true;
1878        }
1879
1880        @Override
1881        public void onPackageModified(String packageName) {
1882            final PackageManager pm = mContext.getPackageManager();
1883            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1884                    new ArrayList<Pair<Intent, Integer>>();
1885            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1886            // Copy the list of recent tasks so that we don't hold onto the lock on
1887            // ActivityManagerService for long periods while checking if components exist.
1888            synchronized (ActivityManagerService.this) {
1889                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1890                    TaskRecord tr = mRecentTasks.get(i);
1891                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1892                }
1893            }
1894            // Check the recent tasks and filter out all tasks with components that no longer exist.
1895            Intent tmpI = new Intent();
1896            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1897                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1898                ComponentName cn = p.first.getComponent();
1899                if (cn != null && cn.getPackageName().equals(packageName)) {
1900                    try {
1901                        // Add the task to the list to remove if the component no longer exists
1902                        tmpI.setComponent(cn);
1903                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1904                            tasksToRemove.add(p.second);
1905                        }
1906                    } catch (Exception e) {}
1907                }
1908            }
1909            // Prune all the tasks with removed components from the list of recent tasks
1910            synchronized (ActivityManagerService.this) {
1911                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1912                    // Remove the task but don't kill the process (since other components in that
1913                    // package may still be running and in the background)
1914                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1915                }
1916            }
1917        }
1918
1919        @Override
1920        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1921            // Force stop the specified packages
1922            if (packages != null) {
1923                for (String pkg : packages) {
1924                    synchronized (ActivityManagerService.this) {
1925                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1926                                "finished booting")) {
1927                            return true;
1928                        }
1929                    }
1930                }
1931            }
1932            return false;
1933        }
1934    };
1935
1936    public void setSystemProcess() {
1937        try {
1938            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1939            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1940            ServiceManager.addService("meminfo", new MemBinder(this));
1941            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1942            ServiceManager.addService("dbinfo", new DbBinder(this));
1943            if (MONITOR_CPU_USAGE) {
1944                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1945            }
1946            ServiceManager.addService("permission", new PermissionController(this));
1947
1948            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1949                    "android", STOCK_PM_FLAGS);
1950            mSystemThread.installSystemApplicationInfo(info);
1951
1952            synchronized (this) {
1953                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1954                app.persistent = true;
1955                app.pid = MY_PID;
1956                app.maxAdj = ProcessList.SYSTEM_ADJ;
1957                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1958                mProcessNames.put(app.processName, app.uid, app);
1959                synchronized (mPidsSelfLocked) {
1960                    mPidsSelfLocked.put(app.pid, app);
1961                }
1962                updateLruProcessLocked(app, false, null);
1963                updateOomAdjLocked();
1964            }
1965        } catch (PackageManager.NameNotFoundException e) {
1966            throw new RuntimeException(
1967                    "Unable to find android system package", e);
1968        }
1969    }
1970
1971    public void setWindowManager(WindowManagerService wm) {
1972        mWindowManager = wm;
1973        mStackSupervisor.setWindowManager(wm);
1974    }
1975
1976    public void startObservingNativeCrashes() {
1977        final NativeCrashListener ncl = new NativeCrashListener(this);
1978        ncl.start();
1979    }
1980
1981    public IAppOpsService getAppOpsService() {
1982        return mAppOpsService;
1983    }
1984
1985    static class MemBinder extends Binder {
1986        ActivityManagerService mActivityManagerService;
1987        MemBinder(ActivityManagerService activityManagerService) {
1988            mActivityManagerService = activityManagerService;
1989        }
1990
1991        @Override
1992        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1993            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1994                    != PackageManager.PERMISSION_GRANTED) {
1995                pw.println("Permission Denial: can't dump meminfo from from pid="
1996                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1997                        + " without permission " + android.Manifest.permission.DUMP);
1998                return;
1999            }
2000
2001            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2002        }
2003    }
2004
2005    static class GraphicsBinder extends Binder {
2006        ActivityManagerService mActivityManagerService;
2007        GraphicsBinder(ActivityManagerService activityManagerService) {
2008            mActivityManagerService = activityManagerService;
2009        }
2010
2011        @Override
2012        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2013            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2014                    != PackageManager.PERMISSION_GRANTED) {
2015                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2016                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2017                        + " without permission " + android.Manifest.permission.DUMP);
2018                return;
2019            }
2020
2021            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2022        }
2023    }
2024
2025    static class DbBinder extends Binder {
2026        ActivityManagerService mActivityManagerService;
2027        DbBinder(ActivityManagerService activityManagerService) {
2028            mActivityManagerService = activityManagerService;
2029        }
2030
2031        @Override
2032        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2033            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2034                    != PackageManager.PERMISSION_GRANTED) {
2035                pw.println("Permission Denial: can't dump dbinfo from from pid="
2036                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2037                        + " without permission " + android.Manifest.permission.DUMP);
2038                return;
2039            }
2040
2041            mActivityManagerService.dumpDbInfo(fd, pw, args);
2042        }
2043    }
2044
2045    static class CpuBinder extends Binder {
2046        ActivityManagerService mActivityManagerService;
2047        CpuBinder(ActivityManagerService activityManagerService) {
2048            mActivityManagerService = activityManagerService;
2049        }
2050
2051        @Override
2052        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2053            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2054                    != PackageManager.PERMISSION_GRANTED) {
2055                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2056                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2057                        + " without permission " + android.Manifest.permission.DUMP);
2058                return;
2059            }
2060
2061            synchronized (mActivityManagerService.mProcessCpuThread) {
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2063                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2064                        SystemClock.uptimeMillis()));
2065            }
2066        }
2067    }
2068
2069    public static final class Lifecycle extends SystemService {
2070        private final ActivityManagerService mService;
2071
2072        public Lifecycle(Context context) {
2073            super(context);
2074            mService = new ActivityManagerService(context);
2075        }
2076
2077        @Override
2078        public void onStart() {
2079            mService.start();
2080        }
2081
2082        public ActivityManagerService getService() {
2083            return mService;
2084        }
2085    }
2086
2087    // Note: This method is invoked on the main thread but may need to attach various
2088    // handlers to other threads.  So take care to be explicit about the looper.
2089    public ActivityManagerService(Context systemContext) {
2090        mContext = systemContext;
2091        mFactoryTest = FactoryTest.getMode();
2092        mSystemThread = ActivityThread.currentActivityThread();
2093
2094        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2095
2096        mHandlerThread = new ServiceThread(TAG,
2097                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2098        mHandlerThread.start();
2099        mHandler = new MainHandler(mHandlerThread.getLooper());
2100
2101        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2102                "foreground", BROADCAST_FG_TIMEOUT, false);
2103        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2104                "background", BROADCAST_BG_TIMEOUT, true);
2105        mBroadcastQueues[0] = mFgBroadcastQueue;
2106        mBroadcastQueues[1] = mBgBroadcastQueue;
2107
2108        mServices = new ActiveServices(this);
2109        mProviderMap = new ProviderMap(this);
2110
2111        // TODO: Move creation of battery stats service outside of activity manager service.
2112        File dataDir = Environment.getDataDirectory();
2113        File systemDir = new File(dataDir, "system");
2114        systemDir.mkdirs();
2115        mBatteryStatsService = new BatteryStatsService(new File(
2116                systemDir, "batterystats.bin").toString(), mHandler);
2117        mBatteryStatsService.getActiveStatistics().readLocked();
2118        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2119        mOnBattery = DEBUG_POWER ? true
2120                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2121        mBatteryStatsService.getActiveStatistics().setCallback(this);
2122
2123        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2124
2125        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2126        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2127
2128        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2129
2130        // User 0 is the first and only user that runs at boot.
2131        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2132        mUserLru.add(Integer.valueOf(0));
2133        updateStartedUserArrayLocked();
2134
2135        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2136            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2137
2138        mConfiguration.setToDefaults();
2139        mConfiguration.setLocale(Locale.getDefault());
2140
2141        mConfigurationSeq = mConfiguration.seq = 1;
2142        mProcessCpuTracker.init();
2143
2144        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2145        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2146        mStackSupervisor = new ActivityStackSupervisor(this);
2147        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2148
2149        mProcessCpuThread = new Thread("CpuTracker") {
2150            @Override
2151            public void run() {
2152                while (true) {
2153                    try {
2154                        try {
2155                            synchronized(this) {
2156                                final long now = SystemClock.uptimeMillis();
2157                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2158                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2159                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2160                                //        + ", write delay=" + nextWriteDelay);
2161                                if (nextWriteDelay < nextCpuDelay) {
2162                                    nextCpuDelay = nextWriteDelay;
2163                                }
2164                                if (nextCpuDelay > 0) {
2165                                    mProcessCpuMutexFree.set(true);
2166                                    this.wait(nextCpuDelay);
2167                                }
2168                            }
2169                        } catch (InterruptedException e) {
2170                        }
2171                        updateCpuStatsNow();
2172                    } catch (Exception e) {
2173                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2174                    }
2175                }
2176            }
2177        };
2178
2179        Watchdog.getInstance().addMonitor(this);
2180        Watchdog.getInstance().addThread(mHandler);
2181    }
2182
2183    public void setSystemServiceManager(SystemServiceManager mgr) {
2184        mSystemServiceManager = mgr;
2185    }
2186
2187    private void start() {
2188        mProcessCpuThread.start();
2189
2190        mBatteryStatsService.publish(mContext);
2191        mUsageStatsService.publish(mContext);
2192        mAppOpsService.publish(mContext);
2193        Slog.d("AppOps", "AppOpsService published");
2194        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2195    }
2196
2197    @Override
2198    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2199            throws RemoteException {
2200        if (code == SYSPROPS_TRANSACTION) {
2201            // We need to tell all apps about the system property change.
2202            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2203            synchronized(this) {
2204                final int NP = mProcessNames.getMap().size();
2205                for (int ip=0; ip<NP; ip++) {
2206                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2207                    final int NA = apps.size();
2208                    for (int ia=0; ia<NA; ia++) {
2209                        ProcessRecord app = apps.valueAt(ia);
2210                        if (app.thread != null) {
2211                            procs.add(app.thread.asBinder());
2212                        }
2213                    }
2214                }
2215            }
2216
2217            int N = procs.size();
2218            for (int i=0; i<N; i++) {
2219                Parcel data2 = Parcel.obtain();
2220                try {
2221                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2222                } catch (RemoteException e) {
2223                }
2224                data2.recycle();
2225            }
2226        }
2227        try {
2228            return super.onTransact(code, data, reply, flags);
2229        } catch (RuntimeException e) {
2230            // The activity manager only throws security exceptions, so let's
2231            // log all others.
2232            if (!(e instanceof SecurityException)) {
2233                Slog.wtf(TAG, "Activity Manager Crash", e);
2234            }
2235            throw e;
2236        }
2237    }
2238
2239    void updateCpuStats() {
2240        final long now = SystemClock.uptimeMillis();
2241        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2242            return;
2243        }
2244        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2245            synchronized (mProcessCpuThread) {
2246                mProcessCpuThread.notify();
2247            }
2248        }
2249    }
2250
2251    void updateCpuStatsNow() {
2252        synchronized (mProcessCpuThread) {
2253            mProcessCpuMutexFree.set(false);
2254            final long now = SystemClock.uptimeMillis();
2255            boolean haveNewCpuStats = false;
2256
2257            if (MONITOR_CPU_USAGE &&
2258                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2259                mLastCpuTime.set(now);
2260                haveNewCpuStats = true;
2261                mProcessCpuTracker.update();
2262                //Slog.i(TAG, mProcessCpu.printCurrentState());
2263                //Slog.i(TAG, "Total CPU usage: "
2264                //        + mProcessCpu.getTotalCpuPercent() + "%");
2265
2266                // Slog the cpu usage if the property is set.
2267                if ("true".equals(SystemProperties.get("events.cpu"))) {
2268                    int user = mProcessCpuTracker.getLastUserTime();
2269                    int system = mProcessCpuTracker.getLastSystemTime();
2270                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2271                    int irq = mProcessCpuTracker.getLastIrqTime();
2272                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2273                    int idle = mProcessCpuTracker.getLastIdleTime();
2274
2275                    int total = user + system + iowait + irq + softIrq + idle;
2276                    if (total == 0) total = 1;
2277
2278                    EventLog.writeEvent(EventLogTags.CPU,
2279                            ((user+system+iowait+irq+softIrq) * 100) / total,
2280                            (user * 100) / total,
2281                            (system * 100) / total,
2282                            (iowait * 100) / total,
2283                            (irq * 100) / total,
2284                            (softIrq * 100) / total);
2285                }
2286            }
2287
2288            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2289            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2290            synchronized(bstats) {
2291                synchronized(mPidsSelfLocked) {
2292                    if (haveNewCpuStats) {
2293                        if (mOnBattery) {
2294                            int perc = bstats.startAddingCpuLocked();
2295                            int totalUTime = 0;
2296                            int totalSTime = 0;
2297                            final int N = mProcessCpuTracker.countStats();
2298                            for (int i=0; i<N; i++) {
2299                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2300                                if (!st.working) {
2301                                    continue;
2302                                }
2303                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2304                                int otherUTime = (st.rel_utime*perc)/100;
2305                                int otherSTime = (st.rel_stime*perc)/100;
2306                                totalUTime += otherUTime;
2307                                totalSTime += otherSTime;
2308                                if (pr != null) {
2309                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2312                                                pr.info.uid, pr.processName);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2318                                } else {
2319                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2320                                    if (ps == null || !ps.isActive()) {
2321                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2322                                                bstats.mapUid(st.uid), st.name);
2323                                    }
2324                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2325                                            st.rel_stime-otherSTime);
2326                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2327                                }
2328                            }
2329                            bstats.finishAddingCpuLocked(perc, totalUTime,
2330                                    totalSTime, cpuSpeedTimes);
2331                        }
2332                    }
2333                }
2334
2335                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2336                    mLastWriteTime = now;
2337                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2338                }
2339            }
2340        }
2341    }
2342
2343    @Override
2344    public void batteryNeedsCpuUpdate() {
2345        updateCpuStatsNow();
2346    }
2347
2348    @Override
2349    public void batteryPowerChanged(boolean onBattery) {
2350        // When plugging in, update the CPU stats first before changing
2351        // the plug state.
2352        updateCpuStatsNow();
2353        synchronized (this) {
2354            synchronized(mPidsSelfLocked) {
2355                mOnBattery = DEBUG_POWER ? true : onBattery;
2356            }
2357        }
2358    }
2359
2360    /**
2361     * Initialize the application bind args. These are passed to each
2362     * process when the bindApplication() IPC is sent to the process. They're
2363     * lazily setup to make sure the services are running when they're asked for.
2364     */
2365    private HashMap<String, IBinder> getCommonServicesLocked() {
2366        if (mAppBindArgs == null) {
2367            mAppBindArgs = new HashMap<String, IBinder>();
2368
2369            // Setup the application init args
2370            mAppBindArgs.put("package", ServiceManager.getService("package"));
2371            mAppBindArgs.put("window", ServiceManager.getService("window"));
2372            mAppBindArgs.put(Context.ALARM_SERVICE,
2373                    ServiceManager.getService(Context.ALARM_SERVICE));
2374        }
2375        return mAppBindArgs;
2376    }
2377
2378    final void setFocusedActivityLocked(ActivityRecord r) {
2379        if (mFocusedActivity != r) {
2380            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2381            mFocusedActivity = r;
2382            if (r.task != null && r.task.voiceInteractor != null) {
2383                startRunningVoiceLocked();
2384            } else {
2385                finishRunningVoiceLocked();
2386            }
2387            mStackSupervisor.setFocusedStack(r);
2388            if (r != null) {
2389                mWindowManager.setFocusedApp(r.appToken, true);
2390            }
2391            applyUpdateLockStateLocked(r);
2392        }
2393    }
2394
2395    final void clearFocusedActivity(ActivityRecord r) {
2396        if (mFocusedActivity == r) {
2397            mFocusedActivity = null;
2398        }
2399    }
2400
2401    @Override
2402    public void setFocusedStack(int stackId) {
2403        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2404        synchronized (ActivityManagerService.this) {
2405            ActivityStack stack = mStackSupervisor.getStack(stackId);
2406            if (stack != null) {
2407                ActivityRecord r = stack.topRunningActivityLocked(null);
2408                if (r != null) {
2409                    setFocusedActivityLocked(r);
2410                }
2411            }
2412        }
2413    }
2414
2415    @Override
2416    public void notifyActivityDrawn(IBinder token) {
2417        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2418        synchronized (this) {
2419            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2420            if (r != null) {
2421                r.task.stack.notifyActivityDrawnLocked(r);
2422            }
2423        }
2424    }
2425
2426    final void applyUpdateLockStateLocked(ActivityRecord r) {
2427        // Modifications to the UpdateLock state are done on our handler, outside
2428        // the activity manager's locks.  The new state is determined based on the
2429        // state *now* of the relevant activity record.  The object is passed to
2430        // the handler solely for logging detail, not to be consulted/modified.
2431        final boolean nextState = r != null && r.immersive;
2432        mHandler.sendMessage(
2433                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2434    }
2435
2436    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2437        Message msg = Message.obtain();
2438        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2439        msg.obj = r.task.askedCompatMode ? null : r;
2440        mHandler.sendMessage(msg);
2441    }
2442
2443    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2444            String what, Object obj, ProcessRecord srcApp) {
2445        app.lastActivityTime = now;
2446
2447        if (app.activities.size() > 0) {
2448            // Don't want to touch dependent processes that are hosting activities.
2449            return index;
2450        }
2451
2452        int lrui = mLruProcesses.lastIndexOf(app);
2453        if (lrui < 0) {
2454            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2455                    + what + " " + obj + " from " + srcApp);
2456            return index;
2457        }
2458
2459        if (lrui >= index) {
2460            // Don't want to cause this to move dependent processes *back* in the
2461            // list as if they were less frequently used.
2462            return index;
2463        }
2464
2465        if (lrui >= mLruProcessActivityStart) {
2466            // Don't want to touch dependent processes that are hosting activities.
2467            return index;
2468        }
2469
2470        mLruProcesses.remove(lrui);
2471        if (index > 0) {
2472            index--;
2473        }
2474        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2475                + " in LRU list: " + app);
2476        mLruProcesses.add(index, app);
2477        return index;
2478    }
2479
2480    final void removeLruProcessLocked(ProcessRecord app) {
2481        int lrui = mLruProcesses.lastIndexOf(app);
2482        if (lrui >= 0) {
2483            if (lrui <= mLruProcessActivityStart) {
2484                mLruProcessActivityStart--;
2485            }
2486            if (lrui <= mLruProcessServiceStart) {
2487                mLruProcessServiceStart--;
2488            }
2489            mLruProcesses.remove(lrui);
2490        }
2491    }
2492
2493    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2494            ProcessRecord client) {
2495        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2496                || app.treatLikeActivity;
2497        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2498        if (!activityChange && hasActivity) {
2499            // The process has activities, so we are only allowing activity-based adjustments
2500            // to move it.  It should be kept in the front of the list with other
2501            // processes that have activities, and we don't want those to change their
2502            // order except due to activity operations.
2503            return;
2504        }
2505
2506        mLruSeq++;
2507        final long now = SystemClock.uptimeMillis();
2508        app.lastActivityTime = now;
2509
2510        // First a quick reject: if the app is already at the position we will
2511        // put it, then there is nothing to do.
2512        if (hasActivity) {
2513            final int N = mLruProcesses.size();
2514            if (N > 0 && mLruProcesses.get(N-1) == app) {
2515                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2516                return;
2517            }
2518        } else {
2519            if (mLruProcessServiceStart > 0
2520                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2521                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2522                return;
2523            }
2524        }
2525
2526        int lrui = mLruProcesses.lastIndexOf(app);
2527
2528        if (app.persistent && lrui >= 0) {
2529            // We don't care about the position of persistent processes, as long as
2530            // they are in the list.
2531            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2532            return;
2533        }
2534
2535        /* In progress: compute new position first, so we can avoid doing work
2536           if the process is not actually going to move.  Not yet working.
2537        int addIndex;
2538        int nextIndex;
2539        boolean inActivity = false, inService = false;
2540        if (hasActivity) {
2541            // Process has activities, put it at the very tipsy-top.
2542            addIndex = mLruProcesses.size();
2543            nextIndex = mLruProcessServiceStart;
2544            inActivity = true;
2545        } else if (hasService) {
2546            // Process has services, put it at the top of the service list.
2547            addIndex = mLruProcessActivityStart;
2548            nextIndex = mLruProcessServiceStart;
2549            inActivity = true;
2550            inService = true;
2551        } else  {
2552            // Process not otherwise of interest, it goes to the top of the non-service area.
2553            addIndex = mLruProcessServiceStart;
2554            if (client != null) {
2555                int clientIndex = mLruProcesses.lastIndexOf(client);
2556                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2557                        + app);
2558                if (clientIndex >= 0 && addIndex > clientIndex) {
2559                    addIndex = clientIndex;
2560                }
2561            }
2562            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2563        }
2564
2565        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2566                + mLruProcessActivityStart + "): " + app);
2567        */
2568
2569        if (lrui >= 0) {
2570            if (lrui < mLruProcessActivityStart) {
2571                mLruProcessActivityStart--;
2572            }
2573            if (lrui < mLruProcessServiceStart) {
2574                mLruProcessServiceStart--;
2575            }
2576            /*
2577            if (addIndex > lrui) {
2578                addIndex--;
2579            }
2580            if (nextIndex > lrui) {
2581                nextIndex--;
2582            }
2583            */
2584            mLruProcesses.remove(lrui);
2585        }
2586
2587        /*
2588        mLruProcesses.add(addIndex, app);
2589        if (inActivity) {
2590            mLruProcessActivityStart++;
2591        }
2592        if (inService) {
2593            mLruProcessActivityStart++;
2594        }
2595        */
2596
2597        int nextIndex;
2598        if (hasActivity) {
2599            final int N = mLruProcesses.size();
2600            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2601                // Process doesn't have activities, but has clients with
2602                // activities...  move it up, but one below the top (the top
2603                // should always have a real activity).
2604                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2605                mLruProcesses.add(N-1, app);
2606                // To keep it from spamming the LRU list (by making a bunch of clients),
2607                // we will push down any other entries owned by the app.
2608                final int uid = app.info.uid;
2609                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2610                    ProcessRecord subProc = mLruProcesses.get(i);
2611                    if (subProc.info.uid == uid) {
2612                        // We want to push this one down the list.  If the process after
2613                        // it is for the same uid, however, don't do so, because we don't
2614                        // want them internally to be re-ordered.
2615                        if (mLruProcesses.get(i-1).info.uid != uid) {
2616                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2617                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2618                            ProcessRecord tmp = mLruProcesses.get(i);
2619                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2620                            mLruProcesses.set(i-1, tmp);
2621                            i--;
2622                        }
2623                    } else {
2624                        // A gap, we can stop here.
2625                        break;
2626                    }
2627                }
2628            } else {
2629                // Process has activities, put it at the very tipsy-top.
2630                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2631                mLruProcesses.add(app);
2632            }
2633            nextIndex = mLruProcessServiceStart;
2634        } else if (hasService) {
2635            // Process has services, put it at the top of the service list.
2636            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2637            mLruProcesses.add(mLruProcessActivityStart, app);
2638            nextIndex = mLruProcessServiceStart;
2639            mLruProcessActivityStart++;
2640        } else  {
2641            // Process not otherwise of interest, it goes to the top of the non-service area.
2642            int index = mLruProcessServiceStart;
2643            if (client != null) {
2644                // If there is a client, don't allow the process to be moved up higher
2645                // in the list than that client.
2646                int clientIndex = mLruProcesses.lastIndexOf(client);
2647                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2648                        + " when updating " + app);
2649                if (clientIndex <= lrui) {
2650                    // Don't allow the client index restriction to push it down farther in the
2651                    // list than it already is.
2652                    clientIndex = lrui;
2653                }
2654                if (clientIndex >= 0 && index > clientIndex) {
2655                    index = clientIndex;
2656                }
2657            }
2658            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2659            mLruProcesses.add(index, app);
2660            nextIndex = index-1;
2661            mLruProcessActivityStart++;
2662            mLruProcessServiceStart++;
2663        }
2664
2665        // If the app is currently using a content provider or service,
2666        // bump those processes as well.
2667        for (int j=app.connections.size()-1; j>=0; j--) {
2668            ConnectionRecord cr = app.connections.valueAt(j);
2669            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2670                    && cr.binding.service.app != null
2671                    && cr.binding.service.app.lruSeq != mLruSeq
2672                    && !cr.binding.service.app.persistent) {
2673                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2674                        "service connection", cr, app);
2675            }
2676        }
2677        for (int j=app.conProviders.size()-1; j>=0; j--) {
2678            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2679            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2680                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2681                        "provider reference", cpr, app);
2682            }
2683        }
2684    }
2685
2686    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2687        if (uid == Process.SYSTEM_UID) {
2688            // The system gets to run in any process.  If there are multiple
2689            // processes with the same uid, just pick the first (this
2690            // should never happen).
2691            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2692            if (procs == null) return null;
2693            final int N = procs.size();
2694            for (int i = 0; i < N; i++) {
2695                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2696            }
2697        }
2698        ProcessRecord proc = mProcessNames.get(processName, uid);
2699        if (false && proc != null && !keepIfLarge
2700                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2701                && proc.lastCachedPss >= 4000) {
2702            // Turn this condition on to cause killing to happen regularly, for testing.
2703            if (proc.baseProcessTracker != null) {
2704                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2705            }
2706            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2707                    + "k from cached");
2708        } else if (proc != null && !keepIfLarge
2709                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2710                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2711            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2712            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2713                if (proc.baseProcessTracker != null) {
2714                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2715                }
2716                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2717                        + "k from cached");
2718            }
2719        }
2720        return proc;
2721    }
2722
2723    void ensurePackageDexOpt(String packageName) {
2724        IPackageManager pm = AppGlobals.getPackageManager();
2725        try {
2726            if (pm.performDexOpt(packageName)) {
2727                mDidDexOpt = true;
2728            }
2729        } catch (RemoteException e) {
2730        }
2731    }
2732
2733    boolean isNextTransitionForward() {
2734        int transit = mWindowManager.getPendingAppTransition();
2735        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_OPEN
2737                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2738    }
2739
2740    final ProcessRecord startProcessLocked(String processName,
2741            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2742            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2743            boolean isolated, boolean keepIfLarge) {
2744        ProcessRecord app;
2745        if (!isolated) {
2746            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2747        } else {
2748            // If this is an isolated process, it can't re-use an existing process.
2749            app = null;
2750        }
2751        // We don't have to do anything more if:
2752        // (1) There is an existing application record; and
2753        // (2) The caller doesn't think it is dead, OR there is no thread
2754        //     object attached to it so we know it couldn't have crashed; and
2755        // (3) There is a pid assigned to it, so it is either starting or
2756        //     already running.
2757        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2758                + " app=" + app + " knownToBeDead=" + knownToBeDead
2759                + " thread=" + (app != null ? app.thread : null)
2760                + " pid=" + (app != null ? app.pid : -1));
2761        if (app != null && app.pid > 0) {
2762            if (!knownToBeDead || app.thread == null) {
2763                // We already have the app running, or are waiting for it to
2764                // come up (we have a pid but not yet its thread), so keep it.
2765                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2766                // If this is a new package in the process, add the package to the list
2767                app.addPackage(info.packageName, mProcessStats);
2768                return app;
2769            }
2770
2771            // An application record is attached to a previous process,
2772            // clean it up now.
2773            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2774            handleAppDiedLocked(app, true, true);
2775        }
2776
2777        String hostingNameStr = hostingName != null
2778                ? hostingName.flattenToShortString() : null;
2779
2780        if (!isolated) {
2781            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2782                // If we are in the background, then check to see if this process
2783                // is bad.  If so, we will just silently fail.
2784                if (mBadProcesses.get(info.processName, info.uid) != null) {
2785                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2786                            + "/" + info.processName);
2787                    return null;
2788                }
2789            } else {
2790                // When the user is explicitly starting a process, then clear its
2791                // crash count so that we won't make it bad until they see at
2792                // least one crash dialog again, and make the process good again
2793                // if it had been bad.
2794                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2795                        + "/" + info.processName);
2796                mProcessCrashTimes.remove(info.processName, info.uid);
2797                if (mBadProcesses.get(info.processName, info.uid) != null) {
2798                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2799                            UserHandle.getUserId(info.uid), info.uid,
2800                            info.processName);
2801                    mBadProcesses.remove(info.processName, info.uid);
2802                    if (app != null) {
2803                        app.bad = false;
2804                    }
2805                }
2806            }
2807        }
2808
2809        if (app == null) {
2810            app = newProcessRecordLocked(info, processName, isolated);
2811            if (app == null) {
2812                Slog.w(TAG, "Failed making new process record for "
2813                        + processName + "/" + info.uid + " isolated=" + isolated);
2814                return null;
2815            }
2816            mProcessNames.put(processName, app.uid, app);
2817            if (isolated) {
2818                mIsolatedProcesses.put(app.uid, app);
2819            }
2820        } else {
2821            // If this is a new package in the process, add the package to the list
2822            app.addPackage(info.packageName, mProcessStats);
2823        }
2824
2825        // If the system is not ready yet, then hold off on starting this
2826        // process until it is.
2827        if (!mProcessesReady
2828                && !isAllowedWhileBooting(info)
2829                && !allowWhileBooting) {
2830            if (!mProcessesOnHold.contains(app)) {
2831                mProcessesOnHold.add(app);
2832            }
2833            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2834            return app;
2835        }
2836
2837        startProcessLocked(app, hostingType, hostingNameStr);
2838        return (app.pid != 0) ? app : null;
2839    }
2840
2841    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2842        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2843    }
2844
2845    private final void startProcessLocked(ProcessRecord app,
2846            String hostingType, String hostingNameStr) {
2847        if (app.pid > 0 && app.pid != MY_PID) {
2848            synchronized (mPidsSelfLocked) {
2849                mPidsSelfLocked.remove(app.pid);
2850                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2851            }
2852            app.setPid(0);
2853        }
2854
2855        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2856                "startProcessLocked removing on hold: " + app);
2857        mProcessesOnHold.remove(app);
2858
2859        updateCpuStats();
2860
2861        try {
2862            int uid = app.uid;
2863
2864            int[] gids = null;
2865            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2866            if (!app.isolated) {
2867                int[] permGids = null;
2868                try {
2869                    final PackageManager pm = mContext.getPackageManager();
2870                    permGids = pm.getPackageGids(app.info.packageName);
2871
2872                    if (Environment.isExternalStorageEmulated()) {
2873                        if (pm.checkPermission(
2874                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2875                                app.info.packageName) == PERMISSION_GRANTED) {
2876                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2877                        } else {
2878                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2879                        }
2880                    }
2881                } catch (PackageManager.NameNotFoundException e) {
2882                    Slog.w(TAG, "Unable to retrieve gids", e);
2883                }
2884
2885                /*
2886                 * Add shared application GID so applications can share some
2887                 * resources like shared libraries
2888                 */
2889                if (permGids == null) {
2890                    gids = new int[1];
2891                } else {
2892                    gids = new int[permGids.length + 1];
2893                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2894                }
2895                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2896            }
2897            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2898                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2899                        && mTopComponent != null
2900                        && app.processName.equals(mTopComponent.getPackageName())) {
2901                    uid = 0;
2902                }
2903                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2904                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2905                    uid = 0;
2906                }
2907            }
2908            int debugFlags = 0;
2909            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2910                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2911                // Also turn on CheckJNI for debuggable apps. It's quite
2912                // awkward to turn on otherwise.
2913                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2914            }
2915            // Run the app in safe mode if its manifest requests so or the
2916            // system is booted in safe mode.
2917            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2918                mSafeMode == true) {
2919                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2920            }
2921            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2922                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2923            }
2924            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2925                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2926            }
2927            if ("1".equals(SystemProperties.get("debug.assert"))) {
2928                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2929            }
2930
2931            String requiredAbi = app.info.cpuAbi;
2932            if (requiredAbi == null) {
2933                requiredAbi = Build.SUPPORTED_ABIS[0];
2934            }
2935
2936            // Start the process.  It will either succeed and return a result containing
2937            // the PID of the new process, or else throw a RuntimeException.
2938            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2939                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2940                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2941
2942            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2943            synchronized (bs) {
2944                if (bs.isOnBattery()) {
2945                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2946                }
2947            }
2948
2949            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2950                    UserHandle.getUserId(uid), startResult.pid, uid,
2951                    app.processName, hostingType,
2952                    hostingNameStr != null ? hostingNameStr : "");
2953
2954            if (app.persistent) {
2955                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2956            }
2957
2958            StringBuilder buf = mStringBuilder;
2959            buf.setLength(0);
2960            buf.append("Start proc ");
2961            buf.append(app.processName);
2962            buf.append(" for ");
2963            buf.append(hostingType);
2964            if (hostingNameStr != null) {
2965                buf.append(" ");
2966                buf.append(hostingNameStr);
2967            }
2968            buf.append(": pid=");
2969            buf.append(startResult.pid);
2970            buf.append(" uid=");
2971            buf.append(uid);
2972            buf.append(" gids={");
2973            if (gids != null) {
2974                for (int gi=0; gi<gids.length; gi++) {
2975                    if (gi != 0) buf.append(", ");
2976                    buf.append(gids[gi]);
2977
2978                }
2979            }
2980            buf.append("}");
2981            Slog.i(TAG, buf.toString());
2982            app.setPid(startResult.pid);
2983            app.usingWrapper = startResult.usingWrapper;
2984            app.removed = false;
2985            synchronized (mPidsSelfLocked) {
2986                this.mPidsSelfLocked.put(startResult.pid, app);
2987                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2988                msg.obj = app;
2989                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2990                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2991            }
2992            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2993                    app.processName, app.info.uid);
2994            if (app.isolated) {
2995                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2996            }
2997        } catch (RuntimeException e) {
2998            // XXX do better error recovery.
2999            app.setPid(0);
3000            Slog.e(TAG, "Failure starting process " + app.processName, e);
3001        }
3002    }
3003
3004    void updateUsageStats(ActivityRecord component, boolean resumed) {
3005        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3006        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3007        if (resumed) {
3008            mUsageStatsService.noteResumeComponent(component.realActivity);
3009            synchronized (stats) {
3010                stats.noteActivityResumedLocked(component.app.uid);
3011            }
3012        } else {
3013            mUsageStatsService.notePauseComponent(component.realActivity);
3014            synchronized (stats) {
3015                stats.noteActivityPausedLocked(component.app.uid);
3016            }
3017        }
3018    }
3019
3020    Intent getHomeIntent() {
3021        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3022        intent.setComponent(mTopComponent);
3023        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3024            intent.addCategory(Intent.CATEGORY_HOME);
3025        }
3026        return intent;
3027    }
3028
3029    boolean startHomeActivityLocked(int userId) {
3030        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3031                && mTopAction == null) {
3032            // We are running in factory test mode, but unable to find
3033            // the factory test app, so just sit around displaying the
3034            // error message and don't try to start anything.
3035            return false;
3036        }
3037        Intent intent = getHomeIntent();
3038        ActivityInfo aInfo =
3039            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3040        if (aInfo != null) {
3041            intent.setComponent(new ComponentName(
3042                    aInfo.applicationInfo.packageName, aInfo.name));
3043            // Don't do this if the home app is currently being
3044            // instrumented.
3045            aInfo = new ActivityInfo(aInfo);
3046            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3047            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3048                    aInfo.applicationInfo.uid, true);
3049            if (app == null || app.instrumentationClass == null) {
3050                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3051                mStackSupervisor.startHomeActivity(intent, aInfo);
3052            }
3053        }
3054
3055        return true;
3056    }
3057
3058    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3059        ActivityInfo ai = null;
3060        ComponentName comp = intent.getComponent();
3061        try {
3062            if (comp != null) {
3063                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3064            } else {
3065                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3066                        intent,
3067                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3068                            flags, userId);
3069
3070                if (info != null) {
3071                    ai = info.activityInfo;
3072                }
3073            }
3074        } catch (RemoteException e) {
3075            // ignore
3076        }
3077
3078        return ai;
3079    }
3080
3081    /**
3082     * Starts the "new version setup screen" if appropriate.
3083     */
3084    void startSetupActivityLocked() {
3085        // Only do this once per boot.
3086        if (mCheckedForSetup) {
3087            return;
3088        }
3089
3090        // We will show this screen if the current one is a different
3091        // version than the last one shown, and we are not running in
3092        // low-level factory test mode.
3093        final ContentResolver resolver = mContext.getContentResolver();
3094        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3095                Settings.Global.getInt(resolver,
3096                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3097            mCheckedForSetup = true;
3098
3099            // See if we should be showing the platform update setup UI.
3100            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3101            List<ResolveInfo> ris = mContext.getPackageManager()
3102                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3103
3104            // We don't allow third party apps to replace this.
3105            ResolveInfo ri = null;
3106            for (int i=0; ris != null && i<ris.size(); i++) {
3107                if ((ris.get(i).activityInfo.applicationInfo.flags
3108                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3109                    ri = ris.get(i);
3110                    break;
3111                }
3112            }
3113
3114            if (ri != null) {
3115                String vers = ri.activityInfo.metaData != null
3116                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3117                        : null;
3118                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3119                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3120                            Intent.METADATA_SETUP_VERSION);
3121                }
3122                String lastVers = Settings.Secure.getString(
3123                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3124                if (vers != null && !vers.equals(lastVers)) {
3125                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3126                    intent.setComponent(new ComponentName(
3127                            ri.activityInfo.packageName, ri.activityInfo.name));
3128                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3129                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3130                }
3131            }
3132        }
3133    }
3134
3135    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3136        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3137    }
3138
3139    void enforceNotIsolatedCaller(String caller) {
3140        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3141            throw new SecurityException("Isolated process not allowed to call " + caller);
3142        }
3143    }
3144
3145    @Override
3146    public int getFrontActivityScreenCompatMode() {
3147        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3148        synchronized (this) {
3149            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3150        }
3151    }
3152
3153    @Override
3154    public void setFrontActivityScreenCompatMode(int mode) {
3155        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3156                "setFrontActivityScreenCompatMode");
3157        synchronized (this) {
3158            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3159        }
3160    }
3161
3162    @Override
3163    public int getPackageScreenCompatMode(String packageName) {
3164        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3165        synchronized (this) {
3166            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3167        }
3168    }
3169
3170    @Override
3171    public void setPackageScreenCompatMode(String packageName, int mode) {
3172        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3173                "setPackageScreenCompatMode");
3174        synchronized (this) {
3175            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3176        }
3177    }
3178
3179    @Override
3180    public boolean getPackageAskScreenCompat(String packageName) {
3181        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3182        synchronized (this) {
3183            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3184        }
3185    }
3186
3187    @Override
3188    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3189        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3190                "setPackageAskScreenCompat");
3191        synchronized (this) {
3192            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3193        }
3194    }
3195
3196    private void dispatchProcessesChanged() {
3197        int N;
3198        synchronized (this) {
3199            N = mPendingProcessChanges.size();
3200            if (mActiveProcessChanges.length < N) {
3201                mActiveProcessChanges = new ProcessChangeItem[N];
3202            }
3203            mPendingProcessChanges.toArray(mActiveProcessChanges);
3204            mAvailProcessChanges.addAll(mPendingProcessChanges);
3205            mPendingProcessChanges.clear();
3206            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3207        }
3208
3209        int i = mProcessObservers.beginBroadcast();
3210        while (i > 0) {
3211            i--;
3212            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3213            if (observer != null) {
3214                try {
3215                    for (int j=0; j<N; j++) {
3216                        ProcessChangeItem item = mActiveProcessChanges[j];
3217                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3218                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3219                                    + item.pid + " uid=" + item.uid + ": "
3220                                    + item.foregroundActivities);
3221                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3222                                    item.foregroundActivities);
3223                        }
3224                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3225                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3226                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3227                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3228                        }
3229                    }
3230                } catch (RemoteException e) {
3231                }
3232            }
3233        }
3234        mProcessObservers.finishBroadcast();
3235    }
3236
3237    private void dispatchProcessDied(int pid, int uid) {
3238        int i = mProcessObservers.beginBroadcast();
3239        while (i > 0) {
3240            i--;
3241            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3242            if (observer != null) {
3243                try {
3244                    observer.onProcessDied(pid, uid);
3245                } catch (RemoteException e) {
3246                }
3247            }
3248        }
3249        mProcessObservers.finishBroadcast();
3250    }
3251
3252    final void doPendingActivityLaunchesLocked(boolean doResume) {
3253        final int N = mPendingActivityLaunches.size();
3254        if (N <= 0) {
3255            return;
3256        }
3257        for (int i=0; i<N; i++) {
3258            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3259            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3260                    doResume && i == (N-1), null);
3261        }
3262        mPendingActivityLaunches.clear();
3263    }
3264
3265    @Override
3266    public final int startActivity(IApplicationThread caller, String callingPackage,
3267            Intent intent, String resolvedType, IBinder resultTo,
3268            String resultWho, int requestCode, int startFlags,
3269            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3270        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3271                resultWho, requestCode,
3272                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3273    }
3274
3275    @Override
3276    public final int startActivityAsUser(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, int userId) {
3280        enforceNotIsolatedCaller("startActivity");
3281        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3282                false, true, "startActivity", null);
3283        // TODO: Switch to user app stacks here.
3284        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3285                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3286                null, null, options, userId, null);
3287    }
3288
3289    @Override
3290    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3291            Intent intent, String resolvedType, IBinder resultTo,
3292            String resultWho, int requestCode, int startFlags, String profileFile,
3293            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3294        enforceNotIsolatedCaller("startActivityAndWait");
3295        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3296                false, true, "startActivityAndWait", null);
3297        WaitResult res = new WaitResult();
3298        // TODO: Switch to user app stacks here.
3299        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3300                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3301                res, null, options, UserHandle.getCallingUserId(), null);
3302        return res;
3303    }
3304
3305    @Override
3306    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3307            Intent intent, String resolvedType, IBinder resultTo,
3308            String resultWho, int requestCode, int startFlags, Configuration config,
3309            Bundle options, int userId) {
3310        enforceNotIsolatedCaller("startActivityWithConfig");
3311        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3312                false, true, "startActivityWithConfig", null);
3313        // TODO: Switch to user app stacks here.
3314        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3315                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3316                null, null, null, config, options, userId, null);
3317        return ret;
3318    }
3319
3320    @Override
3321    public int startActivityIntentSender(IApplicationThread caller,
3322            IntentSender intent, Intent fillInIntent, String resolvedType,
3323            IBinder resultTo, String resultWho, int requestCode,
3324            int flagsMask, int flagsValues, Bundle options) {
3325        enforceNotIsolatedCaller("startActivityIntentSender");
3326        // Refuse possible leaked file descriptors
3327        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3328            throw new IllegalArgumentException("File descriptors passed in Intent");
3329        }
3330
3331        IIntentSender sender = intent.getTarget();
3332        if (!(sender instanceof PendingIntentRecord)) {
3333            throw new IllegalArgumentException("Bad PendingIntent object");
3334        }
3335
3336        PendingIntentRecord pir = (PendingIntentRecord)sender;
3337
3338        synchronized (this) {
3339            // If this is coming from the currently resumed activity, it is
3340            // effectively saying that app switches are allowed at this point.
3341            final ActivityStack stack = getFocusedStack();
3342            if (stack.mResumedActivity != null &&
3343                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3344                mAppSwitchesAllowedTime = 0;
3345            }
3346        }
3347        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3348                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3349        return ret;
3350    }
3351
3352    @Override
3353    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3354            Intent intent, String resolvedType, IVoiceInteractionSession session,
3355            IVoiceInteractor interactor, int startFlags, String profileFile,
3356            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3357        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3358                != PackageManager.PERMISSION_GRANTED) {
3359            String msg = "Permission Denial: startVoiceActivity() from pid="
3360                    + Binder.getCallingPid()
3361                    + ", uid=" + Binder.getCallingUid()
3362                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3363            Slog.w(TAG, msg);
3364            throw new SecurityException(msg);
3365        }
3366        if (session == null || interactor == null) {
3367            throw new NullPointerException("null session or interactor");
3368        }
3369        userId = handleIncomingUser(callingPid, callingUid, userId,
3370                false, true, "startVoiceActivity", null);
3371        // TODO: Switch to user app stacks here.
3372        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3373                resolvedType, session, interactor, null, null, 0, startFlags,
3374                profileFile, profileFd, null, null, options, userId, null);
3375    }
3376
3377    @Override
3378    public boolean startNextMatchingActivity(IBinder callingActivity,
3379            Intent intent, Bundle options) {
3380        // Refuse possible leaked file descriptors
3381        if (intent != null && intent.hasFileDescriptors() == true) {
3382            throw new IllegalArgumentException("File descriptors passed in Intent");
3383        }
3384
3385        synchronized (this) {
3386            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3387            if (r == null) {
3388                ActivityOptions.abort(options);
3389                return false;
3390            }
3391            if (r.app == null || r.app.thread == null) {
3392                // The caller is not running...  d'oh!
3393                ActivityOptions.abort(options);
3394                return false;
3395            }
3396            intent = new Intent(intent);
3397            // The caller is not allowed to change the data.
3398            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3399            // And we are resetting to find the next component...
3400            intent.setComponent(null);
3401
3402            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3403
3404            ActivityInfo aInfo = null;
3405            try {
3406                List<ResolveInfo> resolves =
3407                    AppGlobals.getPackageManager().queryIntentActivities(
3408                            intent, r.resolvedType,
3409                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3410                            UserHandle.getCallingUserId());
3411
3412                // Look for the original activity in the list...
3413                final int N = resolves != null ? resolves.size() : 0;
3414                for (int i=0; i<N; i++) {
3415                    ResolveInfo rInfo = resolves.get(i);
3416                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3417                            && rInfo.activityInfo.name.equals(r.info.name)) {
3418                        // We found the current one...  the next matching is
3419                        // after it.
3420                        i++;
3421                        if (i<N) {
3422                            aInfo = resolves.get(i).activityInfo;
3423                        }
3424                        if (debug) {
3425                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3426                                    + "/" + r.info.name);
3427                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3428                                    + "/" + aInfo.name);
3429                        }
3430                        break;
3431                    }
3432                }
3433            } catch (RemoteException e) {
3434            }
3435
3436            if (aInfo == null) {
3437                // Nobody who is next!
3438                ActivityOptions.abort(options);
3439                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3440                return false;
3441            }
3442
3443            intent.setComponent(new ComponentName(
3444                    aInfo.applicationInfo.packageName, aInfo.name));
3445            intent.setFlags(intent.getFlags()&~(
3446                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3447                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3448                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3449                    Intent.FLAG_ACTIVITY_NEW_TASK));
3450
3451            // Okay now we need to start the new activity, replacing the
3452            // currently running activity.  This is a little tricky because
3453            // we want to start the new one as if the current one is finished,
3454            // but not finish the current one first so that there is no flicker.
3455            // And thus...
3456            final boolean wasFinishing = r.finishing;
3457            r.finishing = true;
3458
3459            // Propagate reply information over to the new activity.
3460            final ActivityRecord resultTo = r.resultTo;
3461            final String resultWho = r.resultWho;
3462            final int requestCode = r.requestCode;
3463            r.resultTo = null;
3464            if (resultTo != null) {
3465                resultTo.removeResultsLocked(r, resultWho, requestCode);
3466            }
3467
3468            final long origId = Binder.clearCallingIdentity();
3469            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3470                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3471                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3472                    options, false, null, null);
3473            Binder.restoreCallingIdentity(origId);
3474
3475            r.finishing = wasFinishing;
3476            if (res != ActivityManager.START_SUCCESS) {
3477                return false;
3478            }
3479            return true;
3480        }
3481    }
3482
3483    final int startActivityInPackage(int uid, String callingPackage,
3484            Intent intent, String resolvedType, IBinder resultTo,
3485            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3486                    IActivityContainer container) {
3487
3488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3489                false, true, "startActivityInPackage", null);
3490
3491        // TODO: Switch to user app stacks here.
3492        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3493                null, null, resultTo, resultWho, requestCode, startFlags,
3494                null, null, null, null, options, userId, container);
3495        return ret;
3496    }
3497
3498    @Override
3499    public final int startActivities(IApplicationThread caller, String callingPackage,
3500            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3501            int userId) {
3502        enforceNotIsolatedCaller("startActivities");
3503        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3504                false, true, "startActivity", null);
3505        // TODO: Switch to user app stacks here.
3506        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3507                resolvedTypes, resultTo, options, userId);
3508        return ret;
3509    }
3510
3511    final int startActivitiesInPackage(int uid, String callingPackage,
3512            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3513            Bundle options, int userId) {
3514
3515        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3516                false, true, "startActivityInPackage", null);
3517        // TODO: Switch to user app stacks here.
3518        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3519                resultTo, options, userId);
3520        return ret;
3521    }
3522
3523    final void addRecentTaskLocked(TaskRecord task) {
3524        int N = mRecentTasks.size();
3525        // Quick case: check if the top-most recent task is the same.
3526        if (N > 0 && mRecentTasks.get(0) == task) {
3527            return;
3528        }
3529        // Another quick case: never add voice sessions.
3530        if (task.voiceSession != null) {
3531            return;
3532        }
3533        // Remove any existing entries that are the same kind of task.
3534        final Intent intent = task.intent;
3535        final boolean document = intent != null && intent.isDocument();
3536        for (int i=0; i<N; i++) {
3537            TaskRecord tr = mRecentTasks.get(i);
3538            if (task != tr) {
3539                if (task.userId != tr.userId) {
3540                    continue;
3541                }
3542                final Intent trIntent = tr.intent;
3543                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3544                    (intent == null || !intent.filterEquals(trIntent))) {
3545                    continue;
3546                }
3547                if (document || trIntent != null && trIntent.isDocument()) {
3548                    // Document tasks do not match other tasks.
3549                    continue;
3550                }
3551            }
3552
3553            // Either task and tr are the same or, their affinities match or their intents match
3554            // and neither of them is a document.
3555            tr.disposeThumbnail();
3556            mRecentTasks.remove(i);
3557            i--;
3558            N--;
3559            if (task.intent == null) {
3560                // If the new recent task we are adding is not fully
3561                // specified, then replace it with the existing recent task.
3562                task = tr;
3563            }
3564        }
3565        if (N >= MAX_RECENT_TASKS) {
3566            mRecentTasks.remove(N-1).disposeThumbnail();
3567        }
3568        mRecentTasks.add(0, task);
3569    }
3570
3571    @Override
3572    public void reportActivityFullyDrawn(IBinder token) {
3573        synchronized (this) {
3574            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3575            if (r == null) {
3576                return;
3577            }
3578            r.reportFullyDrawnLocked();
3579        }
3580    }
3581
3582    @Override
3583    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3584        synchronized (this) {
3585            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3586            if (r == null) {
3587                return;
3588            }
3589            final long origId = Binder.clearCallingIdentity();
3590            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3591            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3592                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3593            if (config != null) {
3594                r.frozenBeforeDestroy = true;
3595                if (!updateConfigurationLocked(config, r, false, false)) {
3596                    mStackSupervisor.resumeTopActivitiesLocked();
3597                }
3598            }
3599            Binder.restoreCallingIdentity(origId);
3600        }
3601    }
3602
3603    @Override
3604    public int getRequestedOrientation(IBinder token) {
3605        synchronized (this) {
3606            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3607            if (r == null) {
3608                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3609            }
3610            return mWindowManager.getAppOrientation(r.appToken);
3611        }
3612    }
3613
3614    /**
3615     * This is the internal entry point for handling Activity.finish().
3616     *
3617     * @param token The Binder token referencing the Activity we want to finish.
3618     * @param resultCode Result code, if any, from this Activity.
3619     * @param resultData Result data (Intent), if any, from this Activity.
3620     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3621     *            the root Activity in the task.
3622     *
3623     * @return Returns true if the activity successfully finished, or false if it is still running.
3624     */
3625    @Override
3626    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3627            boolean finishTask) {
3628        // Refuse possible leaked file descriptors
3629        if (resultData != null && resultData.hasFileDescriptors() == true) {
3630            throw new IllegalArgumentException("File descriptors passed in Intent");
3631        }
3632
3633        synchronized(this) {
3634            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3635            if (r == null) {
3636                return true;
3637            }
3638            // Keep track of the root activity of the task before we finish it
3639            TaskRecord tr = r.task;
3640            ActivityRecord rootR = tr.getRootActivity();
3641            if (mController != null) {
3642                // Find the first activity that is not finishing.
3643                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3644                if (next != null) {
3645                    // ask watcher if this is allowed
3646                    boolean resumeOK = true;
3647                    try {
3648                        resumeOK = mController.activityResuming(next.packageName);
3649                    } catch (RemoteException e) {
3650                        mController = null;
3651                        Watchdog.getInstance().setActivityController(null);
3652                    }
3653
3654                    if (!resumeOK) {
3655                        return false;
3656                    }
3657                }
3658            }
3659            final long origId = Binder.clearCallingIdentity();
3660            try {
3661                boolean res;
3662                if (finishTask && r == rootR) {
3663                    // If requested, remove the task that is associated to this activity only if it
3664                    // was the root activity in the task.  The result code and data is ignored because
3665                    // we don't support returning them across task boundaries.
3666                    res = removeTaskByIdLocked(tr.taskId, 0);
3667                } else {
3668                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3669                            resultData, "app-request", true);
3670                }
3671                return res;
3672            } finally {
3673                Binder.restoreCallingIdentity(origId);
3674            }
3675        }
3676    }
3677
3678    @Override
3679    public final void finishHeavyWeightApp() {
3680        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3681                != PackageManager.PERMISSION_GRANTED) {
3682            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3683                    + Binder.getCallingPid()
3684                    + ", uid=" + Binder.getCallingUid()
3685                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3686            Slog.w(TAG, msg);
3687            throw new SecurityException(msg);
3688        }
3689
3690        synchronized(this) {
3691            if (mHeavyWeightProcess == null) {
3692                return;
3693            }
3694
3695            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3696                    mHeavyWeightProcess.activities);
3697            for (int i=0; i<activities.size(); i++) {
3698                ActivityRecord r = activities.get(i);
3699                if (!r.finishing) {
3700                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3701                            null, "finish-heavy", true);
3702                }
3703            }
3704
3705            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3706                    mHeavyWeightProcess.userId, 0));
3707            mHeavyWeightProcess = null;
3708        }
3709    }
3710
3711    @Override
3712    public void crashApplication(int uid, int initialPid, String packageName,
3713            String message) {
3714        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3715                != PackageManager.PERMISSION_GRANTED) {
3716            String msg = "Permission Denial: crashApplication() from pid="
3717                    + Binder.getCallingPid()
3718                    + ", uid=" + Binder.getCallingUid()
3719                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3720            Slog.w(TAG, msg);
3721            throw new SecurityException(msg);
3722        }
3723
3724        synchronized(this) {
3725            ProcessRecord proc = null;
3726
3727            // Figure out which process to kill.  We don't trust that initialPid
3728            // still has any relation to current pids, so must scan through the
3729            // list.
3730            synchronized (mPidsSelfLocked) {
3731                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3732                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3733                    if (p.uid != uid) {
3734                        continue;
3735                    }
3736                    if (p.pid == initialPid) {
3737                        proc = p;
3738                        break;
3739                    }
3740                    if (p.pkgList.containsKey(packageName)) {
3741                        proc = p;
3742                    }
3743                }
3744            }
3745
3746            if (proc == null) {
3747                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3748                        + " initialPid=" + initialPid
3749                        + " packageName=" + packageName);
3750                return;
3751            }
3752
3753            if (proc.thread != null) {
3754                if (proc.pid == Process.myPid()) {
3755                    Log.w(TAG, "crashApplication: trying to crash self!");
3756                    return;
3757                }
3758                long ident = Binder.clearCallingIdentity();
3759                try {
3760                    proc.thread.scheduleCrash(message);
3761                } catch (RemoteException e) {
3762                }
3763                Binder.restoreCallingIdentity(ident);
3764            }
3765        }
3766    }
3767
3768    @Override
3769    public final void finishSubActivity(IBinder token, String resultWho,
3770            int requestCode) {
3771        synchronized(this) {
3772            final long origId = Binder.clearCallingIdentity();
3773            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3774            if (r != null) {
3775                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3776            }
3777            Binder.restoreCallingIdentity(origId);
3778        }
3779    }
3780
3781    @Override
3782    public boolean finishActivityAffinity(IBinder token) {
3783        synchronized(this) {
3784            final long origId = Binder.clearCallingIdentity();
3785            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3786            boolean res = false;
3787            if (r != null) {
3788                res = r.task.stack.finishActivityAffinityLocked(r);
3789            }
3790            Binder.restoreCallingIdentity(origId);
3791            return res;
3792        }
3793    }
3794
3795    @Override
3796    public boolean willActivityBeVisible(IBinder token) {
3797        synchronized(this) {
3798            ActivityStack stack = ActivityRecord.getStackLocked(token);
3799            if (stack != null) {
3800                return stack.willActivityBeVisibleLocked(token);
3801            }
3802            return false;
3803        }
3804    }
3805
3806    @Override
3807    public void overridePendingTransition(IBinder token, String packageName,
3808            int enterAnim, int exitAnim) {
3809        synchronized(this) {
3810            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3811            if (self == null) {
3812                return;
3813            }
3814
3815            final long origId = Binder.clearCallingIdentity();
3816
3817            if (self.state == ActivityState.RESUMED
3818                    || self.state == ActivityState.PAUSING) {
3819                mWindowManager.overridePendingAppTransition(packageName,
3820                        enterAnim, exitAnim, null);
3821            }
3822
3823            Binder.restoreCallingIdentity(origId);
3824        }
3825    }
3826
3827    /**
3828     * Main function for removing an existing process from the activity manager
3829     * as a result of that process going away.  Clears out all connections
3830     * to the process.
3831     */
3832    private final void handleAppDiedLocked(ProcessRecord app,
3833            boolean restarting, boolean allowRestart) {
3834        int pid = app.pid;
3835        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3836        if (!restarting) {
3837            removeLruProcessLocked(app);
3838            if (pid > 0) {
3839                ProcessList.remove(pid);
3840            }
3841        }
3842
3843        if (mProfileProc == app) {
3844            clearProfilerLocked();
3845        }
3846
3847        // Remove this application's activities from active lists.
3848        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3849
3850        app.activities.clear();
3851
3852        if (app.instrumentationClass != null) {
3853            Slog.w(TAG, "Crash of app " + app.processName
3854                  + " running instrumentation " + app.instrumentationClass);
3855            Bundle info = new Bundle();
3856            info.putString("shortMsg", "Process crashed.");
3857            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3858        }
3859
3860        if (!restarting) {
3861            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3862                // If there was nothing to resume, and we are not already
3863                // restarting this process, but there is a visible activity that
3864                // is hosted by the process...  then make sure all visible
3865                // activities are running, taking care of restarting this
3866                // process.
3867                if (hasVisibleActivities) {
3868                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3869                }
3870            }
3871        }
3872    }
3873
3874    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3875        IBinder threadBinder = thread.asBinder();
3876        // Find the application record.
3877        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3878            ProcessRecord rec = mLruProcesses.get(i);
3879            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3880                return i;
3881            }
3882        }
3883        return -1;
3884    }
3885
3886    final ProcessRecord getRecordForAppLocked(
3887            IApplicationThread thread) {
3888        if (thread == null) {
3889            return null;
3890        }
3891
3892        int appIndex = getLRURecordIndexForAppLocked(thread);
3893        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3894    }
3895
3896    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3897        // If there are no longer any background processes running,
3898        // and the app that died was not running instrumentation,
3899        // then tell everyone we are now low on memory.
3900        boolean haveBg = false;
3901        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3902            ProcessRecord rec = mLruProcesses.get(i);
3903            if (rec.thread != null
3904                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3905                haveBg = true;
3906                break;
3907            }
3908        }
3909
3910        if (!haveBg) {
3911            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3912            if (doReport) {
3913                long now = SystemClock.uptimeMillis();
3914                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3915                    doReport = false;
3916                } else {
3917                    mLastMemUsageReportTime = now;
3918                }
3919            }
3920            final ArrayList<ProcessMemInfo> memInfos
3921                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3922            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3923            long now = SystemClock.uptimeMillis();
3924            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3925                ProcessRecord rec = mLruProcesses.get(i);
3926                if (rec == dyingProc || rec.thread == null) {
3927                    continue;
3928                }
3929                if (doReport) {
3930                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3931                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3932                }
3933                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3934                    // The low memory report is overriding any current
3935                    // state for a GC request.  Make sure to do
3936                    // heavy/important/visible/foreground processes first.
3937                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3938                        rec.lastRequestedGc = 0;
3939                    } else {
3940                        rec.lastRequestedGc = rec.lastLowMemory;
3941                    }
3942                    rec.reportLowMemory = true;
3943                    rec.lastLowMemory = now;
3944                    mProcessesToGc.remove(rec);
3945                    addProcessToGcListLocked(rec);
3946                }
3947            }
3948            if (doReport) {
3949                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3950                mHandler.sendMessage(msg);
3951            }
3952            scheduleAppGcsLocked();
3953        }
3954    }
3955
3956    final void appDiedLocked(ProcessRecord app, int pid,
3957            IApplicationThread thread) {
3958
3959        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3960        synchronized (stats) {
3961            stats.noteProcessDiedLocked(app.info.uid, pid);
3962        }
3963
3964        // Clean up already done if the process has been re-started.
3965        if (app.pid == pid && app.thread != null &&
3966                app.thread.asBinder() == thread.asBinder()) {
3967            boolean doLowMem = app.instrumentationClass == null;
3968            boolean doOomAdj = doLowMem;
3969            if (!app.killedByAm) {
3970                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3971                        + ") has died.");
3972                mAllowLowerMemLevel = true;
3973            } else {
3974                // Note that we always want to do oom adj to update our state with the
3975                // new number of procs.
3976                mAllowLowerMemLevel = false;
3977                doLowMem = false;
3978            }
3979            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3980            if (DEBUG_CLEANUP) Slog.v(
3981                TAG, "Dying app: " + app + ", pid: " + pid
3982                + ", thread: " + thread.asBinder());
3983            handleAppDiedLocked(app, false, true);
3984
3985            if (doOomAdj) {
3986                updateOomAdjLocked();
3987            }
3988            if (doLowMem) {
3989                doLowMemReportIfNeededLocked(app);
3990            }
3991        } else if (app.pid != pid) {
3992            // A new process has already been started.
3993            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3994                    + ") has died and restarted (pid " + app.pid + ").");
3995            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3996        } else if (DEBUG_PROCESSES) {
3997            Slog.d(TAG, "Received spurious death notification for thread "
3998                    + thread.asBinder());
3999        }
4000    }
4001
4002    /**
4003     * If a stack trace dump file is configured, dump process stack traces.
4004     * @param clearTraces causes the dump file to be erased prior to the new
4005     *    traces being written, if true; when false, the new traces will be
4006     *    appended to any existing file content.
4007     * @param firstPids of dalvik VM processes to dump stack traces for first
4008     * @param lastPids of dalvik VM processes to dump stack traces for last
4009     * @param nativeProcs optional list of native process names to dump stack crawls
4010     * @return file containing stack traces, or null if no dump file is configured
4011     */
4012    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4013            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4014        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4015        if (tracesPath == null || tracesPath.length() == 0) {
4016            return null;
4017        }
4018
4019        File tracesFile = new File(tracesPath);
4020        try {
4021            File tracesDir = tracesFile.getParentFile();
4022            if (!tracesDir.exists()) {
4023                tracesFile.mkdirs();
4024                if (!SELinux.restorecon(tracesDir)) {
4025                    return null;
4026                }
4027            }
4028            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4029
4030            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4031            tracesFile.createNewFile();
4032            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4033        } catch (IOException e) {
4034            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4035            return null;
4036        }
4037
4038        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4039        return tracesFile;
4040    }
4041
4042    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4043            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4044        // Use a FileObserver to detect when traces finish writing.
4045        // The order of traces is considered important to maintain for legibility.
4046        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4047            @Override
4048            public synchronized void onEvent(int event, String path) { notify(); }
4049        };
4050
4051        try {
4052            observer.startWatching();
4053
4054            // First collect all of the stacks of the most important pids.
4055            if (firstPids != null) {
4056                try {
4057                    int num = firstPids.size();
4058                    for (int i = 0; i < num; i++) {
4059                        synchronized (observer) {
4060                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4061                            observer.wait(200);  // Wait for write-close, give up after 200msec
4062                        }
4063                    }
4064                } catch (InterruptedException e) {
4065                    Log.wtf(TAG, e);
4066                }
4067            }
4068
4069            // Next collect the stacks of the native pids
4070            if (nativeProcs != null) {
4071                int[] pids = Process.getPidsForCommands(nativeProcs);
4072                if (pids != null) {
4073                    for (int pid : pids) {
4074                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4075                    }
4076                }
4077            }
4078
4079            // Lastly, measure CPU usage.
4080            if (processCpuTracker != null) {
4081                processCpuTracker.init();
4082                System.gc();
4083                processCpuTracker.update();
4084                try {
4085                    synchronized (processCpuTracker) {
4086                        processCpuTracker.wait(500); // measure over 1/2 second.
4087                    }
4088                } catch (InterruptedException e) {
4089                }
4090                processCpuTracker.update();
4091
4092                // We'll take the stack crawls of just the top apps using CPU.
4093                final int N = processCpuTracker.countWorkingStats();
4094                int numProcs = 0;
4095                for (int i=0; i<N && numProcs<5; i++) {
4096                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4097                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4098                        numProcs++;
4099                        try {
4100                            synchronized (observer) {
4101                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4102                                observer.wait(200);  // Wait for write-close, give up after 200msec
4103                            }
4104                        } catch (InterruptedException e) {
4105                            Log.wtf(TAG, e);
4106                        }
4107
4108                    }
4109                }
4110            }
4111        } finally {
4112            observer.stopWatching();
4113        }
4114    }
4115
4116    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4117        if (true || IS_USER_BUILD) {
4118            return;
4119        }
4120        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4121        if (tracesPath == null || tracesPath.length() == 0) {
4122            return;
4123        }
4124
4125        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4126        StrictMode.allowThreadDiskWrites();
4127        try {
4128            final File tracesFile = new File(tracesPath);
4129            final File tracesDir = tracesFile.getParentFile();
4130            final File tracesTmp = new File(tracesDir, "__tmp__");
4131            try {
4132                if (!tracesDir.exists()) {
4133                    tracesFile.mkdirs();
4134                    if (!SELinux.restorecon(tracesDir.getPath())) {
4135                        return;
4136                    }
4137                }
4138                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4139
4140                if (tracesFile.exists()) {
4141                    tracesTmp.delete();
4142                    tracesFile.renameTo(tracesTmp);
4143                }
4144                StringBuilder sb = new StringBuilder();
4145                Time tobj = new Time();
4146                tobj.set(System.currentTimeMillis());
4147                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4148                sb.append(": ");
4149                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4150                sb.append(" since ");
4151                sb.append(msg);
4152                FileOutputStream fos = new FileOutputStream(tracesFile);
4153                fos.write(sb.toString().getBytes());
4154                if (app == null) {
4155                    fos.write("\n*** No application process!".getBytes());
4156                }
4157                fos.close();
4158                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4159            } catch (IOException e) {
4160                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4161                return;
4162            }
4163
4164            if (app != null) {
4165                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4166                firstPids.add(app.pid);
4167                dumpStackTraces(tracesPath, firstPids, null, null, null);
4168            }
4169
4170            File lastTracesFile = null;
4171            File curTracesFile = null;
4172            for (int i=9; i>=0; i--) {
4173                String name = String.format(Locale.US, "slow%02d.txt", i);
4174                curTracesFile = new File(tracesDir, name);
4175                if (curTracesFile.exists()) {
4176                    if (lastTracesFile != null) {
4177                        curTracesFile.renameTo(lastTracesFile);
4178                    } else {
4179                        curTracesFile.delete();
4180                    }
4181                }
4182                lastTracesFile = curTracesFile;
4183            }
4184            tracesFile.renameTo(curTracesFile);
4185            if (tracesTmp.exists()) {
4186                tracesTmp.renameTo(tracesFile);
4187            }
4188        } finally {
4189            StrictMode.setThreadPolicy(oldPolicy);
4190        }
4191    }
4192
4193    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4194            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4195        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4196        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4197
4198        if (mController != null) {
4199            try {
4200                // 0 == continue, -1 = kill process immediately
4201                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4202                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4203            } catch (RemoteException e) {
4204                mController = null;
4205                Watchdog.getInstance().setActivityController(null);
4206            }
4207        }
4208
4209        long anrTime = SystemClock.uptimeMillis();
4210        if (MONITOR_CPU_USAGE) {
4211            updateCpuStatsNow();
4212        }
4213
4214        synchronized (this) {
4215            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4216            if (mShuttingDown) {
4217                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4218                return;
4219            } else if (app.notResponding) {
4220                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4221                return;
4222            } else if (app.crashing) {
4223                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4224                return;
4225            }
4226
4227            // In case we come through here for the same app before completing
4228            // this one, mark as anring now so we will bail out.
4229            app.notResponding = true;
4230
4231            // Log the ANR to the event log.
4232            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4233                    app.processName, app.info.flags, annotation);
4234
4235            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4236            firstPids.add(app.pid);
4237
4238            int parentPid = app.pid;
4239            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4240            if (parentPid != app.pid) firstPids.add(parentPid);
4241
4242            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4243
4244            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4245                ProcessRecord r = mLruProcesses.get(i);
4246                if (r != null && r.thread != null) {
4247                    int pid = r.pid;
4248                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4249                        if (r.persistent) {
4250                            firstPids.add(pid);
4251                        } else {
4252                            lastPids.put(pid, Boolean.TRUE);
4253                        }
4254                    }
4255                }
4256            }
4257        }
4258
4259        // Log the ANR to the main log.
4260        StringBuilder info = new StringBuilder();
4261        info.setLength(0);
4262        info.append("ANR in ").append(app.processName);
4263        if (activity != null && activity.shortComponentName != null) {
4264            info.append(" (").append(activity.shortComponentName).append(")");
4265        }
4266        info.append("\n");
4267        info.append("PID: ").append(app.pid).append("\n");
4268        if (annotation != null) {
4269            info.append("Reason: ").append(annotation).append("\n");
4270        }
4271        if (parent != null && parent != activity) {
4272            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4273        }
4274
4275        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4276
4277        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4278                NATIVE_STACKS_OF_INTEREST);
4279
4280        String cpuInfo = null;
4281        if (MONITOR_CPU_USAGE) {
4282            updateCpuStatsNow();
4283            synchronized (mProcessCpuThread) {
4284                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4285            }
4286            info.append(processCpuTracker.printCurrentLoad());
4287            info.append(cpuInfo);
4288        }
4289
4290        info.append(processCpuTracker.printCurrentState(anrTime));
4291
4292        Slog.e(TAG, info.toString());
4293        if (tracesFile == null) {
4294            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4295            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4296        }
4297
4298        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4299                cpuInfo, tracesFile, null);
4300
4301        if (mController != null) {
4302            try {
4303                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4304                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4305                if (res != 0) {
4306                    if (res < 0 && app.pid != MY_PID) {
4307                        Process.killProcess(app.pid);
4308                    } else {
4309                        synchronized (this) {
4310                            mServices.scheduleServiceTimeoutLocked(app);
4311                        }
4312                    }
4313                    return;
4314                }
4315            } catch (RemoteException e) {
4316                mController = null;
4317                Watchdog.getInstance().setActivityController(null);
4318            }
4319        }
4320
4321        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4322        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4323                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4324
4325        synchronized (this) {
4326            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4327                killUnneededProcessLocked(app, "background ANR");
4328                return;
4329            }
4330
4331            // Set the app's notResponding state, and look up the errorReportReceiver
4332            makeAppNotRespondingLocked(app,
4333                    activity != null ? activity.shortComponentName : null,
4334                    annotation != null ? "ANR " + annotation : "ANR",
4335                    info.toString());
4336
4337            // Bring up the infamous App Not Responding dialog
4338            Message msg = Message.obtain();
4339            HashMap<String, Object> map = new HashMap<String, Object>();
4340            msg.what = SHOW_NOT_RESPONDING_MSG;
4341            msg.obj = map;
4342            msg.arg1 = aboveSystem ? 1 : 0;
4343            map.put("app", app);
4344            if (activity != null) {
4345                map.put("activity", activity);
4346            }
4347
4348            mHandler.sendMessage(msg);
4349        }
4350    }
4351
4352    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4353        if (!mLaunchWarningShown) {
4354            mLaunchWarningShown = true;
4355            mHandler.post(new Runnable() {
4356                @Override
4357                public void run() {
4358                    synchronized (ActivityManagerService.this) {
4359                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4360                        d.show();
4361                        mHandler.postDelayed(new Runnable() {
4362                            @Override
4363                            public void run() {
4364                                synchronized (ActivityManagerService.this) {
4365                                    d.dismiss();
4366                                    mLaunchWarningShown = false;
4367                                }
4368                            }
4369                        }, 4000);
4370                    }
4371                }
4372            });
4373        }
4374    }
4375
4376    @Override
4377    public boolean clearApplicationUserData(final String packageName,
4378            final IPackageDataObserver observer, int userId) {
4379        enforceNotIsolatedCaller("clearApplicationUserData");
4380        int uid = Binder.getCallingUid();
4381        int pid = Binder.getCallingPid();
4382        userId = handleIncomingUser(pid, uid,
4383                userId, false, true, "clearApplicationUserData", null);
4384        long callingId = Binder.clearCallingIdentity();
4385        try {
4386            IPackageManager pm = AppGlobals.getPackageManager();
4387            int pkgUid = -1;
4388            synchronized(this) {
4389                try {
4390                    pkgUid = pm.getPackageUid(packageName, userId);
4391                } catch (RemoteException e) {
4392                }
4393                if (pkgUid == -1) {
4394                    Slog.w(TAG, "Invalid packageName: " + packageName);
4395                    if (observer != null) {
4396                        try {
4397                            observer.onRemoveCompleted(packageName, false);
4398                        } catch (RemoteException e) {
4399                            Slog.i(TAG, "Observer no longer exists.");
4400                        }
4401                    }
4402                    return false;
4403                }
4404                if (uid == pkgUid || checkComponentPermission(
4405                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4406                        pid, uid, -1, true)
4407                        == PackageManager.PERMISSION_GRANTED) {
4408                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4409                } else {
4410                    throw new SecurityException("PID " + pid + " does not have permission "
4411                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4412                                    + " of package " + packageName);
4413                }
4414            }
4415
4416            try {
4417                // Clear application user data
4418                pm.clearApplicationUserData(packageName, observer, userId);
4419
4420                // Remove all permissions granted from/to this package
4421                removeUriPermissionsForPackageLocked(packageName, userId, true);
4422
4423                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4424                        Uri.fromParts("package", packageName, null));
4425                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4426                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4427                        null, null, 0, null, null, null, false, false, userId);
4428            } catch (RemoteException e) {
4429            }
4430        } finally {
4431            Binder.restoreCallingIdentity(callingId);
4432        }
4433        return true;
4434    }
4435
4436    @Override
4437    public void killBackgroundProcesses(final String packageName, int userId) {
4438        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4439                != PackageManager.PERMISSION_GRANTED &&
4440                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4441                        != PackageManager.PERMISSION_GRANTED) {
4442            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4443                    + Binder.getCallingPid()
4444                    + ", uid=" + Binder.getCallingUid()
4445                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4446            Slog.w(TAG, msg);
4447            throw new SecurityException(msg);
4448        }
4449
4450        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4451                userId, true, true, "killBackgroundProcesses", null);
4452        long callingId = Binder.clearCallingIdentity();
4453        try {
4454            IPackageManager pm = AppGlobals.getPackageManager();
4455            synchronized(this) {
4456                int appId = -1;
4457                try {
4458                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4459                } catch (RemoteException e) {
4460                }
4461                if (appId == -1) {
4462                    Slog.w(TAG, "Invalid packageName: " + packageName);
4463                    return;
4464                }
4465                killPackageProcessesLocked(packageName, appId, userId,
4466                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4467            }
4468        } finally {
4469            Binder.restoreCallingIdentity(callingId);
4470        }
4471    }
4472
4473    @Override
4474    public void killAllBackgroundProcesses() {
4475        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4476                != PackageManager.PERMISSION_GRANTED) {
4477            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4478                    + Binder.getCallingPid()
4479                    + ", uid=" + Binder.getCallingUid()
4480                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4481            Slog.w(TAG, msg);
4482            throw new SecurityException(msg);
4483        }
4484
4485        long callingId = Binder.clearCallingIdentity();
4486        try {
4487            synchronized(this) {
4488                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4489                final int NP = mProcessNames.getMap().size();
4490                for (int ip=0; ip<NP; ip++) {
4491                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4492                    final int NA = apps.size();
4493                    for (int ia=0; ia<NA; ia++) {
4494                        ProcessRecord app = apps.valueAt(ia);
4495                        if (app.persistent) {
4496                            // we don't kill persistent processes
4497                            continue;
4498                        }
4499                        if (app.removed) {
4500                            procs.add(app);
4501                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4502                            app.removed = true;
4503                            procs.add(app);
4504                        }
4505                    }
4506                }
4507
4508                int N = procs.size();
4509                for (int i=0; i<N; i++) {
4510                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4511                }
4512                mAllowLowerMemLevel = true;
4513                updateOomAdjLocked();
4514                doLowMemReportIfNeededLocked(null);
4515            }
4516        } finally {
4517            Binder.restoreCallingIdentity(callingId);
4518        }
4519    }
4520
4521    @Override
4522    public void forceStopPackage(final String packageName, int userId) {
4523        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4524                != PackageManager.PERMISSION_GRANTED) {
4525            String msg = "Permission Denial: forceStopPackage() from pid="
4526                    + Binder.getCallingPid()
4527                    + ", uid=" + Binder.getCallingUid()
4528                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4529            Slog.w(TAG, msg);
4530            throw new SecurityException(msg);
4531        }
4532        final int callingPid = Binder.getCallingPid();
4533        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4534                userId, true, true, "forceStopPackage", null);
4535        long callingId = Binder.clearCallingIdentity();
4536        try {
4537            IPackageManager pm = AppGlobals.getPackageManager();
4538            synchronized(this) {
4539                int[] users = userId == UserHandle.USER_ALL
4540                        ? getUsersLocked() : new int[] { userId };
4541                for (int user : users) {
4542                    int pkgUid = -1;
4543                    try {
4544                        pkgUid = pm.getPackageUid(packageName, user);
4545                    } catch (RemoteException e) {
4546                    }
4547                    if (pkgUid == -1) {
4548                        Slog.w(TAG, "Invalid packageName: " + packageName);
4549                        continue;
4550                    }
4551                    try {
4552                        pm.setPackageStoppedState(packageName, true, user);
4553                    } catch (RemoteException e) {
4554                    } catch (IllegalArgumentException e) {
4555                        Slog.w(TAG, "Failed trying to unstop package "
4556                                + packageName + ": " + e);
4557                    }
4558                    if (isUserRunningLocked(user, false)) {
4559                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4560                    }
4561                }
4562            }
4563        } finally {
4564            Binder.restoreCallingIdentity(callingId);
4565        }
4566    }
4567
4568    /*
4569     * The pkg name and app id have to be specified.
4570     */
4571    @Override
4572    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4573        if (pkg == null) {
4574            return;
4575        }
4576        // Make sure the uid is valid.
4577        if (appid < 0) {
4578            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4579            return;
4580        }
4581        int callerUid = Binder.getCallingUid();
4582        // Only the system server can kill an application
4583        if (callerUid == Process.SYSTEM_UID) {
4584            // Post an aysnc message to kill the application
4585            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4586            msg.arg1 = appid;
4587            msg.arg2 = 0;
4588            Bundle bundle = new Bundle();
4589            bundle.putString("pkg", pkg);
4590            bundle.putString("reason", reason);
4591            msg.obj = bundle;
4592            mHandler.sendMessage(msg);
4593        } else {
4594            throw new SecurityException(callerUid + " cannot kill pkg: " +
4595                    pkg);
4596        }
4597    }
4598
4599    @Override
4600    public void closeSystemDialogs(String reason) {
4601        enforceNotIsolatedCaller("closeSystemDialogs");
4602
4603        final int pid = Binder.getCallingPid();
4604        final int uid = Binder.getCallingUid();
4605        final long origId = Binder.clearCallingIdentity();
4606        try {
4607            synchronized (this) {
4608                // Only allow this from foreground processes, so that background
4609                // applications can't abuse it to prevent system UI from being shown.
4610                if (uid >= Process.FIRST_APPLICATION_UID) {
4611                    ProcessRecord proc;
4612                    synchronized (mPidsSelfLocked) {
4613                        proc = mPidsSelfLocked.get(pid);
4614                    }
4615                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4616                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4617                                + " from background process " + proc);
4618                        return;
4619                    }
4620                }
4621                closeSystemDialogsLocked(reason);
4622            }
4623        } finally {
4624            Binder.restoreCallingIdentity(origId);
4625        }
4626    }
4627
4628    void closeSystemDialogsLocked(String reason) {
4629        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4630        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4631                | Intent.FLAG_RECEIVER_FOREGROUND);
4632        if (reason != null) {
4633            intent.putExtra("reason", reason);
4634        }
4635        mWindowManager.closeSystemDialogs(reason);
4636
4637        mStackSupervisor.closeSystemDialogsLocked();
4638
4639        broadcastIntentLocked(null, null, intent, null,
4640                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4641                Process.SYSTEM_UID, UserHandle.USER_ALL);
4642    }
4643
4644    @Override
4645    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4646        enforceNotIsolatedCaller("getProcessMemoryInfo");
4647        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4648        for (int i=pids.length-1; i>=0; i--) {
4649            ProcessRecord proc;
4650            int oomAdj;
4651            synchronized (this) {
4652                synchronized (mPidsSelfLocked) {
4653                    proc = mPidsSelfLocked.get(pids[i]);
4654                    oomAdj = proc != null ? proc.setAdj : 0;
4655                }
4656            }
4657            infos[i] = new Debug.MemoryInfo();
4658            Debug.getMemoryInfo(pids[i], infos[i]);
4659            if (proc != null) {
4660                synchronized (this) {
4661                    if (proc.thread != null && proc.setAdj == oomAdj) {
4662                        // Record this for posterity if the process has been stable.
4663                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4664                                infos[i].getTotalUss(), false, proc.pkgList);
4665                    }
4666                }
4667            }
4668        }
4669        return infos;
4670    }
4671
4672    @Override
4673    public long[] getProcessPss(int[] pids) {
4674        enforceNotIsolatedCaller("getProcessPss");
4675        long[] pss = new long[pids.length];
4676        for (int i=pids.length-1; i>=0; i--) {
4677            ProcessRecord proc;
4678            int oomAdj;
4679            synchronized (this) {
4680                synchronized (mPidsSelfLocked) {
4681                    proc = mPidsSelfLocked.get(pids[i]);
4682                    oomAdj = proc != null ? proc.setAdj : 0;
4683                }
4684            }
4685            long[] tmpUss = new long[1];
4686            pss[i] = Debug.getPss(pids[i], tmpUss);
4687            if (proc != null) {
4688                synchronized (this) {
4689                    if (proc.thread != null && proc.setAdj == oomAdj) {
4690                        // Record this for posterity if the process has been stable.
4691                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4692                    }
4693                }
4694            }
4695        }
4696        return pss;
4697    }
4698
4699    @Override
4700    public void killApplicationProcess(String processName, int uid) {
4701        if (processName == null) {
4702            return;
4703        }
4704
4705        int callerUid = Binder.getCallingUid();
4706        // Only the system server can kill an application
4707        if (callerUid == Process.SYSTEM_UID) {
4708            synchronized (this) {
4709                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4710                if (app != null && app.thread != null) {
4711                    try {
4712                        app.thread.scheduleSuicide();
4713                    } catch (RemoteException e) {
4714                        // If the other end already died, then our work here is done.
4715                    }
4716                } else {
4717                    Slog.w(TAG, "Process/uid not found attempting kill of "
4718                            + processName + " / " + uid);
4719                }
4720            }
4721        } else {
4722            throw new SecurityException(callerUid + " cannot kill app process: " +
4723                    processName);
4724        }
4725    }
4726
4727    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4728        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4729                false, true, false, false, UserHandle.getUserId(uid), reason);
4730        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4731                Uri.fromParts("package", packageName, null));
4732        if (!mProcessesReady) {
4733            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4734                    | Intent.FLAG_RECEIVER_FOREGROUND);
4735        }
4736        intent.putExtra(Intent.EXTRA_UID, uid);
4737        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4738        broadcastIntentLocked(null, null, intent,
4739                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4740                false, false,
4741                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4742    }
4743
4744    private void forceStopUserLocked(int userId, String reason) {
4745        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4746        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4747        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4748                | Intent.FLAG_RECEIVER_FOREGROUND);
4749        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4750        broadcastIntentLocked(null, null, intent,
4751                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4752                false, false,
4753                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4754    }
4755
4756    private final boolean killPackageProcessesLocked(String packageName, int appId,
4757            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4758            boolean doit, boolean evenPersistent, String reason) {
4759        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4760
4761        // Remove all processes this package may have touched: all with the
4762        // same UID (except for the system or root user), and all whose name
4763        // matches the package name.
4764        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4765        final int NP = mProcessNames.getMap().size();
4766        for (int ip=0; ip<NP; ip++) {
4767            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4768            final int NA = apps.size();
4769            for (int ia=0; ia<NA; ia++) {
4770                ProcessRecord app = apps.valueAt(ia);
4771                if (app.persistent && !evenPersistent) {
4772                    // we don't kill persistent processes
4773                    continue;
4774                }
4775                if (app.removed) {
4776                    if (doit) {
4777                        procs.add(app);
4778                    }
4779                    continue;
4780                }
4781
4782                // Skip process if it doesn't meet our oom adj requirement.
4783                if (app.setAdj < minOomAdj) {
4784                    continue;
4785                }
4786
4787                // If no package is specified, we call all processes under the
4788                // give user id.
4789                if (packageName == null) {
4790                    if (app.userId != userId) {
4791                        continue;
4792                    }
4793                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4794                        continue;
4795                    }
4796                // Package has been specified, we want to hit all processes
4797                // that match it.  We need to qualify this by the processes
4798                // that are running under the specified app and user ID.
4799                } else {
4800                    if (UserHandle.getAppId(app.uid) != appId) {
4801                        continue;
4802                    }
4803                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4804                        continue;
4805                    }
4806                    if (!app.pkgList.containsKey(packageName)) {
4807                        continue;
4808                    }
4809                }
4810
4811                // Process has passed all conditions, kill it!
4812                if (!doit) {
4813                    return true;
4814                }
4815                app.removed = true;
4816                procs.add(app);
4817            }
4818        }
4819
4820        int N = procs.size();
4821        for (int i=0; i<N; i++) {
4822            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4823        }
4824        updateOomAdjLocked();
4825        return N > 0;
4826    }
4827
4828    private final boolean forceStopPackageLocked(String name, int appId,
4829            boolean callerWillRestart, boolean purgeCache, boolean doit,
4830            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4831        int i;
4832        int N;
4833
4834        if (userId == UserHandle.USER_ALL && name == null) {
4835            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4836        }
4837
4838        if (appId < 0 && name != null) {
4839            try {
4840                appId = UserHandle.getAppId(
4841                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4842            } catch (RemoteException e) {
4843            }
4844        }
4845
4846        if (doit) {
4847            if (name != null) {
4848                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4849                        + " user=" + userId + ": " + reason);
4850            } else {
4851                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4852            }
4853
4854            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4855            for (int ip=pmap.size()-1; ip>=0; ip--) {
4856                SparseArray<Long> ba = pmap.valueAt(ip);
4857                for (i=ba.size()-1; i>=0; i--) {
4858                    boolean remove = false;
4859                    final int entUid = ba.keyAt(i);
4860                    if (name != null) {
4861                        if (userId == UserHandle.USER_ALL) {
4862                            if (UserHandle.getAppId(entUid) == appId) {
4863                                remove = true;
4864                            }
4865                        } else {
4866                            if (entUid == UserHandle.getUid(userId, appId)) {
4867                                remove = true;
4868                            }
4869                        }
4870                    } else if (UserHandle.getUserId(entUid) == userId) {
4871                        remove = true;
4872                    }
4873                    if (remove) {
4874                        ba.removeAt(i);
4875                    }
4876                }
4877                if (ba.size() == 0) {
4878                    pmap.removeAt(ip);
4879                }
4880            }
4881        }
4882
4883        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4884                -100, callerWillRestart, true, doit, evenPersistent,
4885                name == null ? ("stop user " + userId) : ("stop " + name));
4886
4887        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4888            if (!doit) {
4889                return true;
4890            }
4891            didSomething = true;
4892        }
4893
4894        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4895            if (!doit) {
4896                return true;
4897            }
4898            didSomething = true;
4899        }
4900
4901        if (name == null) {
4902            // Remove all sticky broadcasts from this user.
4903            mStickyBroadcasts.remove(userId);
4904        }
4905
4906        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4907        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4908                userId, providers)) {
4909            if (!doit) {
4910                return true;
4911            }
4912            didSomething = true;
4913        }
4914        N = providers.size();
4915        for (i=0; i<N; i++) {
4916            removeDyingProviderLocked(null, providers.get(i), true);
4917        }
4918
4919        // Remove transient permissions granted from/to this package/user
4920        removeUriPermissionsForPackageLocked(name, userId, false);
4921
4922        if (name == null || uninstalling) {
4923            // Remove pending intents.  For now we only do this when force
4924            // stopping users, because we have some problems when doing this
4925            // for packages -- app widgets are not currently cleaned up for
4926            // such packages, so they can be left with bad pending intents.
4927            if (mIntentSenderRecords.size() > 0) {
4928                Iterator<WeakReference<PendingIntentRecord>> it
4929                        = mIntentSenderRecords.values().iterator();
4930                while (it.hasNext()) {
4931                    WeakReference<PendingIntentRecord> wpir = it.next();
4932                    if (wpir == null) {
4933                        it.remove();
4934                        continue;
4935                    }
4936                    PendingIntentRecord pir = wpir.get();
4937                    if (pir == null) {
4938                        it.remove();
4939                        continue;
4940                    }
4941                    if (name == null) {
4942                        // Stopping user, remove all objects for the user.
4943                        if (pir.key.userId != userId) {
4944                            // Not the same user, skip it.
4945                            continue;
4946                        }
4947                    } else {
4948                        if (UserHandle.getAppId(pir.uid) != appId) {
4949                            // Different app id, skip it.
4950                            continue;
4951                        }
4952                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4953                            // Different user, skip it.
4954                            continue;
4955                        }
4956                        if (!pir.key.packageName.equals(name)) {
4957                            // Different package, skip it.
4958                            continue;
4959                        }
4960                    }
4961                    if (!doit) {
4962                        return true;
4963                    }
4964                    didSomething = true;
4965                    it.remove();
4966                    pir.canceled = true;
4967                    if (pir.key.activity != null) {
4968                        pir.key.activity.pendingResults.remove(pir.ref);
4969                    }
4970                }
4971            }
4972        }
4973
4974        if (doit) {
4975            if (purgeCache && name != null) {
4976                AttributeCache ac = AttributeCache.instance();
4977                if (ac != null) {
4978                    ac.removePackage(name);
4979                }
4980            }
4981            if (mBooted) {
4982                mStackSupervisor.resumeTopActivitiesLocked();
4983                mStackSupervisor.scheduleIdleLocked();
4984            }
4985        }
4986
4987        return didSomething;
4988    }
4989
4990    private final boolean removeProcessLocked(ProcessRecord app,
4991            boolean callerWillRestart, boolean allowRestart, String reason) {
4992        final String name = app.processName;
4993        final int uid = app.uid;
4994        if (DEBUG_PROCESSES) Slog.d(
4995            TAG, "Force removing proc " + app.toShortString() + " (" + name
4996            + "/" + uid + ")");
4997
4998        mProcessNames.remove(name, uid);
4999        mIsolatedProcesses.remove(app.uid);
5000        if (mHeavyWeightProcess == app) {
5001            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5002                    mHeavyWeightProcess.userId, 0));
5003            mHeavyWeightProcess = null;
5004        }
5005        boolean needRestart = false;
5006        if (app.pid > 0 && app.pid != MY_PID) {
5007            int pid = app.pid;
5008            synchronized (mPidsSelfLocked) {
5009                mPidsSelfLocked.remove(pid);
5010                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5011            }
5012            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5013                    app.processName, app.info.uid);
5014            if (app.isolated) {
5015                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5016            }
5017            killUnneededProcessLocked(app, reason);
5018            handleAppDiedLocked(app, true, allowRestart);
5019            removeLruProcessLocked(app);
5020
5021            if (app.persistent && !app.isolated) {
5022                if (!callerWillRestart) {
5023                    addAppLocked(app.info, false);
5024                } else {
5025                    needRestart = true;
5026                }
5027            }
5028        } else {
5029            mRemovedProcesses.add(app);
5030        }
5031
5032        return needRestart;
5033    }
5034
5035    private final void processStartTimedOutLocked(ProcessRecord app) {
5036        final int pid = app.pid;
5037        boolean gone = false;
5038        synchronized (mPidsSelfLocked) {
5039            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5040            if (knownApp != null && knownApp.thread == null) {
5041                mPidsSelfLocked.remove(pid);
5042                gone = true;
5043            }
5044        }
5045
5046        if (gone) {
5047            Slog.w(TAG, "Process " + app + " failed to attach");
5048            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5049                    pid, app.uid, app.processName);
5050            mProcessNames.remove(app.processName, app.uid);
5051            mIsolatedProcesses.remove(app.uid);
5052            if (mHeavyWeightProcess == app) {
5053                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5054                        mHeavyWeightProcess.userId, 0));
5055                mHeavyWeightProcess = null;
5056            }
5057            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5058                    app.processName, app.info.uid);
5059            if (app.isolated) {
5060                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5061            }
5062            // Take care of any launching providers waiting for this process.
5063            checkAppInLaunchingProvidersLocked(app, true);
5064            // Take care of any services that are waiting for the process.
5065            mServices.processStartTimedOutLocked(app);
5066            killUnneededProcessLocked(app, "start timeout");
5067            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5068                Slog.w(TAG, "Unattached app died before backup, skipping");
5069                try {
5070                    IBackupManager bm = IBackupManager.Stub.asInterface(
5071                            ServiceManager.getService(Context.BACKUP_SERVICE));
5072                    bm.agentDisconnected(app.info.packageName);
5073                } catch (RemoteException e) {
5074                    // Can't happen; the backup manager is local
5075                }
5076            }
5077            if (isPendingBroadcastProcessLocked(pid)) {
5078                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5079                skipPendingBroadcastLocked(pid);
5080            }
5081        } else {
5082            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5083        }
5084    }
5085
5086    private final boolean attachApplicationLocked(IApplicationThread thread,
5087            int pid) {
5088
5089        // Find the application record that is being attached...  either via
5090        // the pid if we are running in multiple processes, or just pull the
5091        // next app record if we are emulating process with anonymous threads.
5092        ProcessRecord app;
5093        if (pid != MY_PID && pid >= 0) {
5094            synchronized (mPidsSelfLocked) {
5095                app = mPidsSelfLocked.get(pid);
5096            }
5097        } else {
5098            app = null;
5099        }
5100
5101        if (app == null) {
5102            Slog.w(TAG, "No pending application record for pid " + pid
5103                    + " (IApplicationThread " + thread + "); dropping process");
5104            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5105            if (pid > 0 && pid != MY_PID) {
5106                Process.killProcessQuiet(pid);
5107            } else {
5108                try {
5109                    thread.scheduleExit();
5110                } catch (Exception e) {
5111                    // Ignore exceptions.
5112                }
5113            }
5114            return false;
5115        }
5116
5117        // If this application record is still attached to a previous
5118        // process, clean it up now.
5119        if (app.thread != null) {
5120            handleAppDiedLocked(app, true, true);
5121        }
5122
5123        // Tell the process all about itself.
5124
5125        if (localLOGV) Slog.v(
5126                TAG, "Binding process pid " + pid + " to record " + app);
5127
5128        final String processName = app.processName;
5129        try {
5130            AppDeathRecipient adr = new AppDeathRecipient(
5131                    app, pid, thread);
5132            thread.asBinder().linkToDeath(adr, 0);
5133            app.deathRecipient = adr;
5134        } catch (RemoteException e) {
5135            app.resetPackageList(mProcessStats);
5136            startProcessLocked(app, "link fail", processName);
5137            return false;
5138        }
5139
5140        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5141
5142        app.makeActive(thread, mProcessStats);
5143        app.curAdj = app.setAdj = -100;
5144        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5145        app.forcingToForeground = null;
5146        updateProcessForegroundLocked(app, false, false);
5147        app.hasShownUi = false;
5148        app.debugging = false;
5149        app.cached = false;
5150
5151        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5152
5153        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5154        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5155
5156        if (!normalMode) {
5157            Slog.i(TAG, "Launching preboot mode app: " + app);
5158        }
5159
5160        if (localLOGV) Slog.v(
5161            TAG, "New app record " + app
5162            + " thread=" + thread.asBinder() + " pid=" + pid);
5163        try {
5164            int testMode = IApplicationThread.DEBUG_OFF;
5165            if (mDebugApp != null && mDebugApp.equals(processName)) {
5166                testMode = mWaitForDebugger
5167                    ? IApplicationThread.DEBUG_WAIT
5168                    : IApplicationThread.DEBUG_ON;
5169                app.debugging = true;
5170                if (mDebugTransient) {
5171                    mDebugApp = mOrigDebugApp;
5172                    mWaitForDebugger = mOrigWaitForDebugger;
5173                }
5174            }
5175            String profileFile = app.instrumentationProfileFile;
5176            ParcelFileDescriptor profileFd = null;
5177            boolean profileAutoStop = false;
5178            if (mProfileApp != null && mProfileApp.equals(processName)) {
5179                mProfileProc = app;
5180                profileFile = mProfileFile;
5181                profileFd = mProfileFd;
5182                profileAutoStop = mAutoStopProfiler;
5183            }
5184            boolean enableOpenGlTrace = false;
5185            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5186                enableOpenGlTrace = true;
5187                mOpenGlTraceApp = null;
5188            }
5189
5190            // If the app is being launched for restore or full backup, set it up specially
5191            boolean isRestrictedBackupMode = false;
5192            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5193                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5194                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5195                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5196            }
5197
5198            ensurePackageDexOpt(app.instrumentationInfo != null
5199                    ? app.instrumentationInfo.packageName
5200                    : app.info.packageName);
5201            if (app.instrumentationClass != null) {
5202                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5203            }
5204            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5205                    + processName + " with config " + mConfiguration);
5206            ApplicationInfo appInfo = app.instrumentationInfo != null
5207                    ? app.instrumentationInfo : app.info;
5208            app.compat = compatibilityInfoForPackageLocked(appInfo);
5209            if (profileFd != null) {
5210                profileFd = profileFd.dup();
5211            }
5212            thread.bindApplication(processName, appInfo, providers,
5213                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5214                    app.instrumentationArguments, app.instrumentationWatcher,
5215                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5216                    isRestrictedBackupMode || !normalMode, app.persistent,
5217                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5218                    mCoreSettingsObserver.getCoreSettingsLocked());
5219            updateLruProcessLocked(app, false, null);
5220            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5221        } catch (Exception e) {
5222            // todo: Yikes!  What should we do?  For now we will try to
5223            // start another process, but that could easily get us in
5224            // an infinite loop of restarting processes...
5225            Slog.w(TAG, "Exception thrown during bind!", e);
5226
5227            app.resetPackageList(mProcessStats);
5228            app.unlinkDeathRecipient();
5229            startProcessLocked(app, "bind fail", processName);
5230            return false;
5231        }
5232
5233        // Remove this record from the list of starting applications.
5234        mPersistentStartingProcesses.remove(app);
5235        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5236                "Attach application locked removing on hold: " + app);
5237        mProcessesOnHold.remove(app);
5238
5239        boolean badApp = false;
5240        boolean didSomething = false;
5241
5242        // See if the top visible activity is waiting to run in this process...
5243        if (normalMode) {
5244            try {
5245                if (mStackSupervisor.attachApplicationLocked(app)) {
5246                    didSomething = true;
5247                }
5248            } catch (Exception e) {
5249                badApp = true;
5250            }
5251        }
5252
5253        // Find any services that should be running in this process...
5254        if (!badApp) {
5255            try {
5256                didSomething |= mServices.attachApplicationLocked(app, processName);
5257            } catch (Exception e) {
5258                badApp = true;
5259            }
5260        }
5261
5262        // Check if a next-broadcast receiver is in this process...
5263        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5264            try {
5265                didSomething |= sendPendingBroadcastsLocked(app);
5266            } catch (Exception e) {
5267                // If the app died trying to launch the receiver we declare it 'bad'
5268                badApp = true;
5269            }
5270        }
5271
5272        // Check whether the next backup agent is in this process...
5273        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5274            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5275            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5276            try {
5277                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5278                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5279                        mBackupTarget.backupMode);
5280            } catch (Exception e) {
5281                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5282                e.printStackTrace();
5283            }
5284        }
5285
5286        if (badApp) {
5287            // todo: Also need to kill application to deal with all
5288            // kinds of exceptions.
5289            handleAppDiedLocked(app, false, true);
5290            return false;
5291        }
5292
5293        if (!didSomething) {
5294            updateOomAdjLocked();
5295        }
5296
5297        return true;
5298    }
5299
5300    @Override
5301    public final void attachApplication(IApplicationThread thread) {
5302        synchronized (this) {
5303            int callingPid = Binder.getCallingPid();
5304            final long origId = Binder.clearCallingIdentity();
5305            attachApplicationLocked(thread, callingPid);
5306            Binder.restoreCallingIdentity(origId);
5307        }
5308    }
5309
5310    @Override
5311    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5312        final long origId = Binder.clearCallingIdentity();
5313        synchronized (this) {
5314            ActivityStack stack = ActivityRecord.getStackLocked(token);
5315            if (stack != null) {
5316                ActivityRecord r =
5317                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5318                if (stopProfiling) {
5319                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5320                        try {
5321                            mProfileFd.close();
5322                        } catch (IOException e) {
5323                        }
5324                        clearProfilerLocked();
5325                    }
5326                }
5327            }
5328        }
5329        Binder.restoreCallingIdentity(origId);
5330    }
5331
5332    void enableScreenAfterBoot() {
5333        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5334                SystemClock.uptimeMillis());
5335        mWindowManager.enableScreenAfterBoot();
5336
5337        synchronized (this) {
5338            updateEventDispatchingLocked();
5339        }
5340    }
5341
5342    @Override
5343    public void showBootMessage(final CharSequence msg, final boolean always) {
5344        enforceNotIsolatedCaller("showBootMessage");
5345        mWindowManager.showBootMessage(msg, always);
5346    }
5347
5348    @Override
5349    public void dismissKeyguardOnNextActivity() {
5350        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5351        final long token = Binder.clearCallingIdentity();
5352        try {
5353            synchronized (this) {
5354                if (DEBUG_LOCKSCREEN) logLockScreen("");
5355                if (mLockScreenShown) {
5356                    mLockScreenShown = false;
5357                    comeOutOfSleepIfNeededLocked();
5358                }
5359                mStackSupervisor.setDismissKeyguard(true);
5360            }
5361        } finally {
5362            Binder.restoreCallingIdentity(token);
5363        }
5364    }
5365
5366    final void finishBooting() {
5367        // Register receivers to handle package update events
5368        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5369
5370        synchronized (this) {
5371            // Ensure that any processes we had put on hold are now started
5372            // up.
5373            final int NP = mProcessesOnHold.size();
5374            if (NP > 0) {
5375                ArrayList<ProcessRecord> procs =
5376                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5377                for (int ip=0; ip<NP; ip++) {
5378                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5379                            + procs.get(ip));
5380                    startProcessLocked(procs.get(ip), "on-hold", null);
5381                }
5382            }
5383
5384            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5385                // Start looking for apps that are abusing wake locks.
5386                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5387                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5388                // Tell anyone interested that we are done booting!
5389                SystemProperties.set("sys.boot_completed", "1");
5390                SystemProperties.set("dev.bootcomplete", "1");
5391                for (int i=0; i<mStartedUsers.size(); i++) {
5392                    UserStartedState uss = mStartedUsers.valueAt(i);
5393                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5394                        uss.mState = UserStartedState.STATE_RUNNING;
5395                        final int userId = mStartedUsers.keyAt(i);
5396                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5397                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5398                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5399                        broadcastIntentLocked(null, null, intent, null,
5400                                new IIntentReceiver.Stub() {
5401                                    @Override
5402                                    public void performReceive(Intent intent, int resultCode,
5403                                            String data, Bundle extras, boolean ordered,
5404                                            boolean sticky, int sendingUser) {
5405                                        synchronized (ActivityManagerService.this) {
5406                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5407                                                    true, false);
5408                                        }
5409                                    }
5410                                },
5411                                0, null, null,
5412                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5413                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5414                                userId);
5415                    }
5416                }
5417                scheduleStartProfilesLocked();
5418            }
5419        }
5420    }
5421
5422    final void ensureBootCompleted() {
5423        boolean booting;
5424        boolean enableScreen;
5425        synchronized (this) {
5426            booting = mBooting;
5427            mBooting = false;
5428            enableScreen = !mBooted;
5429            mBooted = true;
5430        }
5431
5432        if (booting) {
5433            finishBooting();
5434        }
5435
5436        if (enableScreen) {
5437            enableScreenAfterBoot();
5438        }
5439    }
5440
5441    @Override
5442    public final void activityResumed(IBinder token) {
5443        final long origId = Binder.clearCallingIdentity();
5444        synchronized(this) {
5445            ActivityStack stack = ActivityRecord.getStackLocked(token);
5446            if (stack != null) {
5447                ActivityRecord.activityResumedLocked(token);
5448            }
5449        }
5450        Binder.restoreCallingIdentity(origId);
5451    }
5452
5453    @Override
5454    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5455        final long origId = Binder.clearCallingIdentity();
5456        synchronized(this) {
5457            ActivityStack stack = ActivityRecord.getStackLocked(token);
5458            if (stack != null) {
5459                stack.activityPausedLocked(token, false, persistentState);
5460            }
5461        }
5462        Binder.restoreCallingIdentity(origId);
5463    }
5464
5465    @Override
5466    public final void activityStopped(IBinder token, Bundle icicle,
5467            PersistableBundle persistentState, CharSequence description) {
5468        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5469
5470        // Refuse possible leaked file descriptors
5471        if (icicle != null && icicle.hasFileDescriptors()) {
5472            throw new IllegalArgumentException("File descriptors passed in Bundle");
5473        }
5474
5475        final long origId = Binder.clearCallingIdentity();
5476
5477        synchronized (this) {
5478            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5479            if (r != null) {
5480                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5481            }
5482        }
5483
5484        trimApplications();
5485
5486        Binder.restoreCallingIdentity(origId);
5487    }
5488
5489    @Override
5490    public final void activityDestroyed(IBinder token) {
5491        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5492        synchronized (this) {
5493            ActivityStack stack = ActivityRecord.getStackLocked(token);
5494            if (stack != null) {
5495                stack.activityDestroyedLocked(token);
5496            }
5497        }
5498    }
5499
5500    @Override
5501    public String getCallingPackage(IBinder token) {
5502        synchronized (this) {
5503            ActivityRecord r = getCallingRecordLocked(token);
5504            return r != null ? r.info.packageName : null;
5505        }
5506    }
5507
5508    @Override
5509    public ComponentName getCallingActivity(IBinder token) {
5510        synchronized (this) {
5511            ActivityRecord r = getCallingRecordLocked(token);
5512            return r != null ? r.intent.getComponent() : null;
5513        }
5514    }
5515
5516    private ActivityRecord getCallingRecordLocked(IBinder token) {
5517        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5518        if (r == null) {
5519            return null;
5520        }
5521        return r.resultTo;
5522    }
5523
5524    @Override
5525    public ComponentName getActivityClassForToken(IBinder token) {
5526        synchronized(this) {
5527            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5528            if (r == null) {
5529                return null;
5530            }
5531            return r.intent.getComponent();
5532        }
5533    }
5534
5535    @Override
5536    public String getPackageForToken(IBinder token) {
5537        synchronized(this) {
5538            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5539            if (r == null) {
5540                return null;
5541            }
5542            return r.packageName;
5543        }
5544    }
5545
5546    @Override
5547    public IIntentSender getIntentSender(int type,
5548            String packageName, IBinder token, String resultWho,
5549            int requestCode, Intent[] intents, String[] resolvedTypes,
5550            int flags, Bundle options, int userId) {
5551        enforceNotIsolatedCaller("getIntentSender");
5552        // Refuse possible leaked file descriptors
5553        if (intents != null) {
5554            if (intents.length < 1) {
5555                throw new IllegalArgumentException("Intents array length must be >= 1");
5556            }
5557            for (int i=0; i<intents.length; i++) {
5558                Intent intent = intents[i];
5559                if (intent != null) {
5560                    if (intent.hasFileDescriptors()) {
5561                        throw new IllegalArgumentException("File descriptors passed in Intent");
5562                    }
5563                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5564                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5565                        throw new IllegalArgumentException(
5566                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5567                    }
5568                    intents[i] = new Intent(intent);
5569                }
5570            }
5571            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5572                throw new IllegalArgumentException(
5573                        "Intent array length does not match resolvedTypes length");
5574            }
5575        }
5576        if (options != null) {
5577            if (options.hasFileDescriptors()) {
5578                throw new IllegalArgumentException("File descriptors passed in options");
5579            }
5580        }
5581
5582        synchronized(this) {
5583            int callingUid = Binder.getCallingUid();
5584            int origUserId = userId;
5585            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5586                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5587                    "getIntentSender", null);
5588            if (origUserId == UserHandle.USER_CURRENT) {
5589                // We don't want to evaluate this until the pending intent is
5590                // actually executed.  However, we do want to always do the
5591                // security checking for it above.
5592                userId = UserHandle.USER_CURRENT;
5593            }
5594            try {
5595                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5596                    int uid = AppGlobals.getPackageManager()
5597                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5598                    if (!UserHandle.isSameApp(callingUid, uid)) {
5599                        String msg = "Permission Denial: getIntentSender() from pid="
5600                            + Binder.getCallingPid()
5601                            + ", uid=" + Binder.getCallingUid()
5602                            + ", (need uid=" + uid + ")"
5603                            + " is not allowed to send as package " + packageName;
5604                        Slog.w(TAG, msg);
5605                        throw new SecurityException(msg);
5606                    }
5607                }
5608
5609                return getIntentSenderLocked(type, packageName, callingUid, userId,
5610                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5611
5612            } catch (RemoteException e) {
5613                throw new SecurityException(e);
5614            }
5615        }
5616    }
5617
5618    IIntentSender getIntentSenderLocked(int type, String packageName,
5619            int callingUid, int userId, IBinder token, String resultWho,
5620            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5621            Bundle options) {
5622        if (DEBUG_MU)
5623            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5624        ActivityRecord activity = null;
5625        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5626            activity = ActivityRecord.isInStackLocked(token);
5627            if (activity == null) {
5628                return null;
5629            }
5630            if (activity.finishing) {
5631                return null;
5632            }
5633        }
5634
5635        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5636        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5637        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5638        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5639                |PendingIntent.FLAG_UPDATE_CURRENT);
5640
5641        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5642                type, packageName, activity, resultWho,
5643                requestCode, intents, resolvedTypes, flags, options, userId);
5644        WeakReference<PendingIntentRecord> ref;
5645        ref = mIntentSenderRecords.get(key);
5646        PendingIntentRecord rec = ref != null ? ref.get() : null;
5647        if (rec != null) {
5648            if (!cancelCurrent) {
5649                if (updateCurrent) {
5650                    if (rec.key.requestIntent != null) {
5651                        rec.key.requestIntent.replaceExtras(intents != null ?
5652                                intents[intents.length - 1] : null);
5653                    }
5654                    if (intents != null) {
5655                        intents[intents.length-1] = rec.key.requestIntent;
5656                        rec.key.allIntents = intents;
5657                        rec.key.allResolvedTypes = resolvedTypes;
5658                    } else {
5659                        rec.key.allIntents = null;
5660                        rec.key.allResolvedTypes = null;
5661                    }
5662                }
5663                return rec;
5664            }
5665            rec.canceled = true;
5666            mIntentSenderRecords.remove(key);
5667        }
5668        if (noCreate) {
5669            return rec;
5670        }
5671        rec = new PendingIntentRecord(this, key, callingUid);
5672        mIntentSenderRecords.put(key, rec.ref);
5673        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5674            if (activity.pendingResults == null) {
5675                activity.pendingResults
5676                        = new HashSet<WeakReference<PendingIntentRecord>>();
5677            }
5678            activity.pendingResults.add(rec.ref);
5679        }
5680        return rec;
5681    }
5682
5683    @Override
5684    public void cancelIntentSender(IIntentSender sender) {
5685        if (!(sender instanceof PendingIntentRecord)) {
5686            return;
5687        }
5688        synchronized(this) {
5689            PendingIntentRecord rec = (PendingIntentRecord)sender;
5690            try {
5691                int uid = AppGlobals.getPackageManager()
5692                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5693                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5694                    String msg = "Permission Denial: cancelIntentSender() from pid="
5695                        + Binder.getCallingPid()
5696                        + ", uid=" + Binder.getCallingUid()
5697                        + " is not allowed to cancel packges "
5698                        + rec.key.packageName;
5699                    Slog.w(TAG, msg);
5700                    throw new SecurityException(msg);
5701                }
5702            } catch (RemoteException e) {
5703                throw new SecurityException(e);
5704            }
5705            cancelIntentSenderLocked(rec, true);
5706        }
5707    }
5708
5709    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5710        rec.canceled = true;
5711        mIntentSenderRecords.remove(rec.key);
5712        if (cleanActivity && rec.key.activity != null) {
5713            rec.key.activity.pendingResults.remove(rec.ref);
5714        }
5715    }
5716
5717    @Override
5718    public String getPackageForIntentSender(IIntentSender pendingResult) {
5719        if (!(pendingResult instanceof PendingIntentRecord)) {
5720            return null;
5721        }
5722        try {
5723            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5724            return res.key.packageName;
5725        } catch (ClassCastException e) {
5726        }
5727        return null;
5728    }
5729
5730    @Override
5731    public int getUidForIntentSender(IIntentSender sender) {
5732        if (sender instanceof PendingIntentRecord) {
5733            try {
5734                PendingIntentRecord res = (PendingIntentRecord)sender;
5735                return res.uid;
5736            } catch (ClassCastException e) {
5737            }
5738        }
5739        return -1;
5740    }
5741
5742    @Override
5743    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5744        if (!(pendingResult instanceof PendingIntentRecord)) {
5745            return false;
5746        }
5747        try {
5748            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5749            if (res.key.allIntents == null) {
5750                return false;
5751            }
5752            for (int i=0; i<res.key.allIntents.length; i++) {
5753                Intent intent = res.key.allIntents[i];
5754                if (intent.getPackage() != null && intent.getComponent() != null) {
5755                    return false;
5756                }
5757            }
5758            return true;
5759        } catch (ClassCastException e) {
5760        }
5761        return false;
5762    }
5763
5764    @Override
5765    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5766        if (!(pendingResult instanceof PendingIntentRecord)) {
5767            return false;
5768        }
5769        try {
5770            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5771            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5772                return true;
5773            }
5774            return false;
5775        } catch (ClassCastException e) {
5776        }
5777        return false;
5778    }
5779
5780    @Override
5781    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5782        if (!(pendingResult instanceof PendingIntentRecord)) {
5783            return null;
5784        }
5785        try {
5786            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5787            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5788        } catch (ClassCastException e) {
5789        }
5790        return null;
5791    }
5792
5793    @Override
5794    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5795        if (!(pendingResult instanceof PendingIntentRecord)) {
5796            return null;
5797        }
5798        try {
5799            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5800            Intent intent = res.key.requestIntent;
5801            if (intent != null) {
5802                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5803                        || res.lastTagPrefix.equals(prefix))) {
5804                    return res.lastTag;
5805                }
5806                res.lastTagPrefix = prefix;
5807                StringBuilder sb = new StringBuilder(128);
5808                if (prefix != null) {
5809                    sb.append(prefix);
5810                }
5811                if (intent.getAction() != null) {
5812                    sb.append(intent.getAction());
5813                } else if (intent.getComponent() != null) {
5814                    intent.getComponent().appendShortString(sb);
5815                } else {
5816                    sb.append("?");
5817                }
5818                return res.lastTag = sb.toString();
5819            }
5820        } catch (ClassCastException e) {
5821        }
5822        return null;
5823    }
5824
5825    @Override
5826    public void setProcessLimit(int max) {
5827        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5828                "setProcessLimit()");
5829        synchronized (this) {
5830            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5831            mProcessLimitOverride = max;
5832        }
5833        trimApplications();
5834    }
5835
5836    @Override
5837    public int getProcessLimit() {
5838        synchronized (this) {
5839            return mProcessLimitOverride;
5840        }
5841    }
5842
5843    void foregroundTokenDied(ForegroundToken token) {
5844        synchronized (ActivityManagerService.this) {
5845            synchronized (mPidsSelfLocked) {
5846                ForegroundToken cur
5847                    = mForegroundProcesses.get(token.pid);
5848                if (cur != token) {
5849                    return;
5850                }
5851                mForegroundProcesses.remove(token.pid);
5852                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5853                if (pr == null) {
5854                    return;
5855                }
5856                pr.forcingToForeground = null;
5857                updateProcessForegroundLocked(pr, false, false);
5858            }
5859            updateOomAdjLocked();
5860        }
5861    }
5862
5863    @Override
5864    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5865        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5866                "setProcessForeground()");
5867        synchronized(this) {
5868            boolean changed = false;
5869
5870            synchronized (mPidsSelfLocked) {
5871                ProcessRecord pr = mPidsSelfLocked.get(pid);
5872                if (pr == null && isForeground) {
5873                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5874                    return;
5875                }
5876                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5877                if (oldToken != null) {
5878                    oldToken.token.unlinkToDeath(oldToken, 0);
5879                    mForegroundProcesses.remove(pid);
5880                    if (pr != null) {
5881                        pr.forcingToForeground = null;
5882                    }
5883                    changed = true;
5884                }
5885                if (isForeground && token != null) {
5886                    ForegroundToken newToken = new ForegroundToken() {
5887                        @Override
5888                        public void binderDied() {
5889                            foregroundTokenDied(this);
5890                        }
5891                    };
5892                    newToken.pid = pid;
5893                    newToken.token = token;
5894                    try {
5895                        token.linkToDeath(newToken, 0);
5896                        mForegroundProcesses.put(pid, newToken);
5897                        pr.forcingToForeground = token;
5898                        changed = true;
5899                    } catch (RemoteException e) {
5900                        // If the process died while doing this, we will later
5901                        // do the cleanup with the process death link.
5902                    }
5903                }
5904            }
5905
5906            if (changed) {
5907                updateOomAdjLocked();
5908            }
5909        }
5910    }
5911
5912    // =========================================================
5913    // PERMISSIONS
5914    // =========================================================
5915
5916    static class PermissionController extends IPermissionController.Stub {
5917        ActivityManagerService mActivityManagerService;
5918        PermissionController(ActivityManagerService activityManagerService) {
5919            mActivityManagerService = activityManagerService;
5920        }
5921
5922        @Override
5923        public boolean checkPermission(String permission, int pid, int uid) {
5924            return mActivityManagerService.checkPermission(permission, pid,
5925                    uid) == PackageManager.PERMISSION_GRANTED;
5926        }
5927    }
5928
5929    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5930        @Override
5931        public int checkComponentPermission(String permission, int pid, int uid,
5932                int owningUid, boolean exported) {
5933            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5934                    owningUid, exported);
5935        }
5936
5937        @Override
5938        public Object getAMSLock() {
5939            return ActivityManagerService.this;
5940        }
5941    }
5942
5943    /**
5944     * This can be called with or without the global lock held.
5945     */
5946    int checkComponentPermission(String permission, int pid, int uid,
5947            int owningUid, boolean exported) {
5948        // We might be performing an operation on behalf of an indirect binder
5949        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5950        // client identity accordingly before proceeding.
5951        Identity tlsIdentity = sCallerIdentity.get();
5952        if (tlsIdentity != null) {
5953            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5954                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5955            uid = tlsIdentity.uid;
5956            pid = tlsIdentity.pid;
5957        }
5958
5959        if (pid == MY_PID) {
5960            return PackageManager.PERMISSION_GRANTED;
5961        }
5962
5963        return ActivityManager.checkComponentPermission(permission, uid,
5964                owningUid, exported);
5965    }
5966
5967    /**
5968     * As the only public entry point for permissions checking, this method
5969     * can enforce the semantic that requesting a check on a null global
5970     * permission is automatically denied.  (Internally a null permission
5971     * string is used when calling {@link #checkComponentPermission} in cases
5972     * when only uid-based security is needed.)
5973     *
5974     * This can be called with or without the global lock held.
5975     */
5976    @Override
5977    public int checkPermission(String permission, int pid, int uid) {
5978        if (permission == null) {
5979            return PackageManager.PERMISSION_DENIED;
5980        }
5981        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5982    }
5983
5984    /**
5985     * Binder IPC calls go through the public entry point.
5986     * This can be called with or without the global lock held.
5987     */
5988    int checkCallingPermission(String permission) {
5989        return checkPermission(permission,
5990                Binder.getCallingPid(),
5991                UserHandle.getAppId(Binder.getCallingUid()));
5992    }
5993
5994    /**
5995     * This can be called with or without the global lock held.
5996     */
5997    void enforceCallingPermission(String permission, String func) {
5998        if (checkCallingPermission(permission)
5999                == PackageManager.PERMISSION_GRANTED) {
6000            return;
6001        }
6002
6003        String msg = "Permission Denial: " + func + " from pid="
6004                + Binder.getCallingPid()
6005                + ", uid=" + Binder.getCallingUid()
6006                + " requires " + permission;
6007        Slog.w(TAG, msg);
6008        throw new SecurityException(msg);
6009    }
6010
6011    /**
6012     * Determine if UID is holding permissions required to access {@link Uri} in
6013     * the given {@link ProviderInfo}. Final permission checking is always done
6014     * in {@link ContentProvider}.
6015     */
6016    private final boolean checkHoldingPermissionsLocked(
6017            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6018        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6019                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6020        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6021            return false;
6022        }
6023
6024        if (pi.applicationInfo.uid == uid) {
6025            return true;
6026        } else if (!pi.exported) {
6027            return false;
6028        }
6029
6030        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6031        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6032        try {
6033            // check if target holds top-level <provider> permissions
6034            if (!readMet && pi.readPermission != null
6035                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6036                readMet = true;
6037            }
6038            if (!writeMet && pi.writePermission != null
6039                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6040                writeMet = true;
6041            }
6042
6043            // track if unprotected read/write is allowed; any denied
6044            // <path-permission> below removes this ability
6045            boolean allowDefaultRead = pi.readPermission == null;
6046            boolean allowDefaultWrite = pi.writePermission == null;
6047
6048            // check if target holds any <path-permission> that match uri
6049            final PathPermission[] pps = pi.pathPermissions;
6050            if (pps != null) {
6051                final String path = grantUri.uri.getPath();
6052                int i = pps.length;
6053                while (i > 0 && (!readMet || !writeMet)) {
6054                    i--;
6055                    PathPermission pp = pps[i];
6056                    if (pp.match(path)) {
6057                        if (!readMet) {
6058                            final String pprperm = pp.getReadPermission();
6059                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6060                                    + pprperm + " for " + pp.getPath()
6061                                    + ": match=" + pp.match(path)
6062                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6063                            if (pprperm != null) {
6064                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6065                                    readMet = true;
6066                                } else {
6067                                    allowDefaultRead = false;
6068                                }
6069                            }
6070                        }
6071                        if (!writeMet) {
6072                            final String ppwperm = pp.getWritePermission();
6073                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6074                                    + ppwperm + " for " + pp.getPath()
6075                                    + ": match=" + pp.match(path)
6076                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6077                            if (ppwperm != null) {
6078                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6079                                    writeMet = true;
6080                                } else {
6081                                    allowDefaultWrite = false;
6082                                }
6083                            }
6084                        }
6085                    }
6086                }
6087            }
6088
6089            // grant unprotected <provider> read/write, if not blocked by
6090            // <path-permission> above
6091            if (allowDefaultRead) readMet = true;
6092            if (allowDefaultWrite) writeMet = true;
6093
6094        } catch (RemoteException e) {
6095            return false;
6096        }
6097
6098        return readMet && writeMet;
6099    }
6100
6101    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6102        ProviderInfo pi = null;
6103        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6104        if (cpr != null) {
6105            pi = cpr.info;
6106        } else {
6107            try {
6108                pi = AppGlobals.getPackageManager().resolveContentProvider(
6109                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6110            } catch (RemoteException ex) {
6111            }
6112        }
6113        return pi;
6114    }
6115
6116    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6117        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6118        if (targetUris != null) {
6119            return targetUris.get(grantUri);
6120        }
6121        return null;
6122    }
6123
6124    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6125            String targetPkg, int targetUid, GrantUri grantUri) {
6126        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6127        if (targetUris == null) {
6128            targetUris = Maps.newArrayMap();
6129            mGrantedUriPermissions.put(targetUid, targetUris);
6130        }
6131
6132        UriPermission perm = targetUris.get(grantUri);
6133        if (perm == null) {
6134            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6135            targetUris.put(grantUri, perm);
6136        }
6137
6138        return perm;
6139    }
6140
6141    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6142            final int modeFlags) {
6143        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6144        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6145                : UriPermission.STRENGTH_OWNED;
6146
6147        // Root gets to do everything.
6148        if (uid == 0) {
6149            return true;
6150        }
6151
6152        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6153        if (perms == null) return false;
6154
6155        // First look for exact match
6156        final UriPermission exactPerm = perms.get(grantUri);
6157        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6158            return true;
6159        }
6160
6161        // No exact match, look for prefixes
6162        final int N = perms.size();
6163        for (int i = 0; i < N; i++) {
6164            final UriPermission perm = perms.valueAt(i);
6165            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6166                    && perm.getStrength(modeFlags) >= minStrength) {
6167                return true;
6168            }
6169        }
6170
6171        return false;
6172    }
6173
6174    @Override
6175    public int checkUriPermission(Uri uri, int pid, int uid,
6176            final int modeFlags, int userId) {
6177        enforceNotIsolatedCaller("checkUriPermission");
6178
6179        // Another redirected-binder-call permissions check as in
6180        // {@link checkComponentPermission}.
6181        Identity tlsIdentity = sCallerIdentity.get();
6182        if (tlsIdentity != null) {
6183            uid = tlsIdentity.uid;
6184            pid = tlsIdentity.pid;
6185        }
6186
6187        // Our own process gets to do everything.
6188        if (pid == MY_PID) {
6189            return PackageManager.PERMISSION_GRANTED;
6190        }
6191        synchronized (this) {
6192            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6193                    ? PackageManager.PERMISSION_GRANTED
6194                    : PackageManager.PERMISSION_DENIED;
6195        }
6196    }
6197
6198    /**
6199     * Check if the targetPkg can be granted permission to access uri by
6200     * the callingUid using the given modeFlags.  Throws a security exception
6201     * if callingUid is not allowed to do this.  Returns the uid of the target
6202     * if the URI permission grant should be performed; returns -1 if it is not
6203     * needed (for example targetPkg already has permission to access the URI).
6204     * If you already know the uid of the target, you can supply it in
6205     * lastTargetUid else set that to -1.
6206     */
6207    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6208            final int modeFlags, int lastTargetUid) {
6209        if (!Intent.isAccessUriMode(modeFlags)) {
6210            return -1;
6211        }
6212
6213        if (targetPkg != null) {
6214            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6215                    "Checking grant " + targetPkg + " permission to " + grantUri);
6216        }
6217
6218        final IPackageManager pm = AppGlobals.getPackageManager();
6219
6220        // If this is not a content: uri, we can't do anything with it.
6221        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6222            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6223                    "Can't grant URI permission for non-content URI: " + grantUri);
6224            return -1;
6225        }
6226
6227        final String authority = grantUri.uri.getAuthority();
6228        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6229        if (pi == null) {
6230            Slog.w(TAG, "No content provider found for permission check: " +
6231                    grantUri.uri.toSafeString());
6232            return -1;
6233        }
6234
6235        int targetUid = lastTargetUid;
6236        if (targetUid < 0 && targetPkg != null) {
6237            try {
6238                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6239                if (targetUid < 0) {
6240                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6241                            "Can't grant URI permission no uid for: " + targetPkg);
6242                    return -1;
6243                }
6244            } catch (RemoteException ex) {
6245                return -1;
6246            }
6247        }
6248
6249        if (targetUid >= 0) {
6250            // First...  does the target actually need this permission?
6251            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6252                // No need to grant the target this permission.
6253                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6254                        "Target " + targetPkg + " already has full permission to " + grantUri);
6255                return -1;
6256            }
6257        } else {
6258            // First...  there is no target package, so can anyone access it?
6259            boolean allowed = pi.exported;
6260            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6261                if (pi.readPermission != null) {
6262                    allowed = false;
6263                }
6264            }
6265            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6266                if (pi.writePermission != null) {
6267                    allowed = false;
6268                }
6269            }
6270            if (allowed) {
6271                return -1;
6272            }
6273        }
6274
6275        // Second...  is the provider allowing granting of URI permissions?
6276        if (!pi.grantUriPermissions) {
6277            throw new SecurityException("Provider " + pi.packageName
6278                    + "/" + pi.name
6279                    + " does not allow granting of Uri permissions (uri "
6280                    + grantUri + ")");
6281        }
6282        if (pi.uriPermissionPatterns != null) {
6283            final int N = pi.uriPermissionPatterns.length;
6284            boolean allowed = false;
6285            for (int i=0; i<N; i++) {
6286                if (pi.uriPermissionPatterns[i] != null
6287                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6288                    allowed = true;
6289                    break;
6290                }
6291            }
6292            if (!allowed) {
6293                throw new SecurityException("Provider " + pi.packageName
6294                        + "/" + pi.name
6295                        + " does not allow granting of permission to path of Uri "
6296                        + grantUri);
6297            }
6298        }
6299
6300        // Third...  does the caller itself have permission to access
6301        // this uri?
6302        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6303            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6304                // Require they hold a strong enough Uri permission
6305                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6306                    throw new SecurityException("Uid " + callingUid
6307                            + " does not have permission to uri " + grantUri);
6308                }
6309            }
6310        }
6311        return targetUid;
6312    }
6313
6314    @Override
6315    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6316            final int modeFlags, int userId) {
6317        enforceNotIsolatedCaller("checkGrantUriPermission");
6318        synchronized(this) {
6319            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6320                    new GrantUri(userId, uri, false), modeFlags, -1);
6321        }
6322    }
6323
6324    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6325            final int modeFlags, UriPermissionOwner owner) {
6326        if (!Intent.isAccessUriMode(modeFlags)) {
6327            return;
6328        }
6329
6330        // So here we are: the caller has the assumed permission
6331        // to the uri, and the target doesn't.  Let's now give this to
6332        // the target.
6333
6334        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6335                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6336
6337        final String authority = grantUri.uri.getAuthority();
6338        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6339        if (pi == null) {
6340            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6341            return;
6342        }
6343
6344        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6345            grantUri.prefix = true;
6346        }
6347        final UriPermission perm = findOrCreateUriPermissionLocked(
6348                pi.packageName, targetPkg, targetUid, grantUri);
6349        perm.grantModes(modeFlags, owner);
6350    }
6351
6352    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6353            final int modeFlags, UriPermissionOwner owner) {
6354        if (targetPkg == null) {
6355            throw new NullPointerException("targetPkg");
6356        }
6357
6358        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6359                -1);
6360        if (targetUid < 0) {
6361            return;
6362        }
6363
6364        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6365                owner);
6366    }
6367
6368    static class NeededUriGrants extends ArrayList<GrantUri> {
6369        final String targetPkg;
6370        final int targetUid;
6371        final int flags;
6372
6373        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6374            this.targetPkg = targetPkg;
6375            this.targetUid = targetUid;
6376            this.flags = flags;
6377        }
6378    }
6379
6380    /**
6381     * Like checkGrantUriPermissionLocked, but takes an Intent.
6382     */
6383    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6384            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6385        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6386                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6387                + " clip=" + (intent != null ? intent.getClipData() : null)
6388                + " from " + intent + "; flags=0x"
6389                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6390
6391        if (targetPkg == null) {
6392            throw new NullPointerException("targetPkg");
6393        }
6394
6395        if (intent == null) {
6396            return null;
6397        }
6398        Uri data = intent.getData();
6399        ClipData clip = intent.getClipData();
6400        if (data == null && clip == null) {
6401            return null;
6402        }
6403
6404        if (data != null) {
6405            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6406            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6407                    needed != null ? needed.targetUid : -1);
6408            if (targetUid > 0) {
6409                if (needed == null) {
6410                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6411                }
6412                needed.add(grantUri);
6413            }
6414        }
6415        if (clip != null) {
6416            for (int i=0; i<clip.getItemCount(); i++) {
6417                Uri uri = clip.getItemAt(i).getUri();
6418                if (uri != null) {
6419                    int targetUid = -1;
6420                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6421                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6422                            needed != null ? needed.targetUid : -1);
6423                    if (targetUid > 0) {
6424                        if (needed == null) {
6425                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6426                        }
6427                        needed.add(grantUri);
6428                    }
6429                } else {
6430                    Intent clipIntent = clip.getItemAt(i).getIntent();
6431                    if (clipIntent != null) {
6432                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6433                                callingUid, targetPkg, clipIntent, mode, needed);
6434                        if (newNeeded != null) {
6435                            needed = newNeeded;
6436                        }
6437                    }
6438                }
6439            }
6440        }
6441
6442        return needed;
6443    }
6444
6445    /**
6446     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6447     */
6448    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6449            UriPermissionOwner owner) {
6450        if (needed != null) {
6451            for (int i=0; i<needed.size(); i++) {
6452                GrantUri grantUri = needed.get(i);
6453                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6454                        grantUri, needed.flags, owner);
6455            }
6456        }
6457    }
6458
6459    void grantUriPermissionFromIntentLocked(int callingUid,
6460            String targetPkg, Intent intent, UriPermissionOwner owner) {
6461        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6462                intent, intent != null ? intent.getFlags() : 0, null);
6463        if (needed == null) {
6464            return;
6465        }
6466
6467        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6468    }
6469
6470    @Override
6471    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6472            final int modeFlags, int userId) {
6473        enforceNotIsolatedCaller("grantUriPermission");
6474        GrantUri grantUri = new GrantUri(userId, uri, false);
6475        synchronized(this) {
6476            final ProcessRecord r = getRecordForAppLocked(caller);
6477            if (r == null) {
6478                throw new SecurityException("Unable to find app for caller "
6479                        + caller
6480                        + " when granting permission to uri " + grantUri);
6481            }
6482            if (targetPkg == null) {
6483                throw new IllegalArgumentException("null target");
6484            }
6485            if (grantUri == null) {
6486                throw new IllegalArgumentException("null uri");
6487            }
6488
6489            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6490                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6491                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6492                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6493
6494            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6495        }
6496    }
6497
6498    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6499        if (perm.modeFlags == 0) {
6500            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6501                    perm.targetUid);
6502            if (perms != null) {
6503                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6504                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6505
6506                perms.remove(perm.uri);
6507                if (perms.isEmpty()) {
6508                    mGrantedUriPermissions.remove(perm.targetUid);
6509                }
6510            }
6511        }
6512    }
6513
6514    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6515        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6516
6517        final IPackageManager pm = AppGlobals.getPackageManager();
6518        final String authority = grantUri.uri.getAuthority();
6519        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6520        if (pi == null) {
6521            Slog.w(TAG, "No content provider found for permission revoke: "
6522                    + grantUri.toSafeString());
6523            return;
6524        }
6525
6526        // Does the caller have this permission on the URI?
6527        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6528            // Right now, if you are not the original owner of the permission,
6529            // you are not allowed to revoke it.
6530            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6531                throw new SecurityException("Uid " + callingUid
6532                        + " does not have permission to uri " + grantUri);
6533            //}
6534        }
6535
6536        boolean persistChanged = false;
6537
6538        // Go through all of the permissions and remove any that match.
6539        int N = mGrantedUriPermissions.size();
6540        for (int i = 0; i < N; i++) {
6541            final int targetUid = mGrantedUriPermissions.keyAt(i);
6542            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6543
6544            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6545                final UriPermission perm = it.next();
6546                if (perm.uri.sourceUserId == grantUri.sourceUserId
6547                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6548                    if (DEBUG_URI_PERMISSION)
6549                        Slog.v(TAG,
6550                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6551                    persistChanged |= perm.revokeModes(
6552                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6553                    if (perm.modeFlags == 0) {
6554                        it.remove();
6555                    }
6556                }
6557            }
6558
6559            if (perms.isEmpty()) {
6560                mGrantedUriPermissions.remove(targetUid);
6561                N--;
6562                i--;
6563            }
6564        }
6565
6566        if (persistChanged) {
6567            schedulePersistUriGrants();
6568        }
6569    }
6570
6571    @Override
6572    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6573            int userId) {
6574        enforceNotIsolatedCaller("revokeUriPermission");
6575        synchronized(this) {
6576            final ProcessRecord r = getRecordForAppLocked(caller);
6577            if (r == null) {
6578                throw new SecurityException("Unable to find app for caller "
6579                        + caller
6580                        + " when revoking permission to uri " + uri);
6581            }
6582            if (uri == null) {
6583                Slog.w(TAG, "revokeUriPermission: null uri");
6584                return;
6585            }
6586
6587            if (!Intent.isAccessUriMode(modeFlags)) {
6588                return;
6589            }
6590
6591            final IPackageManager pm = AppGlobals.getPackageManager();
6592            final String authority = uri.getAuthority();
6593            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6594            if (pi == null) {
6595                Slog.w(TAG, "No content provider found for permission revoke: "
6596                        + uri.toSafeString());
6597                return;
6598            }
6599
6600            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6601        }
6602    }
6603
6604    /**
6605     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6606     * given package.
6607     *
6608     * @param packageName Package name to match, or {@code null} to apply to all
6609     *            packages.
6610     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6611     *            to all users.
6612     * @param persistable If persistable grants should be removed.
6613     */
6614    private void removeUriPermissionsForPackageLocked(
6615            String packageName, int userHandle, boolean persistable) {
6616        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6617            throw new IllegalArgumentException("Must narrow by either package or user");
6618        }
6619
6620        boolean persistChanged = false;
6621
6622        int N = mGrantedUriPermissions.size();
6623        for (int i = 0; i < N; i++) {
6624            final int targetUid = mGrantedUriPermissions.keyAt(i);
6625            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6626
6627            // Only inspect grants matching user
6628            if (userHandle == UserHandle.USER_ALL
6629                    || userHandle == UserHandle.getUserId(targetUid)) {
6630                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6631                    final UriPermission perm = it.next();
6632
6633                    // Only inspect grants matching package
6634                    if (packageName == null || perm.sourcePkg.equals(packageName)
6635                            || perm.targetPkg.equals(packageName)) {
6636                        persistChanged |= perm.revokeModes(
6637                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6638
6639                        // Only remove when no modes remain; any persisted grants
6640                        // will keep this alive.
6641                        if (perm.modeFlags == 0) {
6642                            it.remove();
6643                        }
6644                    }
6645                }
6646
6647                if (perms.isEmpty()) {
6648                    mGrantedUriPermissions.remove(targetUid);
6649                    N--;
6650                    i--;
6651                }
6652            }
6653        }
6654
6655        if (persistChanged) {
6656            schedulePersistUriGrants();
6657        }
6658    }
6659
6660    @Override
6661    public IBinder newUriPermissionOwner(String name) {
6662        enforceNotIsolatedCaller("newUriPermissionOwner");
6663        synchronized(this) {
6664            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6665            return owner.getExternalTokenLocked();
6666        }
6667    }
6668
6669    @Override
6670    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6671            final int modeFlags, int userId) {
6672        synchronized(this) {
6673            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6674            if (owner == null) {
6675                throw new IllegalArgumentException("Unknown owner: " + token);
6676            }
6677            if (fromUid != Binder.getCallingUid()) {
6678                if (Binder.getCallingUid() != Process.myUid()) {
6679                    // Only system code can grant URI permissions on behalf
6680                    // of other users.
6681                    throw new SecurityException("nice try");
6682                }
6683            }
6684            if (targetPkg == null) {
6685                throw new IllegalArgumentException("null target");
6686            }
6687            if (uri == null) {
6688                throw new IllegalArgumentException("null uri");
6689            }
6690
6691            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6692                    modeFlags, owner);
6693        }
6694    }
6695
6696    @Override
6697    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6698        synchronized(this) {
6699            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6700            if (owner == null) {
6701                throw new IllegalArgumentException("Unknown owner: " + token);
6702            }
6703
6704            if (uri == null) {
6705                owner.removeUriPermissionsLocked(mode);
6706            } else {
6707                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6708            }
6709        }
6710    }
6711
6712    private void schedulePersistUriGrants() {
6713        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6714            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6715                    10 * DateUtils.SECOND_IN_MILLIS);
6716        }
6717    }
6718
6719    private void writeGrantedUriPermissions() {
6720        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6721
6722        // Snapshot permissions so we can persist without lock
6723        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6724        synchronized (this) {
6725            final int size = mGrantedUriPermissions.size();
6726            for (int i = 0; i < size; i++) {
6727                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6728                for (UriPermission perm : perms.values()) {
6729                    if (perm.persistedModeFlags != 0) {
6730                        persist.add(perm.snapshot());
6731                    }
6732                }
6733            }
6734        }
6735
6736        FileOutputStream fos = null;
6737        try {
6738            fos = mGrantFile.startWrite();
6739
6740            XmlSerializer out = new FastXmlSerializer();
6741            out.setOutput(fos, "utf-8");
6742            out.startDocument(null, true);
6743            out.startTag(null, TAG_URI_GRANTS);
6744            for (UriPermission.Snapshot perm : persist) {
6745                out.startTag(null, TAG_URI_GRANT);
6746                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6747                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6748                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6749                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6750                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6751                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6752                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6753                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6754                out.endTag(null, TAG_URI_GRANT);
6755            }
6756            out.endTag(null, TAG_URI_GRANTS);
6757            out.endDocument();
6758
6759            mGrantFile.finishWrite(fos);
6760        } catch (IOException e) {
6761            if (fos != null) {
6762                mGrantFile.failWrite(fos);
6763            }
6764        }
6765    }
6766
6767    private void readGrantedUriPermissionsLocked() {
6768        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6769
6770        final long now = System.currentTimeMillis();
6771
6772        FileInputStream fis = null;
6773        try {
6774            fis = mGrantFile.openRead();
6775            final XmlPullParser in = Xml.newPullParser();
6776            in.setInput(fis, null);
6777
6778            int type;
6779            while ((type = in.next()) != END_DOCUMENT) {
6780                final String tag = in.getName();
6781                if (type == START_TAG) {
6782                    if (TAG_URI_GRANT.equals(tag)) {
6783                        final int sourceUserId;
6784                        final int targetUserId;
6785                        final int userHandle = readIntAttribute(in,
6786                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6787                        if (userHandle != UserHandle.USER_NULL) {
6788                            // For backwards compatibility.
6789                            sourceUserId = userHandle;
6790                            targetUserId = userHandle;
6791                        } else {
6792                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6793                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6794                        }
6795                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6796                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6797                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6798                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6799                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6800                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6801
6802                        // Sanity check that provider still belongs to source package
6803                        final ProviderInfo pi = getProviderInfoLocked(
6804                                uri.getAuthority(), sourceUserId);
6805                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6806                            int targetUid = -1;
6807                            try {
6808                                targetUid = AppGlobals.getPackageManager()
6809                                        .getPackageUid(targetPkg, targetUserId);
6810                            } catch (RemoteException e) {
6811                            }
6812                            if (targetUid != -1) {
6813                                final UriPermission perm = findOrCreateUriPermissionLocked(
6814                                        sourcePkg, targetPkg, targetUid,
6815                                        new GrantUri(sourceUserId, uri, prefix));
6816                                perm.initPersistedModes(modeFlags, createdTime);
6817                            }
6818                        } else {
6819                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6820                                    + " but instead found " + pi);
6821                        }
6822                    }
6823                }
6824            }
6825        } catch (FileNotFoundException e) {
6826            // Missing grants is okay
6827        } catch (IOException e) {
6828            Log.wtf(TAG, "Failed reading Uri grants", e);
6829        } catch (XmlPullParserException e) {
6830            Log.wtf(TAG, "Failed reading Uri grants", e);
6831        } finally {
6832            IoUtils.closeQuietly(fis);
6833        }
6834    }
6835
6836    @Override
6837    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6838        enforceNotIsolatedCaller("takePersistableUriPermission");
6839
6840        Preconditions.checkFlagsArgument(modeFlags,
6841                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6842
6843        synchronized (this) {
6844            final int callingUid = Binder.getCallingUid();
6845            boolean persistChanged = false;
6846            GrantUri grantUri = new GrantUri(userId, uri, false);
6847
6848            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6849                    new GrantUri(userId, uri, false));
6850            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6851                    new GrantUri(userId, uri, true));
6852
6853            final boolean exactValid = (exactPerm != null)
6854                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6855            final boolean prefixValid = (prefixPerm != null)
6856                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6857
6858            if (!(exactValid || prefixValid)) {
6859                throw new SecurityException("No persistable permission grants found for UID "
6860                        + callingUid + " and Uri " + grantUri.toSafeString());
6861            }
6862
6863            if (exactValid) {
6864                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6865            }
6866            if (prefixValid) {
6867                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6868            }
6869
6870            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6871
6872            if (persistChanged) {
6873                schedulePersistUriGrants();
6874            }
6875        }
6876    }
6877
6878    @Override
6879    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6880        enforceNotIsolatedCaller("releasePersistableUriPermission");
6881
6882        Preconditions.checkFlagsArgument(modeFlags,
6883                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6884
6885        synchronized (this) {
6886            final int callingUid = Binder.getCallingUid();
6887            boolean persistChanged = false;
6888
6889            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6890                    new GrantUri(userId, uri, false));
6891            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6892                    new GrantUri(userId, uri, true));
6893            if (exactPerm == null && prefixPerm == null) {
6894                throw new SecurityException("No permission grants found for UID " + callingUid
6895                        + " and Uri " + uri.toSafeString());
6896            }
6897
6898            if (exactPerm != null) {
6899                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6900                removeUriPermissionIfNeededLocked(exactPerm);
6901            }
6902            if (prefixPerm != null) {
6903                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6904                removeUriPermissionIfNeededLocked(prefixPerm);
6905            }
6906
6907            if (persistChanged) {
6908                schedulePersistUriGrants();
6909            }
6910        }
6911    }
6912
6913    /**
6914     * Prune any older {@link UriPermission} for the given UID until outstanding
6915     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6916     *
6917     * @return if any mutations occured that require persisting.
6918     */
6919    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6920        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6921        if (perms == null) return false;
6922        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6923
6924        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6925        for (UriPermission perm : perms.values()) {
6926            if (perm.persistedModeFlags != 0) {
6927                persisted.add(perm);
6928            }
6929        }
6930
6931        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6932        if (trimCount <= 0) return false;
6933
6934        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6935        for (int i = 0; i < trimCount; i++) {
6936            final UriPermission perm = persisted.get(i);
6937
6938            if (DEBUG_URI_PERMISSION) {
6939                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6940            }
6941
6942            perm.releasePersistableModes(~0);
6943            removeUriPermissionIfNeededLocked(perm);
6944        }
6945
6946        return true;
6947    }
6948
6949    @Override
6950    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6951            String packageName, boolean incoming) {
6952        enforceNotIsolatedCaller("getPersistedUriPermissions");
6953        Preconditions.checkNotNull(packageName, "packageName");
6954
6955        final int callingUid = Binder.getCallingUid();
6956        final IPackageManager pm = AppGlobals.getPackageManager();
6957        try {
6958            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6959            if (packageUid != callingUid) {
6960                throw new SecurityException(
6961                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6962            }
6963        } catch (RemoteException e) {
6964            throw new SecurityException("Failed to verify package name ownership");
6965        }
6966
6967        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6968        synchronized (this) {
6969            if (incoming) {
6970                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6971                        callingUid);
6972                if (perms == null) {
6973                    Slog.w(TAG, "No permission grants found for " + packageName);
6974                } else {
6975                    for (UriPermission perm : perms.values()) {
6976                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6977                            result.add(perm.buildPersistedPublicApiObject());
6978                        }
6979                    }
6980                }
6981            } else {
6982                final int size = mGrantedUriPermissions.size();
6983                for (int i = 0; i < size; i++) {
6984                    final ArrayMap<GrantUri, UriPermission> perms =
6985                            mGrantedUriPermissions.valueAt(i);
6986                    for (UriPermission perm : perms.values()) {
6987                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6988                            result.add(perm.buildPersistedPublicApiObject());
6989                        }
6990                    }
6991                }
6992            }
6993        }
6994        return new ParceledListSlice<android.content.UriPermission>(result);
6995    }
6996
6997    @Override
6998    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6999        synchronized (this) {
7000            ProcessRecord app =
7001                who != null ? getRecordForAppLocked(who) : null;
7002            if (app == null) return;
7003
7004            Message msg = Message.obtain();
7005            msg.what = WAIT_FOR_DEBUGGER_MSG;
7006            msg.obj = app;
7007            msg.arg1 = waiting ? 1 : 0;
7008            mHandler.sendMessage(msg);
7009        }
7010    }
7011
7012    @Override
7013    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7014        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7015        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7016        outInfo.availMem = Process.getFreeMemory();
7017        outInfo.totalMem = Process.getTotalMemory();
7018        outInfo.threshold = homeAppMem;
7019        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7020        outInfo.hiddenAppThreshold = cachedAppMem;
7021        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7022                ProcessList.SERVICE_ADJ);
7023        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7024                ProcessList.VISIBLE_APP_ADJ);
7025        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7026                ProcessList.FOREGROUND_APP_ADJ);
7027    }
7028
7029    // =========================================================
7030    // TASK MANAGEMENT
7031    // =========================================================
7032
7033    @Override
7034    public List<IAppTask> getAppTasks() {
7035        int callingUid = Binder.getCallingUid();
7036        long ident = Binder.clearCallingIdentity();
7037        synchronized(this) {
7038            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7039            try {
7040                if (localLOGV) Slog.v(TAG, "getAppTasks");
7041
7042                final int N = mRecentTasks.size();
7043                for (int i = 0; i < N; i++) {
7044                    TaskRecord tr = mRecentTasks.get(i);
7045                    // Skip tasks that are not created by the caller
7046                    if (tr.creatorUid == callingUid) {
7047                        ActivityManager.RecentTaskInfo taskInfo =
7048                                createRecentTaskInfoFromTaskRecord(tr);
7049                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7050                        list.add(taskImpl);
7051                    }
7052                }
7053            } finally {
7054                Binder.restoreCallingIdentity(ident);
7055            }
7056            return list;
7057        }
7058    }
7059
7060    @Override
7061    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7062        final int callingUid = Binder.getCallingUid();
7063        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7064
7065        synchronized(this) {
7066            if (localLOGV) Slog.v(
7067                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7068
7069            final boolean allowed = checkCallingPermission(
7070                    android.Manifest.permission.GET_TASKS)
7071                    == PackageManager.PERMISSION_GRANTED;
7072            if (!allowed) {
7073                Slog.w(TAG, "getTasks: caller " + callingUid
7074                        + " does not hold GET_TASKS; limiting output");
7075            }
7076
7077            // TODO: Improve with MRU list from all ActivityStacks.
7078            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7079        }
7080
7081        return list;
7082    }
7083
7084    TaskRecord getMostRecentTask() {
7085        return mRecentTasks.get(0);
7086    }
7087
7088    /**
7089     * Creates a new RecentTaskInfo from a TaskRecord.
7090     */
7091    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7092        ActivityManager.RecentTaskInfo rti
7093                = new ActivityManager.RecentTaskInfo();
7094        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7095        rti.persistentId = tr.taskId;
7096        rti.baseIntent = new Intent(tr.getBaseIntent());
7097        rti.origActivity = tr.origActivity;
7098        rti.description = tr.lastDescription;
7099        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7100        rti.userId = tr.userId;
7101        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7102        return rti;
7103    }
7104
7105    @Override
7106    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7107            int flags, int userId) {
7108        final int callingUid = Binder.getCallingUid();
7109        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7110                false, true, "getRecentTasks", null);
7111
7112        synchronized (this) {
7113            final boolean allowed = checkCallingPermission(
7114                    android.Manifest.permission.GET_TASKS)
7115                    == PackageManager.PERMISSION_GRANTED;
7116            if (!allowed) {
7117                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7118                        + " does not hold GET_TASKS; limiting output");
7119            }
7120            final boolean detailed = checkCallingPermission(
7121                    android.Manifest.permission.GET_DETAILED_TASKS)
7122                    == PackageManager.PERMISSION_GRANTED;
7123
7124            IPackageManager pm = AppGlobals.getPackageManager();
7125
7126            final int N = mRecentTasks.size();
7127            ArrayList<ActivityManager.RecentTaskInfo> res
7128                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7129                            maxNum < N ? maxNum : N);
7130
7131            final Set<Integer> includedUsers;
7132            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7133                includedUsers = getProfileIdsLocked(userId);
7134            } else {
7135                includedUsers = new HashSet<Integer>();
7136            }
7137            includedUsers.add(Integer.valueOf(userId));
7138            for (int i=0; i<N && maxNum > 0; i++) {
7139                TaskRecord tr = mRecentTasks.get(i);
7140                // Only add calling user or related users recent tasks
7141                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7142
7143                // Return the entry if desired by the caller.  We always return
7144                // the first entry, because callers always expect this to be the
7145                // foreground app.  We may filter others if the caller has
7146                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7147                // we should exclude the entry.
7148
7149                if (i == 0
7150                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7151                        || (tr.intent == null)
7152                        || ((tr.intent.getFlags()
7153                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7154                    if (!allowed) {
7155                        // If the caller doesn't have the GET_TASKS permission, then only
7156                        // allow them to see a small subset of tasks -- their own and home.
7157                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7158                            continue;
7159                        }
7160                    }
7161
7162                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7163                    if (!detailed) {
7164                        rti.baseIntent.replaceExtras((Bundle)null);
7165                    }
7166
7167                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7168                        // Check whether this activity is currently available.
7169                        try {
7170                            if (rti.origActivity != null) {
7171                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7172                                        == null) {
7173                                    continue;
7174                                }
7175                            } else if (rti.baseIntent != null) {
7176                                if (pm.queryIntentActivities(rti.baseIntent,
7177                                        null, 0, userId) == null) {
7178                                    continue;
7179                                }
7180                            }
7181                        } catch (RemoteException e) {
7182                            // Will never happen.
7183                        }
7184                    }
7185
7186                    res.add(rti);
7187                    maxNum--;
7188                }
7189            }
7190            return res;
7191        }
7192    }
7193
7194    private TaskRecord recentTaskForIdLocked(int id) {
7195        final int N = mRecentTasks.size();
7196            for (int i=0; i<N; i++) {
7197                TaskRecord tr = mRecentTasks.get(i);
7198                if (tr.taskId == id) {
7199                    return tr;
7200                }
7201            }
7202            return null;
7203    }
7204
7205    @Override
7206    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7207        synchronized (this) {
7208            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7209                    "getTaskThumbnails()");
7210            TaskRecord tr = recentTaskForIdLocked(id);
7211            if (tr != null) {
7212                return tr.getTaskThumbnailsLocked();
7213            }
7214        }
7215        return null;
7216    }
7217
7218    @Override
7219    public Bitmap getTaskTopThumbnail(int id) {
7220        synchronized (this) {
7221            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7222                    "getTaskTopThumbnail()");
7223            TaskRecord tr = recentTaskForIdLocked(id);
7224            if (tr != null) {
7225                return tr.getTaskTopThumbnailLocked();
7226            }
7227        }
7228        return null;
7229    }
7230
7231    @Override
7232    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7233        synchronized (this) {
7234            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7235            if (r != null) {
7236                r.taskDescription = td;
7237                r.task.updateTaskDescription();
7238            }
7239        }
7240    }
7241
7242    @Override
7243    public boolean removeSubTask(int taskId, int subTaskIndex) {
7244        synchronized (this) {
7245            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7246                    "removeSubTask()");
7247            long ident = Binder.clearCallingIdentity();
7248            try {
7249                TaskRecord tr = recentTaskForIdLocked(taskId);
7250                if (tr != null) {
7251                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7252                }
7253                return false;
7254            } finally {
7255                Binder.restoreCallingIdentity(ident);
7256            }
7257        }
7258    }
7259
7260    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7261        if (!pr.killedByAm) {
7262            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7263            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7264                    pr.processName, pr.setAdj, reason);
7265            pr.killedByAm = true;
7266            Process.killProcessQuiet(pr.pid);
7267        }
7268    }
7269
7270    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7271        tr.disposeThumbnail();
7272        mRecentTasks.remove(tr);
7273        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7274        Intent baseIntent = new Intent(
7275                tr.intent != null ? tr.intent : tr.affinityIntent);
7276        ComponentName component = baseIntent.getComponent();
7277        if (component == null) {
7278            Slog.w(TAG, "Now component for base intent of task: " + tr);
7279            return;
7280        }
7281
7282        // Find any running services associated with this app.
7283        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7284
7285        if (killProcesses) {
7286            // Find any running processes associated with this app.
7287            final String pkg = component.getPackageName();
7288            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7289            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7290            for (int i=0; i<pmap.size(); i++) {
7291                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7292                for (int j=0; j<uids.size(); j++) {
7293                    ProcessRecord proc = uids.valueAt(j);
7294                    if (proc.userId != tr.userId) {
7295                        continue;
7296                    }
7297                    if (!proc.pkgList.containsKey(pkg)) {
7298                        continue;
7299                    }
7300                    procs.add(proc);
7301                }
7302            }
7303
7304            // Kill the running processes.
7305            for (int i=0; i<procs.size(); i++) {
7306                ProcessRecord pr = procs.get(i);
7307                if (pr == mHomeProcess) {
7308                    // Don't kill the home process along with tasks from the same package.
7309                    continue;
7310                }
7311                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7312                    killUnneededProcessLocked(pr, "remove task");
7313                } else {
7314                    pr.waitingToKill = "remove task";
7315                }
7316            }
7317        }
7318    }
7319
7320    /**
7321     * Removes the task with the specified task id.
7322     *
7323     * @param taskId Identifier of the task to be removed.
7324     * @param flags Additional operational flags.  May be 0 or
7325     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7326     * @return Returns true if the given task was found and removed.
7327     */
7328    private boolean removeTaskByIdLocked(int taskId, int flags) {
7329        TaskRecord tr = recentTaskForIdLocked(taskId);
7330        if (tr != null) {
7331            tr.removeTaskActivitiesLocked(-1, false);
7332            cleanUpRemovedTaskLocked(tr, flags);
7333            if (tr.isPersistable) {
7334                notifyTaskPersisterLocked(tr, true);
7335            }
7336            return true;
7337        }
7338        return false;
7339    }
7340
7341    @Override
7342    public boolean removeTask(int taskId, int flags) {
7343        synchronized (this) {
7344            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7345                    "removeTask()");
7346            long ident = Binder.clearCallingIdentity();
7347            try {
7348                return removeTaskByIdLocked(taskId, flags);
7349            } finally {
7350                Binder.restoreCallingIdentity(ident);
7351            }
7352        }
7353    }
7354
7355    /**
7356     * TODO: Add mController hook
7357     */
7358    @Override
7359    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7360        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7361                "moveTaskToFront()");
7362
7363        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7364        synchronized(this) {
7365            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7366                    Binder.getCallingUid(), "Task to front")) {
7367                ActivityOptions.abort(options);
7368                return;
7369            }
7370            final long origId = Binder.clearCallingIdentity();
7371            try {
7372                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7373                if (task == null) {
7374                    return;
7375                }
7376                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7377                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7378                    return;
7379                }
7380                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7381            } finally {
7382                Binder.restoreCallingIdentity(origId);
7383            }
7384            ActivityOptions.abort(options);
7385        }
7386    }
7387
7388    @Override
7389    public void moveTaskToBack(int taskId) {
7390        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7391                "moveTaskToBack()");
7392
7393        synchronized(this) {
7394            TaskRecord tr = recentTaskForIdLocked(taskId);
7395            if (tr != null) {
7396                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7397                ActivityStack stack = tr.stack;
7398                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7399                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7400                            Binder.getCallingUid(), "Task to back")) {
7401                        return;
7402                    }
7403                }
7404                final long origId = Binder.clearCallingIdentity();
7405                try {
7406                    stack.moveTaskToBackLocked(taskId, null);
7407                } finally {
7408                    Binder.restoreCallingIdentity(origId);
7409                }
7410            }
7411        }
7412    }
7413
7414    /**
7415     * Moves an activity, and all of the other activities within the same task, to the bottom
7416     * of the history stack.  The activity's order within the task is unchanged.
7417     *
7418     * @param token A reference to the activity we wish to move
7419     * @param nonRoot If false then this only works if the activity is the root
7420     *                of a task; if true it will work for any activity in a task.
7421     * @return Returns true if the move completed, false if not.
7422     */
7423    @Override
7424    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7425        enforceNotIsolatedCaller("moveActivityTaskToBack");
7426        synchronized(this) {
7427            final long origId = Binder.clearCallingIdentity();
7428            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7429            if (taskId >= 0) {
7430                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7431            }
7432            Binder.restoreCallingIdentity(origId);
7433        }
7434        return false;
7435    }
7436
7437    @Override
7438    public void moveTaskBackwards(int task) {
7439        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7440                "moveTaskBackwards()");
7441
7442        synchronized(this) {
7443            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7444                    Binder.getCallingUid(), "Task backwards")) {
7445                return;
7446            }
7447            final long origId = Binder.clearCallingIdentity();
7448            moveTaskBackwardsLocked(task);
7449            Binder.restoreCallingIdentity(origId);
7450        }
7451    }
7452
7453    private final void moveTaskBackwardsLocked(int task) {
7454        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7455    }
7456
7457    @Override
7458    public IBinder getHomeActivityToken() throws RemoteException {
7459        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7460                "getHomeActivityToken()");
7461        synchronized (this) {
7462            return mStackSupervisor.getHomeActivityToken();
7463        }
7464    }
7465
7466    @Override
7467    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7468            IActivityContainerCallback callback) throws RemoteException {
7469        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7470                "createActivityContainer()");
7471        synchronized (this) {
7472            if (parentActivityToken == null) {
7473                throw new IllegalArgumentException("parent token must not be null");
7474            }
7475            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7476            if (r == null) {
7477                return null;
7478            }
7479            if (callback == null) {
7480                throw new IllegalArgumentException("callback must not be null");
7481            }
7482            return mStackSupervisor.createActivityContainer(r, callback);
7483        }
7484    }
7485
7486    @Override
7487    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7488        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7489                "deleteActivityContainer()");
7490        synchronized (this) {
7491            mStackSupervisor.deleteActivityContainer(container);
7492        }
7493    }
7494
7495    @Override
7496    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7497            throws RemoteException {
7498        synchronized (this) {
7499            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7500            if (stack != null) {
7501                return stack.mActivityContainer;
7502            }
7503            return null;
7504        }
7505    }
7506
7507    @Override
7508    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7509        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7510                "moveTaskToStack()");
7511        if (stackId == HOME_STACK_ID) {
7512            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7513                    new RuntimeException("here").fillInStackTrace());
7514        }
7515        synchronized (this) {
7516            long ident = Binder.clearCallingIdentity();
7517            try {
7518                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7519                        + stackId + " toTop=" + toTop);
7520                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7521            } finally {
7522                Binder.restoreCallingIdentity(ident);
7523            }
7524        }
7525    }
7526
7527    @Override
7528    public void resizeStack(int stackBoxId, Rect bounds) {
7529        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7530                "resizeStackBox()");
7531        long ident = Binder.clearCallingIdentity();
7532        try {
7533            mWindowManager.resizeStack(stackBoxId, bounds);
7534        } finally {
7535            Binder.restoreCallingIdentity(ident);
7536        }
7537    }
7538
7539    @Override
7540    public List<StackInfo> getAllStackInfos() {
7541        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7542                "getAllStackInfos()");
7543        long ident = Binder.clearCallingIdentity();
7544        try {
7545            synchronized (this) {
7546                return mStackSupervisor.getAllStackInfosLocked();
7547            }
7548        } finally {
7549            Binder.restoreCallingIdentity(ident);
7550        }
7551    }
7552
7553    @Override
7554    public StackInfo getStackInfo(int stackId) {
7555        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7556                "getStackInfo()");
7557        long ident = Binder.clearCallingIdentity();
7558        try {
7559            synchronized (this) {
7560                return mStackSupervisor.getStackInfoLocked(stackId);
7561            }
7562        } finally {
7563            Binder.restoreCallingIdentity(ident);
7564        }
7565    }
7566
7567    @Override
7568    public boolean isInHomeStack(int taskId) {
7569        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7570                "getStackInfo()");
7571        long ident = Binder.clearCallingIdentity();
7572        try {
7573            synchronized (this) {
7574                TaskRecord tr = recentTaskForIdLocked(taskId);
7575                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7576            }
7577        } finally {
7578            Binder.restoreCallingIdentity(ident);
7579        }
7580    }
7581
7582    @Override
7583    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7584        synchronized(this) {
7585            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7586        }
7587    }
7588
7589    private boolean isLockTaskAuthorized(ComponentName name) {
7590        final DevicePolicyManager dpm = (DevicePolicyManager)
7591                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7592        return dpm != null && dpm.isLockTaskPermitted(name);
7593    }
7594
7595    private void startLockTaskMode(TaskRecord task) {
7596        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7597            return;
7598        }
7599        long ident = Binder.clearCallingIdentity();
7600        try {
7601            synchronized (this) {
7602                // Since we lost lock on task, make sure it is still there.
7603                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7604                if (task != null) {
7605                    mStackSupervisor.setLockTaskModeLocked(task);
7606                }
7607            }
7608        } finally {
7609            Binder.restoreCallingIdentity(ident);
7610        }
7611    }
7612
7613    @Override
7614    public void startLockTaskMode(int taskId) {
7615        long ident = Binder.clearCallingIdentity();
7616        try {
7617            final TaskRecord task;
7618            synchronized (this) {
7619                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7620            }
7621            if (task != null) {
7622                startLockTaskMode(task);
7623            }
7624        } finally {
7625            Binder.restoreCallingIdentity(ident);
7626        }
7627    }
7628
7629    @Override
7630    public void startLockTaskMode(IBinder token) {
7631        long ident = Binder.clearCallingIdentity();
7632        try {
7633            final TaskRecord task;
7634            synchronized (this) {
7635                final ActivityRecord r = ActivityRecord.forToken(token);
7636                if (r == null) {
7637                    return;
7638                }
7639                task = r.task;
7640            }
7641            if (task != null) {
7642                startLockTaskMode(task);
7643            }
7644        } finally {
7645            Binder.restoreCallingIdentity(ident);
7646        }
7647    }
7648
7649    @Override
7650    public void stopLockTaskMode() {
7651        // Check if the calling task is eligible to use lock task
7652        final int uid = Binder.getCallingUid();
7653        try {
7654            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7655            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7656                return;
7657            }
7658        } catch (RemoteException e) {
7659            Log.d(TAG, "stopLockTaskMode " + e);
7660            return;
7661        }
7662        // Stop lock task
7663        synchronized (this) {
7664            mStackSupervisor.setLockTaskModeLocked(null);
7665        }
7666    }
7667
7668    @Override
7669    public boolean isInLockTaskMode() {
7670        synchronized (this) {
7671            return mStackSupervisor.isInLockTaskMode();
7672        }
7673    }
7674
7675    // =========================================================
7676    // CONTENT PROVIDERS
7677    // =========================================================
7678
7679    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7680        List<ProviderInfo> providers = null;
7681        try {
7682            providers = AppGlobals.getPackageManager().
7683                queryContentProviders(app.processName, app.uid,
7684                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7685        } catch (RemoteException ex) {
7686        }
7687        if (DEBUG_MU)
7688            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7689        int userId = app.userId;
7690        if (providers != null) {
7691            int N = providers.size();
7692            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7693            for (int i=0; i<N; i++) {
7694                ProviderInfo cpi =
7695                    (ProviderInfo)providers.get(i);
7696                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7697                        cpi.name, cpi.flags);
7698                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7699                    // This is a singleton provider, but a user besides the
7700                    // default user is asking to initialize a process it runs
7701                    // in...  well, no, it doesn't actually run in this process,
7702                    // it runs in the process of the default user.  Get rid of it.
7703                    providers.remove(i);
7704                    N--;
7705                    i--;
7706                    continue;
7707                }
7708
7709                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7710                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7711                if (cpr == null) {
7712                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7713                    mProviderMap.putProviderByClass(comp, cpr);
7714                }
7715                if (DEBUG_MU)
7716                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7717                app.pubProviders.put(cpi.name, cpr);
7718                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7719                    // Don't add this if it is a platform component that is marked
7720                    // to run in multiple processes, because this is actually
7721                    // part of the framework so doesn't make sense to track as a
7722                    // separate apk in the process.
7723                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7724                }
7725                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7726            }
7727        }
7728        return providers;
7729    }
7730
7731    /**
7732     * Check if {@link ProcessRecord} has a possible chance at accessing the
7733     * given {@link ProviderInfo}. Final permission checking is always done
7734     * in {@link ContentProvider}.
7735     */
7736    private final String checkContentProviderPermissionLocked(
7737            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7738        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7739        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7740        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7741        // Looking for cross-user grants before to enforce the typical cross-users permissions
7742        if (userId != UserHandle.getUserId(callingUid)) {
7743            if (perms != null) {
7744                for (GrantUri grantUri : perms.keySet()) {
7745                    if (grantUri.sourceUserId == userId) {
7746                        String authority = grantUri.uri.getAuthority();
7747                        if (authority.equals(cpi.authority)) {
7748                            return null;
7749                        }
7750                    }
7751                }
7752            }
7753        }
7754        if (checkUser) {
7755            userId = handleIncomingUser(callingPid, callingUid, userId,
7756                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7757        }
7758        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7759                cpi.applicationInfo.uid, cpi.exported)
7760                == PackageManager.PERMISSION_GRANTED) {
7761            return null;
7762        }
7763        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7764                cpi.applicationInfo.uid, cpi.exported)
7765                == PackageManager.PERMISSION_GRANTED) {
7766            return null;
7767        }
7768
7769        PathPermission[] pps = cpi.pathPermissions;
7770        if (pps != null) {
7771            int i = pps.length;
7772            while (i > 0) {
7773                i--;
7774                PathPermission pp = pps[i];
7775                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7776                        cpi.applicationInfo.uid, cpi.exported)
7777                        == PackageManager.PERMISSION_GRANTED) {
7778                    return null;
7779                }
7780                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7781                        cpi.applicationInfo.uid, cpi.exported)
7782                        == PackageManager.PERMISSION_GRANTED) {
7783                    return null;
7784                }
7785            }
7786        }
7787
7788        if (perms != null) {
7789            for (GrantUri grantUri : perms.keySet()) {
7790                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7791                    return null;
7792                }
7793            }
7794        }
7795
7796        String msg;
7797        if (!cpi.exported) {
7798            msg = "Permission Denial: opening provider " + cpi.name
7799                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7800                    + ", uid=" + callingUid + ") that is not exported from uid "
7801                    + cpi.applicationInfo.uid;
7802        } else {
7803            msg = "Permission Denial: opening provider " + cpi.name
7804                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7805                    + ", uid=" + callingUid + ") requires "
7806                    + cpi.readPermission + " or " + cpi.writePermission;
7807        }
7808        Slog.w(TAG, msg);
7809        return msg;
7810    }
7811
7812    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7813            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7814        if (r != null) {
7815            for (int i=0; i<r.conProviders.size(); i++) {
7816                ContentProviderConnection conn = r.conProviders.get(i);
7817                if (conn.provider == cpr) {
7818                    if (DEBUG_PROVIDER) Slog.v(TAG,
7819                            "Adding provider requested by "
7820                            + r.processName + " from process "
7821                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7822                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7823                    if (stable) {
7824                        conn.stableCount++;
7825                        conn.numStableIncs++;
7826                    } else {
7827                        conn.unstableCount++;
7828                        conn.numUnstableIncs++;
7829                    }
7830                    return conn;
7831                }
7832            }
7833            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7834            if (stable) {
7835                conn.stableCount = 1;
7836                conn.numStableIncs = 1;
7837            } else {
7838                conn.unstableCount = 1;
7839                conn.numUnstableIncs = 1;
7840            }
7841            cpr.connections.add(conn);
7842            r.conProviders.add(conn);
7843            return conn;
7844        }
7845        cpr.addExternalProcessHandleLocked(externalProcessToken);
7846        return null;
7847    }
7848
7849    boolean decProviderCountLocked(ContentProviderConnection conn,
7850            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7851        if (conn != null) {
7852            cpr = conn.provider;
7853            if (DEBUG_PROVIDER) Slog.v(TAG,
7854                    "Removing provider requested by "
7855                    + conn.client.processName + " from process "
7856                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7857                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7858            if (stable) {
7859                conn.stableCount--;
7860            } else {
7861                conn.unstableCount--;
7862            }
7863            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7864                cpr.connections.remove(conn);
7865                conn.client.conProviders.remove(conn);
7866                return true;
7867            }
7868            return false;
7869        }
7870        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7871        return false;
7872    }
7873
7874    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7875            String name, IBinder token, boolean stable, int userId) {
7876        ContentProviderRecord cpr;
7877        ContentProviderConnection conn = null;
7878        ProviderInfo cpi = null;
7879
7880        synchronized(this) {
7881            ProcessRecord r = null;
7882            if (caller != null) {
7883                r = getRecordForAppLocked(caller);
7884                if (r == null) {
7885                    throw new SecurityException(
7886                            "Unable to find app for caller " + caller
7887                          + " (pid=" + Binder.getCallingPid()
7888                          + ") when getting content provider " + name);
7889                }
7890            }
7891
7892            boolean checkCrossUser = true;
7893
7894            // First check if this content provider has been published...
7895            cpr = mProviderMap.getProviderByName(name, userId);
7896            // If that didn't work, check if it exists for user 0 and then
7897            // verify that it's a singleton provider before using it.
7898            if (cpr == null && userId != UserHandle.USER_OWNER) {
7899                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
7900                if (cpr != null) {
7901                    cpi = cpr.info;
7902                    if (isSingleton(cpi.processName, cpi.applicationInfo,
7903                            cpi.name, cpi.flags)
7904                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
7905                        userId = UserHandle.USER_OWNER;
7906                        checkCrossUser = false;
7907                    } else {
7908                        cpr = null;
7909                        cpi = null;
7910                    }
7911                }
7912            }
7913
7914            boolean providerRunning = cpr != null;
7915            if (providerRunning) {
7916                cpi = cpr.info;
7917                String msg;
7918                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
7919                        != null) {
7920                    throw new SecurityException(msg);
7921                }
7922
7923                if (r != null && cpr.canRunHere(r)) {
7924                    // This provider has been published or is in the process
7925                    // of being published...  but it is also allowed to run
7926                    // in the caller's process, so don't make a connection
7927                    // and just let the caller instantiate its own instance.
7928                    ContentProviderHolder holder = cpr.newHolder(null);
7929                    // don't give caller the provider object, it needs
7930                    // to make its own.
7931                    holder.provider = null;
7932                    return holder;
7933                }
7934
7935                final long origId = Binder.clearCallingIdentity();
7936
7937                // In this case the provider instance already exists, so we can
7938                // return it right away.
7939                conn = incProviderCountLocked(r, cpr, token, stable);
7940                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7941                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7942                        // If this is a perceptible app accessing the provider,
7943                        // make sure to count it as being accessed and thus
7944                        // back up on the LRU list.  This is good because
7945                        // content providers are often expensive to start.
7946                        updateLruProcessLocked(cpr.proc, false, null);
7947                    }
7948                }
7949
7950                if (cpr.proc != null) {
7951                    if (false) {
7952                        if (cpr.name.flattenToShortString().equals(
7953                                "com.android.providers.calendar/.CalendarProvider2")) {
7954                            Slog.v(TAG, "****************** KILLING "
7955                                + cpr.name.flattenToShortString());
7956                            Process.killProcess(cpr.proc.pid);
7957                        }
7958                    }
7959                    boolean success = updateOomAdjLocked(cpr.proc);
7960                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7961                    // NOTE: there is still a race here where a signal could be
7962                    // pending on the process even though we managed to update its
7963                    // adj level.  Not sure what to do about this, but at least
7964                    // the race is now smaller.
7965                    if (!success) {
7966                        // Uh oh...  it looks like the provider's process
7967                        // has been killed on us.  We need to wait for a new
7968                        // process to be started, and make sure its death
7969                        // doesn't kill our process.
7970                        Slog.i(TAG,
7971                                "Existing provider " + cpr.name.flattenToShortString()
7972                                + " is crashing; detaching " + r);
7973                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7974                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7975                        if (!lastRef) {
7976                            // This wasn't the last ref our process had on
7977                            // the provider...  we have now been killed, bail.
7978                            return null;
7979                        }
7980                        providerRunning = false;
7981                        conn = null;
7982                    }
7983                }
7984
7985                Binder.restoreCallingIdentity(origId);
7986            }
7987
7988            boolean singleton;
7989            if (!providerRunning) {
7990                try {
7991                    cpi = AppGlobals.getPackageManager().
7992                        resolveContentProvider(name,
7993                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7994                } catch (RemoteException ex) {
7995                }
7996                if (cpi == null) {
7997                    return null;
7998                }
7999                // If the provider is a singleton AND
8000                // (it's a call within the same user || the provider is a
8001                // privileged app)
8002                // Then allow connecting to the singleton provider
8003                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8004                        cpi.name, cpi.flags)
8005                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8006                if (singleton) {
8007                    userId = UserHandle.USER_OWNER;
8008                }
8009                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8010
8011                String msg;
8012                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8013                        != null) {
8014                    throw new SecurityException(msg);
8015                }
8016
8017                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8018                        && !cpi.processName.equals("system")) {
8019                    // If this content provider does not run in the system
8020                    // process, and the system is not yet ready to run other
8021                    // processes, then fail fast instead of hanging.
8022                    throw new IllegalArgumentException(
8023                            "Attempt to launch content provider before system ready");
8024                }
8025
8026                // Make sure that the user who owns this provider is started.  If not,
8027                // we don't want to allow it to run.
8028                if (mStartedUsers.get(userId) == null) {
8029                    Slog.w(TAG, "Unable to launch app "
8030                            + cpi.applicationInfo.packageName + "/"
8031                            + cpi.applicationInfo.uid + " for provider "
8032                            + name + ": user " + userId + " is stopped");
8033                    return null;
8034                }
8035
8036                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8037                cpr = mProviderMap.getProviderByClass(comp, userId);
8038                final boolean firstClass = cpr == null;
8039                if (firstClass) {
8040                    try {
8041                        ApplicationInfo ai =
8042                            AppGlobals.getPackageManager().
8043                                getApplicationInfo(
8044                                        cpi.applicationInfo.packageName,
8045                                        STOCK_PM_FLAGS, userId);
8046                        if (ai == null) {
8047                            Slog.w(TAG, "No package info for content provider "
8048                                    + cpi.name);
8049                            return null;
8050                        }
8051                        ai = getAppInfoForUser(ai, userId);
8052                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8053                    } catch (RemoteException ex) {
8054                        // pm is in same process, this will never happen.
8055                    }
8056                }
8057
8058                if (r != null && cpr.canRunHere(r)) {
8059                    // If this is a multiprocess provider, then just return its
8060                    // info and allow the caller to instantiate it.  Only do
8061                    // this if the provider is the same user as the caller's
8062                    // process, or can run as root (so can be in any process).
8063                    return cpr.newHolder(null);
8064                }
8065
8066                if (DEBUG_PROVIDER) {
8067                    RuntimeException e = new RuntimeException("here");
8068                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8069                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8070                }
8071
8072                // This is single process, and our app is now connecting to it.
8073                // See if we are already in the process of launching this
8074                // provider.
8075                final int N = mLaunchingProviders.size();
8076                int i;
8077                for (i=0; i<N; i++) {
8078                    if (mLaunchingProviders.get(i) == cpr) {
8079                        break;
8080                    }
8081                }
8082
8083                // If the provider is not already being launched, then get it
8084                // started.
8085                if (i >= N) {
8086                    final long origId = Binder.clearCallingIdentity();
8087
8088                    try {
8089                        // Content provider is now in use, its package can't be stopped.
8090                        try {
8091                            AppGlobals.getPackageManager().setPackageStoppedState(
8092                                    cpr.appInfo.packageName, false, userId);
8093                        } catch (RemoteException e) {
8094                        } catch (IllegalArgumentException e) {
8095                            Slog.w(TAG, "Failed trying to unstop package "
8096                                    + cpr.appInfo.packageName + ": " + e);
8097                        }
8098
8099                        // Use existing process if already started
8100                        ProcessRecord proc = getProcessRecordLocked(
8101                                cpi.processName, cpr.appInfo.uid, false);
8102                        if (proc != null && proc.thread != null) {
8103                            if (DEBUG_PROVIDER) {
8104                                Slog.d(TAG, "Installing in existing process " + proc);
8105                            }
8106                            proc.pubProviders.put(cpi.name, cpr);
8107                            try {
8108                                proc.thread.scheduleInstallProvider(cpi);
8109                            } catch (RemoteException e) {
8110                            }
8111                        } else {
8112                            proc = startProcessLocked(cpi.processName,
8113                                    cpr.appInfo, false, 0, "content provider",
8114                                    new ComponentName(cpi.applicationInfo.packageName,
8115                                            cpi.name), false, false, false);
8116                            if (proc == null) {
8117                                Slog.w(TAG, "Unable to launch app "
8118                                        + cpi.applicationInfo.packageName + "/"
8119                                        + cpi.applicationInfo.uid + " for provider "
8120                                        + name + ": process is bad");
8121                                return null;
8122                            }
8123                        }
8124                        cpr.launchingApp = proc;
8125                        mLaunchingProviders.add(cpr);
8126                    } finally {
8127                        Binder.restoreCallingIdentity(origId);
8128                    }
8129                }
8130
8131                // Make sure the provider is published (the same provider class
8132                // may be published under multiple names).
8133                if (firstClass) {
8134                    mProviderMap.putProviderByClass(comp, cpr);
8135                }
8136
8137                mProviderMap.putProviderByName(name, cpr);
8138                conn = incProviderCountLocked(r, cpr, token, stable);
8139                if (conn != null) {
8140                    conn.waiting = true;
8141                }
8142            }
8143        }
8144
8145        // Wait for the provider to be published...
8146        synchronized (cpr) {
8147            while (cpr.provider == null) {
8148                if (cpr.launchingApp == null) {
8149                    Slog.w(TAG, "Unable to launch app "
8150                            + cpi.applicationInfo.packageName + "/"
8151                            + cpi.applicationInfo.uid + " for provider "
8152                            + name + ": launching app became null");
8153                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8154                            UserHandle.getUserId(cpi.applicationInfo.uid),
8155                            cpi.applicationInfo.packageName,
8156                            cpi.applicationInfo.uid, name);
8157                    return null;
8158                }
8159                try {
8160                    if (DEBUG_MU) {
8161                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8162                                + cpr.launchingApp);
8163                    }
8164                    if (conn != null) {
8165                        conn.waiting = true;
8166                    }
8167                    cpr.wait();
8168                } catch (InterruptedException ex) {
8169                } finally {
8170                    if (conn != null) {
8171                        conn.waiting = false;
8172                    }
8173                }
8174            }
8175        }
8176        return cpr != null ? cpr.newHolder(conn) : null;
8177    }
8178
8179    @Override
8180    public final ContentProviderHolder getContentProvider(
8181            IApplicationThread caller, String name, int userId, boolean stable) {
8182        enforceNotIsolatedCaller("getContentProvider");
8183        if (caller == null) {
8184            String msg = "null IApplicationThread when getting content provider "
8185                    + name;
8186            Slog.w(TAG, msg);
8187            throw new SecurityException(msg);
8188        }
8189        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8190        // with cross-user grant.
8191        return getContentProviderImpl(caller, name, null, stable, userId);
8192    }
8193
8194    public ContentProviderHolder getContentProviderExternal(
8195            String name, int userId, IBinder token) {
8196        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8197            "Do not have permission in call getContentProviderExternal()");
8198        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8199                false, true, "getContentProvider", null);
8200        return getContentProviderExternalUnchecked(name, token, userId);
8201    }
8202
8203    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8204            IBinder token, int userId) {
8205        return getContentProviderImpl(null, name, token, true, userId);
8206    }
8207
8208    /**
8209     * Drop a content provider from a ProcessRecord's bookkeeping
8210     */
8211    public void removeContentProvider(IBinder connection, boolean stable) {
8212        enforceNotIsolatedCaller("removeContentProvider");
8213        long ident = Binder.clearCallingIdentity();
8214        try {
8215            synchronized (this) {
8216                ContentProviderConnection conn;
8217                try {
8218                    conn = (ContentProviderConnection)connection;
8219                } catch (ClassCastException e) {
8220                    String msg ="removeContentProvider: " + connection
8221                            + " not a ContentProviderConnection";
8222                    Slog.w(TAG, msg);
8223                    throw new IllegalArgumentException(msg);
8224                }
8225                if (conn == null) {
8226                    throw new NullPointerException("connection is null");
8227                }
8228                if (decProviderCountLocked(conn, null, null, stable)) {
8229                    updateOomAdjLocked();
8230                }
8231            }
8232        } finally {
8233            Binder.restoreCallingIdentity(ident);
8234        }
8235    }
8236
8237    public void removeContentProviderExternal(String name, IBinder token) {
8238        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8239            "Do not have permission in call removeContentProviderExternal()");
8240        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8241    }
8242
8243    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8244        synchronized (this) {
8245            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8246            if(cpr == null) {
8247                //remove from mProvidersByClass
8248                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8249                return;
8250            }
8251
8252            //update content provider record entry info
8253            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8254            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8255            if (localCpr.hasExternalProcessHandles()) {
8256                if (localCpr.removeExternalProcessHandleLocked(token)) {
8257                    updateOomAdjLocked();
8258                } else {
8259                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8260                            + " with no external reference for token: "
8261                            + token + ".");
8262                }
8263            } else {
8264                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8265                        + " with no external references.");
8266            }
8267        }
8268    }
8269
8270    public final void publishContentProviders(IApplicationThread caller,
8271            List<ContentProviderHolder> providers) {
8272        if (providers == null) {
8273            return;
8274        }
8275
8276        enforceNotIsolatedCaller("publishContentProviders");
8277        synchronized (this) {
8278            final ProcessRecord r = getRecordForAppLocked(caller);
8279            if (DEBUG_MU)
8280                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8281            if (r == null) {
8282                throw new SecurityException(
8283                        "Unable to find app for caller " + caller
8284                      + " (pid=" + Binder.getCallingPid()
8285                      + ") when publishing content providers");
8286            }
8287
8288            final long origId = Binder.clearCallingIdentity();
8289
8290            final int N = providers.size();
8291            for (int i=0; i<N; i++) {
8292                ContentProviderHolder src = providers.get(i);
8293                if (src == null || src.info == null || src.provider == null) {
8294                    continue;
8295                }
8296                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8297                if (DEBUG_MU)
8298                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8299                if (dst != null) {
8300                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8301                    mProviderMap.putProviderByClass(comp, dst);
8302                    String names[] = dst.info.authority.split(";");
8303                    for (int j = 0; j < names.length; j++) {
8304                        mProviderMap.putProviderByName(names[j], dst);
8305                    }
8306
8307                    int NL = mLaunchingProviders.size();
8308                    int j;
8309                    for (j=0; j<NL; j++) {
8310                        if (mLaunchingProviders.get(j) == dst) {
8311                            mLaunchingProviders.remove(j);
8312                            j--;
8313                            NL--;
8314                        }
8315                    }
8316                    synchronized (dst) {
8317                        dst.provider = src.provider;
8318                        dst.proc = r;
8319                        dst.notifyAll();
8320                    }
8321                    updateOomAdjLocked(r);
8322                }
8323            }
8324
8325            Binder.restoreCallingIdentity(origId);
8326        }
8327    }
8328
8329    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8330        ContentProviderConnection conn;
8331        try {
8332            conn = (ContentProviderConnection)connection;
8333        } catch (ClassCastException e) {
8334            String msg ="refContentProvider: " + connection
8335                    + " not a ContentProviderConnection";
8336            Slog.w(TAG, msg);
8337            throw new IllegalArgumentException(msg);
8338        }
8339        if (conn == null) {
8340            throw new NullPointerException("connection is null");
8341        }
8342
8343        synchronized (this) {
8344            if (stable > 0) {
8345                conn.numStableIncs += stable;
8346            }
8347            stable = conn.stableCount + stable;
8348            if (stable < 0) {
8349                throw new IllegalStateException("stableCount < 0: " + stable);
8350            }
8351
8352            if (unstable > 0) {
8353                conn.numUnstableIncs += unstable;
8354            }
8355            unstable = conn.unstableCount + unstable;
8356            if (unstable < 0) {
8357                throw new IllegalStateException("unstableCount < 0: " + unstable);
8358            }
8359
8360            if ((stable+unstable) <= 0) {
8361                throw new IllegalStateException("ref counts can't go to zero here: stable="
8362                        + stable + " unstable=" + unstable);
8363            }
8364            conn.stableCount = stable;
8365            conn.unstableCount = unstable;
8366            return !conn.dead;
8367        }
8368    }
8369
8370    public void unstableProviderDied(IBinder connection) {
8371        ContentProviderConnection conn;
8372        try {
8373            conn = (ContentProviderConnection)connection;
8374        } catch (ClassCastException e) {
8375            String msg ="refContentProvider: " + connection
8376                    + " not a ContentProviderConnection";
8377            Slog.w(TAG, msg);
8378            throw new IllegalArgumentException(msg);
8379        }
8380        if (conn == null) {
8381            throw new NullPointerException("connection is null");
8382        }
8383
8384        // Safely retrieve the content provider associated with the connection.
8385        IContentProvider provider;
8386        synchronized (this) {
8387            provider = conn.provider.provider;
8388        }
8389
8390        if (provider == null) {
8391            // Um, yeah, we're way ahead of you.
8392            return;
8393        }
8394
8395        // Make sure the caller is being honest with us.
8396        if (provider.asBinder().pingBinder()) {
8397            // Er, no, still looks good to us.
8398            synchronized (this) {
8399                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8400                        + " says " + conn + " died, but we don't agree");
8401                return;
8402            }
8403        }
8404
8405        // Well look at that!  It's dead!
8406        synchronized (this) {
8407            if (conn.provider.provider != provider) {
8408                // But something changed...  good enough.
8409                return;
8410            }
8411
8412            ProcessRecord proc = conn.provider.proc;
8413            if (proc == null || proc.thread == null) {
8414                // Seems like the process is already cleaned up.
8415                return;
8416            }
8417
8418            // As far as we're concerned, this is just like receiving a
8419            // death notification...  just a bit prematurely.
8420            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8421                    + ") early provider death");
8422            final long ident = Binder.clearCallingIdentity();
8423            try {
8424                appDiedLocked(proc, proc.pid, proc.thread);
8425            } finally {
8426                Binder.restoreCallingIdentity(ident);
8427            }
8428        }
8429    }
8430
8431    @Override
8432    public void appNotRespondingViaProvider(IBinder connection) {
8433        enforceCallingPermission(
8434                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8435
8436        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8437        if (conn == null) {
8438            Slog.w(TAG, "ContentProviderConnection is null");
8439            return;
8440        }
8441
8442        final ProcessRecord host = conn.provider.proc;
8443        if (host == null) {
8444            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8445            return;
8446        }
8447
8448        final long token = Binder.clearCallingIdentity();
8449        try {
8450            appNotResponding(host, null, null, false, "ContentProvider not responding");
8451        } finally {
8452            Binder.restoreCallingIdentity(token);
8453        }
8454    }
8455
8456    public final void installSystemProviders() {
8457        List<ProviderInfo> providers;
8458        synchronized (this) {
8459            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8460            providers = generateApplicationProvidersLocked(app);
8461            if (providers != null) {
8462                for (int i=providers.size()-1; i>=0; i--) {
8463                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8464                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8465                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8466                                + ": not system .apk");
8467                        providers.remove(i);
8468                    }
8469                }
8470            }
8471        }
8472        if (providers != null) {
8473            mSystemThread.installSystemProviders(providers);
8474        }
8475
8476        mCoreSettingsObserver = new CoreSettingsObserver(this);
8477
8478        mUsageStatsService.monitorPackages();
8479    }
8480
8481    /**
8482     * Allows app to retrieve the MIME type of a URI without having permission
8483     * to access its content provider.
8484     *
8485     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8486     *
8487     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8488     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8489     */
8490    public String getProviderMimeType(Uri uri, int userId) {
8491        enforceNotIsolatedCaller("getProviderMimeType");
8492        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8493                userId, false, true, "getProviderMimeType", null);
8494        final String name = uri.getAuthority();
8495        final long ident = Binder.clearCallingIdentity();
8496        ContentProviderHolder holder = null;
8497
8498        try {
8499            holder = getContentProviderExternalUnchecked(name, null, userId);
8500            if (holder != null) {
8501                return holder.provider.getType(uri);
8502            }
8503        } catch (RemoteException e) {
8504            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8505            return null;
8506        } finally {
8507            if (holder != null) {
8508                removeContentProviderExternalUnchecked(name, null, userId);
8509            }
8510            Binder.restoreCallingIdentity(ident);
8511        }
8512
8513        return null;
8514    }
8515
8516    // =========================================================
8517    // GLOBAL MANAGEMENT
8518    // =========================================================
8519
8520    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8521            boolean isolated) {
8522        String proc = customProcess != null ? customProcess : info.processName;
8523        BatteryStatsImpl.Uid.Proc ps = null;
8524        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8525        int uid = info.uid;
8526        if (isolated) {
8527            int userId = UserHandle.getUserId(uid);
8528            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8529            while (true) {
8530                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8531                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8532                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8533                }
8534                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8535                mNextIsolatedProcessUid++;
8536                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8537                    // No process for this uid, use it.
8538                    break;
8539                }
8540                stepsLeft--;
8541                if (stepsLeft <= 0) {
8542                    return null;
8543                }
8544            }
8545        }
8546        return new ProcessRecord(stats, info, proc, uid);
8547    }
8548
8549    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8550        ProcessRecord app;
8551        if (!isolated) {
8552            app = getProcessRecordLocked(info.processName, info.uid, true);
8553        } else {
8554            app = null;
8555        }
8556
8557        if (app == null) {
8558            app = newProcessRecordLocked(info, null, isolated);
8559            mProcessNames.put(info.processName, app.uid, app);
8560            if (isolated) {
8561                mIsolatedProcesses.put(app.uid, app);
8562            }
8563            updateLruProcessLocked(app, false, null);
8564            updateOomAdjLocked();
8565        }
8566
8567        // This package really, really can not be stopped.
8568        try {
8569            AppGlobals.getPackageManager().setPackageStoppedState(
8570                    info.packageName, false, UserHandle.getUserId(app.uid));
8571        } catch (RemoteException e) {
8572        } catch (IllegalArgumentException e) {
8573            Slog.w(TAG, "Failed trying to unstop package "
8574                    + info.packageName + ": " + e);
8575        }
8576
8577        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8578                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8579            app.persistent = true;
8580            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8581        }
8582        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8583            mPersistentStartingProcesses.add(app);
8584            startProcessLocked(app, "added application", app.processName);
8585        }
8586
8587        return app;
8588    }
8589
8590    public void unhandledBack() {
8591        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8592                "unhandledBack()");
8593
8594        synchronized(this) {
8595            final long origId = Binder.clearCallingIdentity();
8596            try {
8597                getFocusedStack().unhandledBackLocked();
8598            } finally {
8599                Binder.restoreCallingIdentity(origId);
8600            }
8601        }
8602    }
8603
8604    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8605        enforceNotIsolatedCaller("openContentUri");
8606        final int userId = UserHandle.getCallingUserId();
8607        String name = uri.getAuthority();
8608        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8609        ParcelFileDescriptor pfd = null;
8610        if (cph != null) {
8611            // We record the binder invoker's uid in thread-local storage before
8612            // going to the content provider to open the file.  Later, in the code
8613            // that handles all permissions checks, we look for this uid and use
8614            // that rather than the Activity Manager's own uid.  The effect is that
8615            // we do the check against the caller's permissions even though it looks
8616            // to the content provider like the Activity Manager itself is making
8617            // the request.
8618            sCallerIdentity.set(new Identity(
8619                    Binder.getCallingPid(), Binder.getCallingUid()));
8620            try {
8621                pfd = cph.provider.openFile(null, uri, "r", null);
8622            } catch (FileNotFoundException e) {
8623                // do nothing; pfd will be returned null
8624            } finally {
8625                // Ensure that whatever happens, we clean up the identity state
8626                sCallerIdentity.remove();
8627            }
8628
8629            // We've got the fd now, so we're done with the provider.
8630            removeContentProviderExternalUnchecked(name, null, userId);
8631        } else {
8632            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8633        }
8634        return pfd;
8635    }
8636
8637    // Actually is sleeping or shutting down or whatever else in the future
8638    // is an inactive state.
8639    public boolean isSleepingOrShuttingDown() {
8640        return mSleeping || mShuttingDown;
8641    }
8642
8643    public boolean isSleeping() {
8644        return mSleeping;
8645    }
8646
8647    void goingToSleep() {
8648        synchronized(this) {
8649            mWentToSleep = true;
8650            updateEventDispatchingLocked();
8651            goToSleepIfNeededLocked();
8652        }
8653    }
8654
8655    void finishRunningVoiceLocked() {
8656        if (mRunningVoice) {
8657            mRunningVoice = false;
8658            goToSleepIfNeededLocked();
8659        }
8660    }
8661
8662    void goToSleepIfNeededLocked() {
8663        if (mWentToSleep && !mRunningVoice) {
8664            if (!mSleeping) {
8665                mSleeping = true;
8666                mStackSupervisor.goingToSleepLocked();
8667
8668                // Initialize the wake times of all processes.
8669                checkExcessivePowerUsageLocked(false);
8670                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8671                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8672                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8673            }
8674        }
8675    }
8676
8677    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8678        mTaskPersister.notify(task, flush);
8679    }
8680
8681    @Override
8682    public boolean shutdown(int timeout) {
8683        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8684                != PackageManager.PERMISSION_GRANTED) {
8685            throw new SecurityException("Requires permission "
8686                    + android.Manifest.permission.SHUTDOWN);
8687        }
8688
8689        boolean timedout = false;
8690
8691        synchronized(this) {
8692            mShuttingDown = true;
8693            updateEventDispatchingLocked();
8694            timedout = mStackSupervisor.shutdownLocked(timeout);
8695        }
8696
8697        mAppOpsService.shutdown();
8698        mUsageStatsService.shutdown();
8699        mBatteryStatsService.shutdown();
8700        synchronized (this) {
8701            mProcessStats.shutdownLocked();
8702        }
8703        notifyTaskPersisterLocked(null, true);
8704
8705        return timedout;
8706    }
8707
8708    public final void activitySlept(IBinder token) {
8709        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8710
8711        final long origId = Binder.clearCallingIdentity();
8712
8713        synchronized (this) {
8714            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8715            if (r != null) {
8716                mStackSupervisor.activitySleptLocked(r);
8717            }
8718        }
8719
8720        Binder.restoreCallingIdentity(origId);
8721    }
8722
8723    void logLockScreen(String msg) {
8724        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8725                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8726                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8727                mStackSupervisor.mDismissKeyguardOnNextActivity);
8728    }
8729
8730    private void comeOutOfSleepIfNeededLocked() {
8731        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8732            if (mSleeping) {
8733                mSleeping = false;
8734                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8735            }
8736        }
8737    }
8738
8739    void wakingUp() {
8740        synchronized(this) {
8741            mWentToSleep = false;
8742            updateEventDispatchingLocked();
8743            comeOutOfSleepIfNeededLocked();
8744        }
8745    }
8746
8747    void startRunningVoiceLocked() {
8748        if (!mRunningVoice) {
8749            mRunningVoice = true;
8750            comeOutOfSleepIfNeededLocked();
8751        }
8752    }
8753
8754    private void updateEventDispatchingLocked() {
8755        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8756    }
8757
8758    public void setLockScreenShown(boolean shown) {
8759        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8760                != PackageManager.PERMISSION_GRANTED) {
8761            throw new SecurityException("Requires permission "
8762                    + android.Manifest.permission.DEVICE_POWER);
8763        }
8764
8765        synchronized(this) {
8766            long ident = Binder.clearCallingIdentity();
8767            try {
8768                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8769                mLockScreenShown = shown;
8770                comeOutOfSleepIfNeededLocked();
8771            } finally {
8772                Binder.restoreCallingIdentity(ident);
8773            }
8774        }
8775    }
8776
8777    public void stopAppSwitches() {
8778        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8779                != PackageManager.PERMISSION_GRANTED) {
8780            throw new SecurityException("Requires permission "
8781                    + android.Manifest.permission.STOP_APP_SWITCHES);
8782        }
8783
8784        synchronized(this) {
8785            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8786                    + APP_SWITCH_DELAY_TIME;
8787            mDidAppSwitch = false;
8788            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8789            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8790            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8791        }
8792    }
8793
8794    public void resumeAppSwitches() {
8795        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8796                != PackageManager.PERMISSION_GRANTED) {
8797            throw new SecurityException("Requires permission "
8798                    + android.Manifest.permission.STOP_APP_SWITCHES);
8799        }
8800
8801        synchronized(this) {
8802            // Note that we don't execute any pending app switches... we will
8803            // let those wait until either the timeout, or the next start
8804            // activity request.
8805            mAppSwitchesAllowedTime = 0;
8806        }
8807    }
8808
8809    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8810            String name) {
8811        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8812            return true;
8813        }
8814
8815        final int perm = checkComponentPermission(
8816                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8817                callingUid, -1, true);
8818        if (perm == PackageManager.PERMISSION_GRANTED) {
8819            return true;
8820        }
8821
8822        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8823        return false;
8824    }
8825
8826    public void setDebugApp(String packageName, boolean waitForDebugger,
8827            boolean persistent) {
8828        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8829                "setDebugApp()");
8830
8831        long ident = Binder.clearCallingIdentity();
8832        try {
8833            // Note that this is not really thread safe if there are multiple
8834            // callers into it at the same time, but that's not a situation we
8835            // care about.
8836            if (persistent) {
8837                final ContentResolver resolver = mContext.getContentResolver();
8838                Settings.Global.putString(
8839                    resolver, Settings.Global.DEBUG_APP,
8840                    packageName);
8841                Settings.Global.putInt(
8842                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8843                    waitForDebugger ? 1 : 0);
8844            }
8845
8846            synchronized (this) {
8847                if (!persistent) {
8848                    mOrigDebugApp = mDebugApp;
8849                    mOrigWaitForDebugger = mWaitForDebugger;
8850                }
8851                mDebugApp = packageName;
8852                mWaitForDebugger = waitForDebugger;
8853                mDebugTransient = !persistent;
8854                if (packageName != null) {
8855                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8856                            false, UserHandle.USER_ALL, "set debug app");
8857                }
8858            }
8859        } finally {
8860            Binder.restoreCallingIdentity(ident);
8861        }
8862    }
8863
8864    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8865        synchronized (this) {
8866            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8867            if (!isDebuggable) {
8868                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8869                    throw new SecurityException("Process not debuggable: " + app.packageName);
8870                }
8871            }
8872
8873            mOpenGlTraceApp = processName;
8874        }
8875    }
8876
8877    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8878            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8879        synchronized (this) {
8880            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8881            if (!isDebuggable) {
8882                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8883                    throw new SecurityException("Process not debuggable: " + app.packageName);
8884                }
8885            }
8886            mProfileApp = processName;
8887            mProfileFile = profileFile;
8888            if (mProfileFd != null) {
8889                try {
8890                    mProfileFd.close();
8891                } catch (IOException e) {
8892                }
8893                mProfileFd = null;
8894            }
8895            mProfileFd = profileFd;
8896            mProfileType = 0;
8897            mAutoStopProfiler = autoStopProfiler;
8898        }
8899    }
8900
8901    @Override
8902    public void setAlwaysFinish(boolean enabled) {
8903        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8904                "setAlwaysFinish()");
8905
8906        Settings.Global.putInt(
8907                mContext.getContentResolver(),
8908                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8909
8910        synchronized (this) {
8911            mAlwaysFinishActivities = enabled;
8912        }
8913    }
8914
8915    @Override
8916    public void setActivityController(IActivityController controller) {
8917        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8918                "setActivityController()");
8919        synchronized (this) {
8920            mController = controller;
8921            Watchdog.getInstance().setActivityController(controller);
8922        }
8923    }
8924
8925    @Override
8926    public void setUserIsMonkey(boolean userIsMonkey) {
8927        synchronized (this) {
8928            synchronized (mPidsSelfLocked) {
8929                final int callingPid = Binder.getCallingPid();
8930                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8931                if (precessRecord == null) {
8932                    throw new SecurityException("Unknown process: " + callingPid);
8933                }
8934                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8935                    throw new SecurityException("Only an instrumentation process "
8936                            + "with a UiAutomation can call setUserIsMonkey");
8937                }
8938            }
8939            mUserIsMonkey = userIsMonkey;
8940        }
8941    }
8942
8943    @Override
8944    public boolean isUserAMonkey() {
8945        synchronized (this) {
8946            // If there is a controller also implies the user is a monkey.
8947            return (mUserIsMonkey || mController != null);
8948        }
8949    }
8950
8951    public void requestBugReport() {
8952        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8953        SystemProperties.set("ctl.start", "bugreport");
8954    }
8955
8956    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8957        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8958    }
8959
8960    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8961        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8962            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8963        }
8964        return KEY_DISPATCHING_TIMEOUT;
8965    }
8966
8967    @Override
8968    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8969        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8970                != PackageManager.PERMISSION_GRANTED) {
8971            throw new SecurityException("Requires permission "
8972                    + android.Manifest.permission.FILTER_EVENTS);
8973        }
8974        ProcessRecord proc;
8975        long timeout;
8976        synchronized (this) {
8977            synchronized (mPidsSelfLocked) {
8978                proc = mPidsSelfLocked.get(pid);
8979            }
8980            timeout = getInputDispatchingTimeoutLocked(proc);
8981        }
8982
8983        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8984            return -1;
8985        }
8986
8987        return timeout;
8988    }
8989
8990    /**
8991     * Handle input dispatching timeouts.
8992     * Returns whether input dispatching should be aborted or not.
8993     */
8994    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8995            final ActivityRecord activity, final ActivityRecord parent,
8996            final boolean aboveSystem, String reason) {
8997        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8998                != PackageManager.PERMISSION_GRANTED) {
8999            throw new SecurityException("Requires permission "
9000                    + android.Manifest.permission.FILTER_EVENTS);
9001        }
9002
9003        final String annotation;
9004        if (reason == null) {
9005            annotation = "Input dispatching timed out";
9006        } else {
9007            annotation = "Input dispatching timed out (" + reason + ")";
9008        }
9009
9010        if (proc != null) {
9011            synchronized (this) {
9012                if (proc.debugging) {
9013                    return false;
9014                }
9015
9016                if (mDidDexOpt) {
9017                    // Give more time since we were dexopting.
9018                    mDidDexOpt = false;
9019                    return false;
9020                }
9021
9022                if (proc.instrumentationClass != null) {
9023                    Bundle info = new Bundle();
9024                    info.putString("shortMsg", "keyDispatchingTimedOut");
9025                    info.putString("longMsg", annotation);
9026                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9027                    return true;
9028                }
9029            }
9030            mHandler.post(new Runnable() {
9031                @Override
9032                public void run() {
9033                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9034                }
9035            });
9036        }
9037
9038        return true;
9039    }
9040
9041    public Bundle getAssistContextExtras(int requestType) {
9042        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9043                "getAssistContextExtras()");
9044        PendingAssistExtras pae;
9045        Bundle extras = new Bundle();
9046        synchronized (this) {
9047            ActivityRecord activity = getFocusedStack().mResumedActivity;
9048            if (activity == null) {
9049                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9050                return null;
9051            }
9052            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9053            if (activity.app == null || activity.app.thread == null) {
9054                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9055                return extras;
9056            }
9057            if (activity.app.pid == Binder.getCallingPid()) {
9058                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9059                return extras;
9060            }
9061            pae = new PendingAssistExtras(activity);
9062            try {
9063                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9064                        requestType);
9065                mPendingAssistExtras.add(pae);
9066                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9067            } catch (RemoteException e) {
9068                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9069                return extras;
9070            }
9071        }
9072        synchronized (pae) {
9073            while (!pae.haveResult) {
9074                try {
9075                    pae.wait();
9076                } catch (InterruptedException e) {
9077                }
9078            }
9079            if (pae.result != null) {
9080                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9081            }
9082        }
9083        synchronized (this) {
9084            mPendingAssistExtras.remove(pae);
9085            mHandler.removeCallbacks(pae);
9086        }
9087        return extras;
9088    }
9089
9090    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9091        PendingAssistExtras pae = (PendingAssistExtras)token;
9092        synchronized (pae) {
9093            pae.result = extras;
9094            pae.haveResult = true;
9095            pae.notifyAll();
9096        }
9097    }
9098
9099    public void registerProcessObserver(IProcessObserver observer) {
9100        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9101                "registerProcessObserver()");
9102        synchronized (this) {
9103            mProcessObservers.register(observer);
9104        }
9105    }
9106
9107    @Override
9108    public void unregisterProcessObserver(IProcessObserver observer) {
9109        synchronized (this) {
9110            mProcessObservers.unregister(observer);
9111        }
9112    }
9113
9114    @Override
9115    public boolean convertFromTranslucent(IBinder token) {
9116        final long origId = Binder.clearCallingIdentity();
9117        try {
9118            synchronized (this) {
9119                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9120                if (r == null) {
9121                    return false;
9122                }
9123                if (r.changeWindowTranslucency(true)) {
9124                    mWindowManager.setAppFullscreen(token, true);
9125                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9126                    return true;
9127                }
9128                return false;
9129            }
9130        } finally {
9131            Binder.restoreCallingIdentity(origId);
9132        }
9133    }
9134
9135    @Override
9136    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9137        final long origId = Binder.clearCallingIdentity();
9138        try {
9139            synchronized (this) {
9140                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9141                if (r == null) {
9142                    return false;
9143                }
9144                if (r.changeWindowTranslucency(false)) {
9145                    r.task.stack.convertToTranslucent(r, options);
9146                    mWindowManager.setAppFullscreen(token, false);
9147                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9148                    return true;
9149                }
9150                return false;
9151            }
9152        } finally {
9153            Binder.restoreCallingIdentity(origId);
9154        }
9155    }
9156
9157    @Override
9158    public ActivityOptions getActivityOptions(IBinder token) {
9159        final long origId = Binder.clearCallingIdentity();
9160        try {
9161            synchronized (this) {
9162                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9163                if (r != null) {
9164                    final ActivityOptions activityOptions = r.pendingOptions;
9165                    r.pendingOptions = null;
9166                    return activityOptions;
9167                }
9168                return null;
9169            }
9170        } finally {
9171            Binder.restoreCallingIdentity(origId);
9172        }
9173    }
9174
9175    @Override
9176    public void setImmersive(IBinder token, boolean immersive) {
9177        synchronized(this) {
9178            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9179            if (r == null) {
9180                throw new IllegalArgumentException();
9181            }
9182            r.immersive = immersive;
9183
9184            // update associated state if we're frontmost
9185            if (r == mFocusedActivity) {
9186                if (DEBUG_IMMERSIVE) {
9187                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9188                }
9189                applyUpdateLockStateLocked(r);
9190            }
9191        }
9192    }
9193
9194    @Override
9195    public boolean isImmersive(IBinder token) {
9196        synchronized (this) {
9197            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9198            if (r == null) {
9199                throw new IllegalArgumentException();
9200            }
9201            return r.immersive;
9202        }
9203    }
9204
9205    public boolean isTopActivityImmersive() {
9206        enforceNotIsolatedCaller("startActivity");
9207        synchronized (this) {
9208            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9209            return (r != null) ? r.immersive : false;
9210        }
9211    }
9212
9213    public final void enterSafeMode() {
9214        synchronized(this) {
9215            // It only makes sense to do this before the system is ready
9216            // and started launching other packages.
9217            if (!mSystemReady) {
9218                try {
9219                    AppGlobals.getPackageManager().enterSafeMode();
9220                } catch (RemoteException e) {
9221                }
9222            }
9223
9224            mSafeMode = true;
9225        }
9226    }
9227
9228    public final void showSafeModeOverlay() {
9229        View v = LayoutInflater.from(mContext).inflate(
9230                com.android.internal.R.layout.safe_mode, null);
9231        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9232        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9233        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9234        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9235        lp.gravity = Gravity.BOTTOM | Gravity.START;
9236        lp.format = v.getBackground().getOpacity();
9237        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9238                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9239        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9240        ((WindowManager)mContext.getSystemService(
9241                Context.WINDOW_SERVICE)).addView(v, lp);
9242    }
9243
9244    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9245        if (!(sender instanceof PendingIntentRecord)) {
9246            return;
9247        }
9248        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9249        synchronized (stats) {
9250            if (mBatteryStatsService.isOnBattery()) {
9251                mBatteryStatsService.enforceCallingPermission();
9252                PendingIntentRecord rec = (PendingIntentRecord)sender;
9253                int MY_UID = Binder.getCallingUid();
9254                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9255                BatteryStatsImpl.Uid.Pkg pkg =
9256                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9257                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9258                pkg.incWakeupsLocked();
9259            }
9260        }
9261    }
9262
9263    public boolean killPids(int[] pids, String pReason, boolean secure) {
9264        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9265            throw new SecurityException("killPids only available to the system");
9266        }
9267        String reason = (pReason == null) ? "Unknown" : pReason;
9268        // XXX Note: don't acquire main activity lock here, because the window
9269        // manager calls in with its locks held.
9270
9271        boolean killed = false;
9272        synchronized (mPidsSelfLocked) {
9273            int[] types = new int[pids.length];
9274            int worstType = 0;
9275            for (int i=0; i<pids.length; i++) {
9276                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9277                if (proc != null) {
9278                    int type = proc.setAdj;
9279                    types[i] = type;
9280                    if (type > worstType) {
9281                        worstType = type;
9282                    }
9283                }
9284            }
9285
9286            // If the worst oom_adj is somewhere in the cached proc LRU range,
9287            // then constrain it so we will kill all cached procs.
9288            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9289                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9290                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9291            }
9292
9293            // If this is not a secure call, don't let it kill processes that
9294            // are important.
9295            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9296                worstType = ProcessList.SERVICE_ADJ;
9297            }
9298
9299            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9300            for (int i=0; i<pids.length; i++) {
9301                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9302                if (proc == null) {
9303                    continue;
9304                }
9305                int adj = proc.setAdj;
9306                if (adj >= worstType && !proc.killedByAm) {
9307                    killUnneededProcessLocked(proc, reason);
9308                    killed = true;
9309                }
9310            }
9311        }
9312        return killed;
9313    }
9314
9315    @Override
9316    public void killUid(int uid, String reason) {
9317        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9318            throw new SecurityException("killUid only available to the system");
9319        }
9320        synchronized (this) {
9321            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9322                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9323                    reason != null ? reason : "kill uid");
9324        }
9325    }
9326
9327    @Override
9328    public boolean killProcessesBelowForeground(String reason) {
9329        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9330            throw new SecurityException("killProcessesBelowForeground() only available to system");
9331        }
9332
9333        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9334    }
9335
9336    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9337        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9338            throw new SecurityException("killProcessesBelowAdj() only available to system");
9339        }
9340
9341        boolean killed = false;
9342        synchronized (mPidsSelfLocked) {
9343            final int size = mPidsSelfLocked.size();
9344            for (int i = 0; i < size; i++) {
9345                final int pid = mPidsSelfLocked.keyAt(i);
9346                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9347                if (proc == null) continue;
9348
9349                final int adj = proc.setAdj;
9350                if (adj > belowAdj && !proc.killedByAm) {
9351                    killUnneededProcessLocked(proc, reason);
9352                    killed = true;
9353                }
9354            }
9355        }
9356        return killed;
9357    }
9358
9359    @Override
9360    public void hang(final IBinder who, boolean allowRestart) {
9361        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9362                != PackageManager.PERMISSION_GRANTED) {
9363            throw new SecurityException("Requires permission "
9364                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9365        }
9366
9367        final IBinder.DeathRecipient death = new DeathRecipient() {
9368            @Override
9369            public void binderDied() {
9370                synchronized (this) {
9371                    notifyAll();
9372                }
9373            }
9374        };
9375
9376        try {
9377            who.linkToDeath(death, 0);
9378        } catch (RemoteException e) {
9379            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9380            return;
9381        }
9382
9383        synchronized (this) {
9384            Watchdog.getInstance().setAllowRestart(allowRestart);
9385            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9386            synchronized (death) {
9387                while (who.isBinderAlive()) {
9388                    try {
9389                        death.wait();
9390                    } catch (InterruptedException e) {
9391                    }
9392                }
9393            }
9394            Watchdog.getInstance().setAllowRestart(true);
9395        }
9396    }
9397
9398    @Override
9399    public void restart() {
9400        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9401                != PackageManager.PERMISSION_GRANTED) {
9402            throw new SecurityException("Requires permission "
9403                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9404        }
9405
9406        Log.i(TAG, "Sending shutdown broadcast...");
9407
9408        BroadcastReceiver br = new BroadcastReceiver() {
9409            @Override public void onReceive(Context context, Intent intent) {
9410                // Now the broadcast is done, finish up the low-level shutdown.
9411                Log.i(TAG, "Shutting down activity manager...");
9412                shutdown(10000);
9413                Log.i(TAG, "Shutdown complete, restarting!");
9414                Process.killProcess(Process.myPid());
9415                System.exit(10);
9416            }
9417        };
9418
9419        // First send the high-level shut down broadcast.
9420        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9421        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9422        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9423        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9424        mContext.sendOrderedBroadcastAsUser(intent,
9425                UserHandle.ALL, null, br, mHandler, 0, null, null);
9426        */
9427        br.onReceive(mContext, intent);
9428    }
9429
9430    private long getLowRamTimeSinceIdle(long now) {
9431        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9432    }
9433
9434    @Override
9435    public void performIdleMaintenance() {
9436        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9437                != PackageManager.PERMISSION_GRANTED) {
9438            throw new SecurityException("Requires permission "
9439                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9440        }
9441
9442        synchronized (this) {
9443            final long now = SystemClock.uptimeMillis();
9444            final long timeSinceLastIdle = now - mLastIdleTime;
9445            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9446            mLastIdleTime = now;
9447            mLowRamTimeSinceLastIdle = 0;
9448            if (mLowRamStartTime != 0) {
9449                mLowRamStartTime = now;
9450            }
9451
9452            StringBuilder sb = new StringBuilder(128);
9453            sb.append("Idle maintenance over ");
9454            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9455            sb.append(" low RAM for ");
9456            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9457            Slog.i(TAG, sb.toString());
9458
9459            // If at least 1/3 of our time since the last idle period has been spent
9460            // with RAM low, then we want to kill processes.
9461            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9462
9463            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9464                ProcessRecord proc = mLruProcesses.get(i);
9465                if (proc.notCachedSinceIdle) {
9466                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9467                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9468                        if (doKilling && proc.initialIdlePss != 0
9469                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9470                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9471                                    + " from " + proc.initialIdlePss + ")");
9472                        }
9473                    }
9474                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9475                    proc.notCachedSinceIdle = true;
9476                    proc.initialIdlePss = 0;
9477                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9478                            isSleeping(), now);
9479                }
9480            }
9481
9482            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9483            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9484        }
9485    }
9486
9487    private void retrieveSettings() {
9488        final ContentResolver resolver = mContext.getContentResolver();
9489        String debugApp = Settings.Global.getString(
9490            resolver, Settings.Global.DEBUG_APP);
9491        boolean waitForDebugger = Settings.Global.getInt(
9492            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9493        boolean alwaysFinishActivities = Settings.Global.getInt(
9494            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9495        boolean forceRtl = Settings.Global.getInt(
9496                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9497        // Transfer any global setting for forcing RTL layout, into a System Property
9498        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9499
9500        Configuration configuration = new Configuration();
9501        Settings.System.getConfiguration(resolver, configuration);
9502        if (forceRtl) {
9503            // This will take care of setting the correct layout direction flags
9504            configuration.setLayoutDirection(configuration.locale);
9505        }
9506
9507        synchronized (this) {
9508            mDebugApp = mOrigDebugApp = debugApp;
9509            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9510            mAlwaysFinishActivities = alwaysFinishActivities;
9511            // This happens before any activities are started, so we can
9512            // change mConfiguration in-place.
9513            updateConfigurationLocked(configuration, null, false, true);
9514            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9515        }
9516    }
9517
9518    public boolean testIsSystemReady() {
9519        // no need to synchronize(this) just to read & return the value
9520        return mSystemReady;
9521    }
9522
9523    private static File getCalledPreBootReceiversFile() {
9524        File dataDir = Environment.getDataDirectory();
9525        File systemDir = new File(dataDir, "system");
9526        File fname = new File(systemDir, "called_pre_boots.dat");
9527        return fname;
9528    }
9529
9530    static final int LAST_DONE_VERSION = 10000;
9531
9532    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9533        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9534        File file = getCalledPreBootReceiversFile();
9535        FileInputStream fis = null;
9536        try {
9537            fis = new FileInputStream(file);
9538            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9539            int fvers = dis.readInt();
9540            if (fvers == LAST_DONE_VERSION) {
9541                String vers = dis.readUTF();
9542                String codename = dis.readUTF();
9543                String build = dis.readUTF();
9544                if (android.os.Build.VERSION.RELEASE.equals(vers)
9545                        && android.os.Build.VERSION.CODENAME.equals(codename)
9546                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9547                    int num = dis.readInt();
9548                    while (num > 0) {
9549                        num--;
9550                        String pkg = dis.readUTF();
9551                        String cls = dis.readUTF();
9552                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9553                    }
9554                }
9555            }
9556        } catch (FileNotFoundException e) {
9557        } catch (IOException e) {
9558            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9559        } finally {
9560            if (fis != null) {
9561                try {
9562                    fis.close();
9563                } catch (IOException e) {
9564                }
9565            }
9566        }
9567        return lastDoneReceivers;
9568    }
9569
9570    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9571        File file = getCalledPreBootReceiversFile();
9572        FileOutputStream fos = null;
9573        DataOutputStream dos = null;
9574        try {
9575            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9576            fos = new FileOutputStream(file);
9577            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9578            dos.writeInt(LAST_DONE_VERSION);
9579            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9580            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9581            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9582            dos.writeInt(list.size());
9583            for (int i=0; i<list.size(); i++) {
9584                dos.writeUTF(list.get(i).getPackageName());
9585                dos.writeUTF(list.get(i).getClassName());
9586            }
9587        } catch (IOException e) {
9588            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9589            file.delete();
9590        } finally {
9591            FileUtils.sync(fos);
9592            if (dos != null) {
9593                try {
9594                    dos.close();
9595                } catch (IOException e) {
9596                    // TODO Auto-generated catch block
9597                    e.printStackTrace();
9598                }
9599            }
9600        }
9601    }
9602
9603    public void systemReady(final Runnable goingCallback) {
9604        synchronized(this) {
9605            if (mSystemReady) {
9606                if (goingCallback != null) goingCallback.run();
9607                return;
9608            }
9609
9610            if (mRecentTasks == null) {
9611                mRecentTasks = mTaskPersister.restoreTasksLocked();
9612                if (!mRecentTasks.isEmpty()) {
9613                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9614                }
9615                mTaskPersister.startPersisting();
9616            }
9617
9618            // Check to see if there are any update receivers to run.
9619            if (!mDidUpdate) {
9620                if (mWaitingUpdate) {
9621                    return;
9622                }
9623                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9624                List<ResolveInfo> ris = null;
9625                try {
9626                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9627                            intent, null, 0, 0);
9628                } catch (RemoteException e) {
9629                }
9630                if (ris != null) {
9631                    for (int i=ris.size()-1; i>=0; i--) {
9632                        if ((ris.get(i).activityInfo.applicationInfo.flags
9633                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9634                            ris.remove(i);
9635                        }
9636                    }
9637                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9638
9639                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9640
9641                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9642                    for (int i=0; i<ris.size(); i++) {
9643                        ActivityInfo ai = ris.get(i).activityInfo;
9644                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9645                        if (lastDoneReceivers.contains(comp)) {
9646                            // We already did the pre boot receiver for this app with the current
9647                            // platform version, so don't do it again...
9648                            ris.remove(i);
9649                            i--;
9650                            // ...however, do keep it as one that has been done, so we don't
9651                            // forget about it when rewriting the file of last done receivers.
9652                            doneReceivers.add(comp);
9653                        }
9654                    }
9655
9656                    final int[] users = getUsersLocked();
9657                    for (int i=0; i<ris.size(); i++) {
9658                        ActivityInfo ai = ris.get(i).activityInfo;
9659                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9660                        doneReceivers.add(comp);
9661                        intent.setComponent(comp);
9662                        for (int j=0; j<users.length; j++) {
9663                            IIntentReceiver finisher = null;
9664                            if (i == ris.size()-1 && j == users.length-1) {
9665                                finisher = new IIntentReceiver.Stub() {
9666                                    public void performReceive(Intent intent, int resultCode,
9667                                            String data, Bundle extras, boolean ordered,
9668                                            boolean sticky, int sendingUser) {
9669                                        // The raw IIntentReceiver interface is called
9670                                        // with the AM lock held, so redispatch to
9671                                        // execute our code without the lock.
9672                                        mHandler.post(new Runnable() {
9673                                            public void run() {
9674                                                synchronized (ActivityManagerService.this) {
9675                                                    mDidUpdate = true;
9676                                                }
9677                                                writeLastDonePreBootReceivers(doneReceivers);
9678                                                showBootMessage(mContext.getText(
9679                                                        R.string.android_upgrading_complete),
9680                                                        false);
9681                                                systemReady(goingCallback);
9682                                            }
9683                                        });
9684                                    }
9685                                };
9686                            }
9687                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9688                                    + " for user " + users[j]);
9689                            broadcastIntentLocked(null, null, intent, null, finisher,
9690                                    0, null, null, null, AppOpsManager.OP_NONE,
9691                                    true, false, MY_PID, Process.SYSTEM_UID,
9692                                    users[j]);
9693                            if (finisher != null) {
9694                                mWaitingUpdate = true;
9695                            }
9696                        }
9697                    }
9698                }
9699                if (mWaitingUpdate) {
9700                    return;
9701                }
9702                mDidUpdate = true;
9703            }
9704
9705            mAppOpsService.systemReady();
9706            mUsageStatsService.systemReady();
9707            mSystemReady = true;
9708        }
9709
9710        ArrayList<ProcessRecord> procsToKill = null;
9711        synchronized(mPidsSelfLocked) {
9712            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9713                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9714                if (!isAllowedWhileBooting(proc.info)){
9715                    if (procsToKill == null) {
9716                        procsToKill = new ArrayList<ProcessRecord>();
9717                    }
9718                    procsToKill.add(proc);
9719                }
9720            }
9721        }
9722
9723        synchronized(this) {
9724            if (procsToKill != null) {
9725                for (int i=procsToKill.size()-1; i>=0; i--) {
9726                    ProcessRecord proc = procsToKill.get(i);
9727                    Slog.i(TAG, "Removing system update proc: " + proc);
9728                    removeProcessLocked(proc, true, false, "system update done");
9729                }
9730            }
9731
9732            // Now that we have cleaned up any update processes, we
9733            // are ready to start launching real processes and know that
9734            // we won't trample on them any more.
9735            mProcessesReady = true;
9736        }
9737
9738        Slog.i(TAG, "System now ready");
9739        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9740            SystemClock.uptimeMillis());
9741
9742        synchronized(this) {
9743            // Make sure we have no pre-ready processes sitting around.
9744
9745            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9746                ResolveInfo ri = mContext.getPackageManager()
9747                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9748                                STOCK_PM_FLAGS);
9749                CharSequence errorMsg = null;
9750                if (ri != null) {
9751                    ActivityInfo ai = ri.activityInfo;
9752                    ApplicationInfo app = ai.applicationInfo;
9753                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9754                        mTopAction = Intent.ACTION_FACTORY_TEST;
9755                        mTopData = null;
9756                        mTopComponent = new ComponentName(app.packageName,
9757                                ai.name);
9758                    } else {
9759                        errorMsg = mContext.getResources().getText(
9760                                com.android.internal.R.string.factorytest_not_system);
9761                    }
9762                } else {
9763                    errorMsg = mContext.getResources().getText(
9764                            com.android.internal.R.string.factorytest_no_action);
9765                }
9766                if (errorMsg != null) {
9767                    mTopAction = null;
9768                    mTopData = null;
9769                    mTopComponent = null;
9770                    Message msg = Message.obtain();
9771                    msg.what = SHOW_FACTORY_ERROR_MSG;
9772                    msg.getData().putCharSequence("msg", errorMsg);
9773                    mHandler.sendMessage(msg);
9774                }
9775            }
9776        }
9777
9778        retrieveSettings();
9779
9780        synchronized (this) {
9781            readGrantedUriPermissionsLocked();
9782        }
9783
9784        if (goingCallback != null) goingCallback.run();
9785
9786        mSystemServiceManager.startUser(mCurrentUserId);
9787
9788        synchronized (this) {
9789            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9790                try {
9791                    List apps = AppGlobals.getPackageManager().
9792                        getPersistentApplications(STOCK_PM_FLAGS);
9793                    if (apps != null) {
9794                        int N = apps.size();
9795                        int i;
9796                        for (i=0; i<N; i++) {
9797                            ApplicationInfo info
9798                                = (ApplicationInfo)apps.get(i);
9799                            if (info != null &&
9800                                    !info.packageName.equals("android")) {
9801                                addAppLocked(info, false);
9802                            }
9803                        }
9804                    }
9805                } catch (RemoteException ex) {
9806                    // pm is in same process, this will never happen.
9807                }
9808            }
9809
9810            // Start up initial activity.
9811            mBooting = true;
9812
9813            try {
9814                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9815                    Message msg = Message.obtain();
9816                    msg.what = SHOW_UID_ERROR_MSG;
9817                    mHandler.sendMessage(msg);
9818                }
9819            } catch (RemoteException e) {
9820            }
9821
9822            long ident = Binder.clearCallingIdentity();
9823            try {
9824                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9825                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9826                        | Intent.FLAG_RECEIVER_FOREGROUND);
9827                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9828                broadcastIntentLocked(null, null, intent,
9829                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9830                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9831                intent = new Intent(Intent.ACTION_USER_STARTING);
9832                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9833                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9834                broadcastIntentLocked(null, null, intent,
9835                        null, new IIntentReceiver.Stub() {
9836                            @Override
9837                            public void performReceive(Intent intent, int resultCode, String data,
9838                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9839                                    throws RemoteException {
9840                            }
9841                        }, 0, null, null,
9842                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9843                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9844            } catch (Throwable t) {
9845                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9846            } finally {
9847                Binder.restoreCallingIdentity(ident);
9848            }
9849            mStackSupervisor.resumeTopActivitiesLocked();
9850            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9851        }
9852    }
9853
9854    private boolean makeAppCrashingLocked(ProcessRecord app,
9855            String shortMsg, String longMsg, String stackTrace) {
9856        app.crashing = true;
9857        app.crashingReport = generateProcessError(app,
9858                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9859        startAppProblemLocked(app);
9860        app.stopFreezingAllLocked();
9861        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9862    }
9863
9864    private void makeAppNotRespondingLocked(ProcessRecord app,
9865            String activity, String shortMsg, String longMsg) {
9866        app.notResponding = true;
9867        app.notRespondingReport = generateProcessError(app,
9868                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9869                activity, shortMsg, longMsg, null);
9870        startAppProblemLocked(app);
9871        app.stopFreezingAllLocked();
9872    }
9873
9874    /**
9875     * Generate a process error record, suitable for attachment to a ProcessRecord.
9876     *
9877     * @param app The ProcessRecord in which the error occurred.
9878     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9879     *                      ActivityManager.AppErrorStateInfo
9880     * @param activity The activity associated with the crash, if known.
9881     * @param shortMsg Short message describing the crash.
9882     * @param longMsg Long message describing the crash.
9883     * @param stackTrace Full crash stack trace, may be null.
9884     *
9885     * @return Returns a fully-formed AppErrorStateInfo record.
9886     */
9887    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9888            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9889        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9890
9891        report.condition = condition;
9892        report.processName = app.processName;
9893        report.pid = app.pid;
9894        report.uid = app.info.uid;
9895        report.tag = activity;
9896        report.shortMsg = shortMsg;
9897        report.longMsg = longMsg;
9898        report.stackTrace = stackTrace;
9899
9900        return report;
9901    }
9902
9903    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9904        synchronized (this) {
9905            app.crashing = false;
9906            app.crashingReport = null;
9907            app.notResponding = false;
9908            app.notRespondingReport = null;
9909            if (app.anrDialog == fromDialog) {
9910                app.anrDialog = null;
9911            }
9912            if (app.waitDialog == fromDialog) {
9913                app.waitDialog = null;
9914            }
9915            if (app.pid > 0 && app.pid != MY_PID) {
9916                handleAppCrashLocked(app, null, null, null);
9917                killUnneededProcessLocked(app, "user request after error");
9918            }
9919        }
9920    }
9921
9922    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9923            String stackTrace) {
9924        long now = SystemClock.uptimeMillis();
9925
9926        Long crashTime;
9927        if (!app.isolated) {
9928            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9929        } else {
9930            crashTime = null;
9931        }
9932        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9933            // This process loses!
9934            Slog.w(TAG, "Process " + app.info.processName
9935                    + " has crashed too many times: killing!");
9936            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9937                    app.userId, app.info.processName, app.uid);
9938            mStackSupervisor.handleAppCrashLocked(app);
9939            if (!app.persistent) {
9940                // We don't want to start this process again until the user
9941                // explicitly does so...  but for persistent process, we really
9942                // need to keep it running.  If a persistent process is actually
9943                // repeatedly crashing, then badness for everyone.
9944                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9945                        app.info.processName);
9946                if (!app.isolated) {
9947                    // XXX We don't have a way to mark isolated processes
9948                    // as bad, since they don't have a peristent identity.
9949                    mBadProcesses.put(app.info.processName, app.uid,
9950                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9951                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9952                }
9953                app.bad = true;
9954                app.removed = true;
9955                // Don't let services in this process be restarted and potentially
9956                // annoy the user repeatedly.  Unless it is persistent, since those
9957                // processes run critical code.
9958                removeProcessLocked(app, false, false, "crash");
9959                mStackSupervisor.resumeTopActivitiesLocked();
9960                return false;
9961            }
9962            mStackSupervisor.resumeTopActivitiesLocked();
9963        } else {
9964            mStackSupervisor.finishTopRunningActivityLocked(app);
9965        }
9966
9967        // Bump up the crash count of any services currently running in the proc.
9968        for (int i=app.services.size()-1; i>=0; i--) {
9969            // Any services running in the application need to be placed
9970            // back in the pending list.
9971            ServiceRecord sr = app.services.valueAt(i);
9972            sr.crashCount++;
9973        }
9974
9975        // If the crashing process is what we consider to be the "home process" and it has been
9976        // replaced by a third-party app, clear the package preferred activities from packages
9977        // with a home activity running in the process to prevent a repeatedly crashing app
9978        // from blocking the user to manually clear the list.
9979        final ArrayList<ActivityRecord> activities = app.activities;
9980        if (app == mHomeProcess && activities.size() > 0
9981                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9982            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9983                final ActivityRecord r = activities.get(activityNdx);
9984                if (r.isHomeActivity()) {
9985                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9986                    try {
9987                        ActivityThread.getPackageManager()
9988                                .clearPackagePreferredActivities(r.packageName);
9989                    } catch (RemoteException c) {
9990                        // pm is in same process, this will never happen.
9991                    }
9992                }
9993            }
9994        }
9995
9996        if (!app.isolated) {
9997            // XXX Can't keep track of crash times for isolated processes,
9998            // because they don't have a perisistent identity.
9999            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10000        }
10001
10002        return true;
10003    }
10004
10005    void startAppProblemLocked(ProcessRecord app) {
10006        if (app.userId == mCurrentUserId) {
10007            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10008                    mContext, app.info.packageName, app.info.flags);
10009        } else {
10010            // If this app is not running under the current user, then we
10011            // can't give it a report button because that would require
10012            // launching the report UI under a different user.
10013            app.errorReportReceiver = null;
10014        }
10015        skipCurrentReceiverLocked(app);
10016    }
10017
10018    void skipCurrentReceiverLocked(ProcessRecord app) {
10019        for (BroadcastQueue queue : mBroadcastQueues) {
10020            queue.skipCurrentReceiverLocked(app);
10021        }
10022    }
10023
10024    /**
10025     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10026     * The application process will exit immediately after this call returns.
10027     * @param app object of the crashing app, null for the system server
10028     * @param crashInfo describing the exception
10029     */
10030    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10031        ProcessRecord r = findAppProcess(app, "Crash");
10032        final String processName = app == null ? "system_server"
10033                : (r == null ? "unknown" : r.processName);
10034
10035        handleApplicationCrashInner("crash", r, processName, crashInfo);
10036    }
10037
10038    /* Native crash reporting uses this inner version because it needs to be somewhat
10039     * decoupled from the AM-managed cleanup lifecycle
10040     */
10041    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10042            ApplicationErrorReport.CrashInfo crashInfo) {
10043        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10044                UserHandle.getUserId(Binder.getCallingUid()), processName,
10045                r == null ? -1 : r.info.flags,
10046                crashInfo.exceptionClassName,
10047                crashInfo.exceptionMessage,
10048                crashInfo.throwFileName,
10049                crashInfo.throwLineNumber);
10050
10051        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10052
10053        crashApplication(r, crashInfo);
10054    }
10055
10056    public void handleApplicationStrictModeViolation(
10057            IBinder app,
10058            int violationMask,
10059            StrictMode.ViolationInfo info) {
10060        ProcessRecord r = findAppProcess(app, "StrictMode");
10061        if (r == null) {
10062            return;
10063        }
10064
10065        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10066            Integer stackFingerprint = info.hashCode();
10067            boolean logIt = true;
10068            synchronized (mAlreadyLoggedViolatedStacks) {
10069                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10070                    logIt = false;
10071                    // TODO: sub-sample into EventLog for these, with
10072                    // the info.durationMillis?  Then we'd get
10073                    // the relative pain numbers, without logging all
10074                    // the stack traces repeatedly.  We'd want to do
10075                    // likewise in the client code, which also does
10076                    // dup suppression, before the Binder call.
10077                } else {
10078                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10079                        mAlreadyLoggedViolatedStacks.clear();
10080                    }
10081                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10082                }
10083            }
10084            if (logIt) {
10085                logStrictModeViolationToDropBox(r, info);
10086            }
10087        }
10088
10089        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10090            AppErrorResult result = new AppErrorResult();
10091            synchronized (this) {
10092                final long origId = Binder.clearCallingIdentity();
10093
10094                Message msg = Message.obtain();
10095                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10096                HashMap<String, Object> data = new HashMap<String, Object>();
10097                data.put("result", result);
10098                data.put("app", r);
10099                data.put("violationMask", violationMask);
10100                data.put("info", info);
10101                msg.obj = data;
10102                mHandler.sendMessage(msg);
10103
10104                Binder.restoreCallingIdentity(origId);
10105            }
10106            int res = result.get();
10107            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10108        }
10109    }
10110
10111    // Depending on the policy in effect, there could be a bunch of
10112    // these in quick succession so we try to batch these together to
10113    // minimize disk writes, number of dropbox entries, and maximize
10114    // compression, by having more fewer, larger records.
10115    private void logStrictModeViolationToDropBox(
10116            ProcessRecord process,
10117            StrictMode.ViolationInfo info) {
10118        if (info == null) {
10119            return;
10120        }
10121        final boolean isSystemApp = process == null ||
10122                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10123                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10124        final String processName = process == null ? "unknown" : process.processName;
10125        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10126        final DropBoxManager dbox = (DropBoxManager)
10127                mContext.getSystemService(Context.DROPBOX_SERVICE);
10128
10129        // Exit early if the dropbox isn't configured to accept this report type.
10130        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10131
10132        boolean bufferWasEmpty;
10133        boolean needsFlush;
10134        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10135        synchronized (sb) {
10136            bufferWasEmpty = sb.length() == 0;
10137            appendDropBoxProcessHeaders(process, processName, sb);
10138            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10139            sb.append("System-App: ").append(isSystemApp).append("\n");
10140            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10141            if (info.violationNumThisLoop != 0) {
10142                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10143            }
10144            if (info.numAnimationsRunning != 0) {
10145                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10146            }
10147            if (info.broadcastIntentAction != null) {
10148                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10149            }
10150            if (info.durationMillis != -1) {
10151                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10152            }
10153            if (info.numInstances != -1) {
10154                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10155            }
10156            if (info.tags != null) {
10157                for (String tag : info.tags) {
10158                    sb.append("Span-Tag: ").append(tag).append("\n");
10159                }
10160            }
10161            sb.append("\n");
10162            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10163                sb.append(info.crashInfo.stackTrace);
10164            }
10165            sb.append("\n");
10166
10167            // Only buffer up to ~64k.  Various logging bits truncate
10168            // things at 128k.
10169            needsFlush = (sb.length() > 64 * 1024);
10170        }
10171
10172        // Flush immediately if the buffer's grown too large, or this
10173        // is a non-system app.  Non-system apps are isolated with a
10174        // different tag & policy and not batched.
10175        //
10176        // Batching is useful during internal testing with
10177        // StrictMode settings turned up high.  Without batching,
10178        // thousands of separate files could be created on boot.
10179        if (!isSystemApp || needsFlush) {
10180            new Thread("Error dump: " + dropboxTag) {
10181                @Override
10182                public void run() {
10183                    String report;
10184                    synchronized (sb) {
10185                        report = sb.toString();
10186                        sb.delete(0, sb.length());
10187                        sb.trimToSize();
10188                    }
10189                    if (report.length() != 0) {
10190                        dbox.addText(dropboxTag, report);
10191                    }
10192                }
10193            }.start();
10194            return;
10195        }
10196
10197        // System app batching:
10198        if (!bufferWasEmpty) {
10199            // An existing dropbox-writing thread is outstanding, so
10200            // we don't need to start it up.  The existing thread will
10201            // catch the buffer appends we just did.
10202            return;
10203        }
10204
10205        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10206        // (After this point, we shouldn't access AMS internal data structures.)
10207        new Thread("Error dump: " + dropboxTag) {
10208            @Override
10209            public void run() {
10210                // 5 second sleep to let stacks arrive and be batched together
10211                try {
10212                    Thread.sleep(5000);  // 5 seconds
10213                } catch (InterruptedException e) {}
10214
10215                String errorReport;
10216                synchronized (mStrictModeBuffer) {
10217                    errorReport = mStrictModeBuffer.toString();
10218                    if (errorReport.length() == 0) {
10219                        return;
10220                    }
10221                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10222                    mStrictModeBuffer.trimToSize();
10223                }
10224                dbox.addText(dropboxTag, errorReport);
10225            }
10226        }.start();
10227    }
10228
10229    /**
10230     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10231     * @param app object of the crashing app, null for the system server
10232     * @param tag reported by the caller
10233     * @param crashInfo describing the context of the error
10234     * @return true if the process should exit immediately (WTF is fatal)
10235     */
10236    public boolean handleApplicationWtf(IBinder app, String tag,
10237            ApplicationErrorReport.CrashInfo crashInfo) {
10238        ProcessRecord r = findAppProcess(app, "WTF");
10239        final String processName = app == null ? "system_server"
10240                : (r == null ? "unknown" : r.processName);
10241
10242        EventLog.writeEvent(EventLogTags.AM_WTF,
10243                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10244                processName,
10245                r == null ? -1 : r.info.flags,
10246                tag, crashInfo.exceptionMessage);
10247
10248        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10249
10250        if (r != null && r.pid != Process.myPid() &&
10251                Settings.Global.getInt(mContext.getContentResolver(),
10252                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10253            crashApplication(r, crashInfo);
10254            return true;
10255        } else {
10256            return false;
10257        }
10258    }
10259
10260    /**
10261     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10262     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10263     */
10264    private ProcessRecord findAppProcess(IBinder app, String reason) {
10265        if (app == null) {
10266            return null;
10267        }
10268
10269        synchronized (this) {
10270            final int NP = mProcessNames.getMap().size();
10271            for (int ip=0; ip<NP; ip++) {
10272                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10273                final int NA = apps.size();
10274                for (int ia=0; ia<NA; ia++) {
10275                    ProcessRecord p = apps.valueAt(ia);
10276                    if (p.thread != null && p.thread.asBinder() == app) {
10277                        return p;
10278                    }
10279                }
10280            }
10281
10282            Slog.w(TAG, "Can't find mystery application for " + reason
10283                    + " from pid=" + Binder.getCallingPid()
10284                    + " uid=" + Binder.getCallingUid() + ": " + app);
10285            return null;
10286        }
10287    }
10288
10289    /**
10290     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10291     * to append various headers to the dropbox log text.
10292     */
10293    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10294            StringBuilder sb) {
10295        // Watchdog thread ends up invoking this function (with
10296        // a null ProcessRecord) to add the stack file to dropbox.
10297        // Do not acquire a lock on this (am) in such cases, as it
10298        // could cause a potential deadlock, if and when watchdog
10299        // is invoked due to unavailability of lock on am and it
10300        // would prevent watchdog from killing system_server.
10301        if (process == null) {
10302            sb.append("Process: ").append(processName).append("\n");
10303            return;
10304        }
10305        // Note: ProcessRecord 'process' is guarded by the service
10306        // instance.  (notably process.pkgList, which could otherwise change
10307        // concurrently during execution of this method)
10308        synchronized (this) {
10309            sb.append("Process: ").append(processName).append("\n");
10310            int flags = process.info.flags;
10311            IPackageManager pm = AppGlobals.getPackageManager();
10312            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10313            for (int ip=0; ip<process.pkgList.size(); ip++) {
10314                String pkg = process.pkgList.keyAt(ip);
10315                sb.append("Package: ").append(pkg);
10316                try {
10317                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10318                    if (pi != null) {
10319                        sb.append(" v").append(pi.versionCode);
10320                        if (pi.versionName != null) {
10321                            sb.append(" (").append(pi.versionName).append(")");
10322                        }
10323                    }
10324                } catch (RemoteException e) {
10325                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10326                }
10327                sb.append("\n");
10328            }
10329        }
10330    }
10331
10332    private static String processClass(ProcessRecord process) {
10333        if (process == null || process.pid == MY_PID) {
10334            return "system_server";
10335        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10336            return "system_app";
10337        } else {
10338            return "data_app";
10339        }
10340    }
10341
10342    /**
10343     * Write a description of an error (crash, WTF, ANR) to the drop box.
10344     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10345     * @param process which caused the error, null means the system server
10346     * @param activity which triggered the error, null if unknown
10347     * @param parent activity related to the error, null if unknown
10348     * @param subject line related to the error, null if absent
10349     * @param report in long form describing the error, null if absent
10350     * @param logFile to include in the report, null if none
10351     * @param crashInfo giving an application stack trace, null if absent
10352     */
10353    public void addErrorToDropBox(String eventType,
10354            ProcessRecord process, String processName, ActivityRecord activity,
10355            ActivityRecord parent, String subject,
10356            final String report, final File logFile,
10357            final ApplicationErrorReport.CrashInfo crashInfo) {
10358        // NOTE -- this must never acquire the ActivityManagerService lock,
10359        // otherwise the watchdog may be prevented from resetting the system.
10360
10361        final String dropboxTag = processClass(process) + "_" + eventType;
10362        final DropBoxManager dbox = (DropBoxManager)
10363                mContext.getSystemService(Context.DROPBOX_SERVICE);
10364
10365        // Exit early if the dropbox isn't configured to accept this report type.
10366        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10367
10368        final StringBuilder sb = new StringBuilder(1024);
10369        appendDropBoxProcessHeaders(process, processName, sb);
10370        if (activity != null) {
10371            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10372        }
10373        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10374            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10375        }
10376        if (parent != null && parent != activity) {
10377            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10378        }
10379        if (subject != null) {
10380            sb.append("Subject: ").append(subject).append("\n");
10381        }
10382        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10383        if (Debug.isDebuggerConnected()) {
10384            sb.append("Debugger: Connected\n");
10385        }
10386        sb.append("\n");
10387
10388        // Do the rest in a worker thread to avoid blocking the caller on I/O
10389        // (After this point, we shouldn't access AMS internal data structures.)
10390        Thread worker = new Thread("Error dump: " + dropboxTag) {
10391            @Override
10392            public void run() {
10393                if (report != null) {
10394                    sb.append(report);
10395                }
10396                if (logFile != null) {
10397                    try {
10398                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10399                                    "\n\n[[TRUNCATED]]"));
10400                    } catch (IOException e) {
10401                        Slog.e(TAG, "Error reading " + logFile, e);
10402                    }
10403                }
10404                if (crashInfo != null && crashInfo.stackTrace != null) {
10405                    sb.append(crashInfo.stackTrace);
10406                }
10407
10408                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10409                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10410                if (lines > 0) {
10411                    sb.append("\n");
10412
10413                    // Merge several logcat streams, and take the last N lines
10414                    InputStreamReader input = null;
10415                    try {
10416                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10417                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10418                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10419
10420                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10421                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10422                        input = new InputStreamReader(logcat.getInputStream());
10423
10424                        int num;
10425                        char[] buf = new char[8192];
10426                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10427                    } catch (IOException e) {
10428                        Slog.e(TAG, "Error running logcat", e);
10429                    } finally {
10430                        if (input != null) try { input.close(); } catch (IOException e) {}
10431                    }
10432                }
10433
10434                dbox.addText(dropboxTag, sb.toString());
10435            }
10436        };
10437
10438        if (process == null) {
10439            // If process is null, we are being called from some internal code
10440            // and may be about to die -- run this synchronously.
10441            worker.run();
10442        } else {
10443            worker.start();
10444        }
10445    }
10446
10447    /**
10448     * Bring up the "unexpected error" dialog box for a crashing app.
10449     * Deal with edge cases (intercepts from instrumented applications,
10450     * ActivityController, error intent receivers, that sort of thing).
10451     * @param r the application crashing
10452     * @param crashInfo describing the failure
10453     */
10454    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10455        long timeMillis = System.currentTimeMillis();
10456        String shortMsg = crashInfo.exceptionClassName;
10457        String longMsg = crashInfo.exceptionMessage;
10458        String stackTrace = crashInfo.stackTrace;
10459        if (shortMsg != null && longMsg != null) {
10460            longMsg = shortMsg + ": " + longMsg;
10461        } else if (shortMsg != null) {
10462            longMsg = shortMsg;
10463        }
10464
10465        AppErrorResult result = new AppErrorResult();
10466        synchronized (this) {
10467            if (mController != null) {
10468                try {
10469                    String name = r != null ? r.processName : null;
10470                    int pid = r != null ? r.pid : Binder.getCallingPid();
10471                    if (!mController.appCrashed(name, pid,
10472                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10473                        Slog.w(TAG, "Force-killing crashed app " + name
10474                                + " at watcher's request");
10475                        Process.killProcess(pid);
10476                        return;
10477                    }
10478                } catch (RemoteException e) {
10479                    mController = null;
10480                    Watchdog.getInstance().setActivityController(null);
10481                }
10482            }
10483
10484            final long origId = Binder.clearCallingIdentity();
10485
10486            // If this process is running instrumentation, finish it.
10487            if (r != null && r.instrumentationClass != null) {
10488                Slog.w(TAG, "Error in app " + r.processName
10489                      + " running instrumentation " + r.instrumentationClass + ":");
10490                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10491                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10492                Bundle info = new Bundle();
10493                info.putString("shortMsg", shortMsg);
10494                info.putString("longMsg", longMsg);
10495                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10496                Binder.restoreCallingIdentity(origId);
10497                return;
10498            }
10499
10500            // If we can't identify the process or it's already exceeded its crash quota,
10501            // quit right away without showing a crash dialog.
10502            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10503                Binder.restoreCallingIdentity(origId);
10504                return;
10505            }
10506
10507            Message msg = Message.obtain();
10508            msg.what = SHOW_ERROR_MSG;
10509            HashMap data = new HashMap();
10510            data.put("result", result);
10511            data.put("app", r);
10512            msg.obj = data;
10513            mHandler.sendMessage(msg);
10514
10515            Binder.restoreCallingIdentity(origId);
10516        }
10517
10518        int res = result.get();
10519
10520        Intent appErrorIntent = null;
10521        synchronized (this) {
10522            if (r != null && !r.isolated) {
10523                // XXX Can't keep track of crash time for isolated processes,
10524                // since they don't have a persistent identity.
10525                mProcessCrashTimes.put(r.info.processName, r.uid,
10526                        SystemClock.uptimeMillis());
10527            }
10528            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10529                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10530            }
10531        }
10532
10533        if (appErrorIntent != null) {
10534            try {
10535                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10536            } catch (ActivityNotFoundException e) {
10537                Slog.w(TAG, "bug report receiver dissappeared", e);
10538            }
10539        }
10540    }
10541
10542    Intent createAppErrorIntentLocked(ProcessRecord r,
10543            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10544        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10545        if (report == null) {
10546            return null;
10547        }
10548        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10549        result.setComponent(r.errorReportReceiver);
10550        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10551        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10552        return result;
10553    }
10554
10555    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10556            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10557        if (r.errorReportReceiver == null) {
10558            return null;
10559        }
10560
10561        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10562            return null;
10563        }
10564
10565        ApplicationErrorReport report = new ApplicationErrorReport();
10566        report.packageName = r.info.packageName;
10567        report.installerPackageName = r.errorReportReceiver.getPackageName();
10568        report.processName = r.processName;
10569        report.time = timeMillis;
10570        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10571
10572        if (r.crashing || r.forceCrashReport) {
10573            report.type = ApplicationErrorReport.TYPE_CRASH;
10574            report.crashInfo = crashInfo;
10575        } else if (r.notResponding) {
10576            report.type = ApplicationErrorReport.TYPE_ANR;
10577            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10578
10579            report.anrInfo.activity = r.notRespondingReport.tag;
10580            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10581            report.anrInfo.info = r.notRespondingReport.longMsg;
10582        }
10583
10584        return report;
10585    }
10586
10587    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10588        enforceNotIsolatedCaller("getProcessesInErrorState");
10589        // assume our apps are happy - lazy create the list
10590        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10591
10592        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10593                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10594        int userId = UserHandle.getUserId(Binder.getCallingUid());
10595
10596        synchronized (this) {
10597
10598            // iterate across all processes
10599            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10600                ProcessRecord app = mLruProcesses.get(i);
10601                if (!allUsers && app.userId != userId) {
10602                    continue;
10603                }
10604                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10605                    // This one's in trouble, so we'll generate a report for it
10606                    // crashes are higher priority (in case there's a crash *and* an anr)
10607                    ActivityManager.ProcessErrorStateInfo report = null;
10608                    if (app.crashing) {
10609                        report = app.crashingReport;
10610                    } else if (app.notResponding) {
10611                        report = app.notRespondingReport;
10612                    }
10613
10614                    if (report != null) {
10615                        if (errList == null) {
10616                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10617                        }
10618                        errList.add(report);
10619                    } else {
10620                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10621                                " crashing = " + app.crashing +
10622                                " notResponding = " + app.notResponding);
10623                    }
10624                }
10625            }
10626        }
10627
10628        return errList;
10629    }
10630
10631    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10632        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10633            if (currApp != null) {
10634                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10635            }
10636            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10637        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10638            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10639        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10640            if (currApp != null) {
10641                currApp.lru = 0;
10642            }
10643            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10644        } else if (adj >= ProcessList.SERVICE_ADJ) {
10645            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10646        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10647            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10648        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10649            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10650        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10651            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10652        } else {
10653            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10654        }
10655    }
10656
10657    private void fillInProcMemInfo(ProcessRecord app,
10658            ActivityManager.RunningAppProcessInfo outInfo) {
10659        outInfo.pid = app.pid;
10660        outInfo.uid = app.info.uid;
10661        if (mHeavyWeightProcess == app) {
10662            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10663        }
10664        if (app.persistent) {
10665            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10666        }
10667        if (app.activities.size() > 0) {
10668            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10669        }
10670        outInfo.lastTrimLevel = app.trimMemoryLevel;
10671        int adj = app.curAdj;
10672        outInfo.importance = oomAdjToImportance(adj, outInfo);
10673        outInfo.importanceReasonCode = app.adjTypeCode;
10674        outInfo.processState = app.curProcState;
10675    }
10676
10677    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10678        enforceNotIsolatedCaller("getRunningAppProcesses");
10679        // Lazy instantiation of list
10680        List<ActivityManager.RunningAppProcessInfo> runList = null;
10681        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10682                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10683        int userId = UserHandle.getUserId(Binder.getCallingUid());
10684        synchronized (this) {
10685            // Iterate across all processes
10686            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10687                ProcessRecord app = mLruProcesses.get(i);
10688                if (!allUsers && app.userId != userId) {
10689                    continue;
10690                }
10691                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10692                    // Generate process state info for running application
10693                    ActivityManager.RunningAppProcessInfo currApp =
10694                        new ActivityManager.RunningAppProcessInfo(app.processName,
10695                                app.pid, app.getPackageList());
10696                    fillInProcMemInfo(app, currApp);
10697                    if (app.adjSource instanceof ProcessRecord) {
10698                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10699                        currApp.importanceReasonImportance = oomAdjToImportance(
10700                                app.adjSourceOom, null);
10701                    } else if (app.adjSource instanceof ActivityRecord) {
10702                        ActivityRecord r = (ActivityRecord)app.adjSource;
10703                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10704                    }
10705                    if (app.adjTarget instanceof ComponentName) {
10706                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10707                    }
10708                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10709                    //        + " lru=" + currApp.lru);
10710                    if (runList == null) {
10711                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10712                    }
10713                    runList.add(currApp);
10714                }
10715            }
10716        }
10717        return runList;
10718    }
10719
10720    public List<ApplicationInfo> getRunningExternalApplications() {
10721        enforceNotIsolatedCaller("getRunningExternalApplications");
10722        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10723        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10724        if (runningApps != null && runningApps.size() > 0) {
10725            Set<String> extList = new HashSet<String>();
10726            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10727                if (app.pkgList != null) {
10728                    for (String pkg : app.pkgList) {
10729                        extList.add(pkg);
10730                    }
10731                }
10732            }
10733            IPackageManager pm = AppGlobals.getPackageManager();
10734            for (String pkg : extList) {
10735                try {
10736                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10737                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10738                        retList.add(info);
10739                    }
10740                } catch (RemoteException e) {
10741                }
10742            }
10743        }
10744        return retList;
10745    }
10746
10747    @Override
10748    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10749        enforceNotIsolatedCaller("getMyMemoryState");
10750        synchronized (this) {
10751            ProcessRecord proc;
10752            synchronized (mPidsSelfLocked) {
10753                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10754            }
10755            fillInProcMemInfo(proc, outInfo);
10756        }
10757    }
10758
10759    @Override
10760    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10761        if (checkCallingPermission(android.Manifest.permission.DUMP)
10762                != PackageManager.PERMISSION_GRANTED) {
10763            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10764                    + Binder.getCallingPid()
10765                    + ", uid=" + Binder.getCallingUid()
10766                    + " without permission "
10767                    + android.Manifest.permission.DUMP);
10768            return;
10769        }
10770
10771        boolean dumpAll = false;
10772        boolean dumpClient = false;
10773        String dumpPackage = null;
10774
10775        int opti = 0;
10776        while (opti < args.length) {
10777            String opt = args[opti];
10778            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10779                break;
10780            }
10781            opti++;
10782            if ("-a".equals(opt)) {
10783                dumpAll = true;
10784            } else if ("-c".equals(opt)) {
10785                dumpClient = true;
10786            } else if ("-h".equals(opt)) {
10787                pw.println("Activity manager dump options:");
10788                pw.println("  [-a] [-c] [-h] [cmd] ...");
10789                pw.println("  cmd may be one of:");
10790                pw.println("    a[ctivities]: activity stack state");
10791                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10792                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10793                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10794                pw.println("    o[om]: out of memory management");
10795                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10796                pw.println("    provider [COMP_SPEC]: provider client-side state");
10797                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10798                pw.println("    service [COMP_SPEC]: service client-side state");
10799                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10800                pw.println("    all: dump all activities");
10801                pw.println("    top: dump the top activity");
10802                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10803                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10804                pw.println("    a partial substring in a component name, a");
10805                pw.println("    hex object identifier.");
10806                pw.println("  -a: include all available server state.");
10807                pw.println("  -c: include client state.");
10808                return;
10809            } else {
10810                pw.println("Unknown argument: " + opt + "; use -h for help");
10811            }
10812        }
10813
10814        long origId = Binder.clearCallingIdentity();
10815        boolean more = false;
10816        // Is the caller requesting to dump a particular piece of data?
10817        if (opti < args.length) {
10818            String cmd = args[opti];
10819            opti++;
10820            if ("activities".equals(cmd) || "a".equals(cmd)) {
10821                synchronized (this) {
10822                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10823                }
10824            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10825                String[] newArgs;
10826                String name;
10827                if (opti >= args.length) {
10828                    name = null;
10829                    newArgs = EMPTY_STRING_ARRAY;
10830                } else {
10831                    name = args[opti];
10832                    opti++;
10833                    newArgs = new String[args.length - opti];
10834                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10835                            args.length - opti);
10836                }
10837                synchronized (this) {
10838                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10839                }
10840            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10841                String[] newArgs;
10842                String name;
10843                if (opti >= args.length) {
10844                    name = null;
10845                    newArgs = EMPTY_STRING_ARRAY;
10846                } else {
10847                    name = args[opti];
10848                    opti++;
10849                    newArgs = new String[args.length - opti];
10850                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10851                            args.length - opti);
10852                }
10853                synchronized (this) {
10854                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10855                }
10856            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10857                String[] newArgs;
10858                String name;
10859                if (opti >= args.length) {
10860                    name = null;
10861                    newArgs = EMPTY_STRING_ARRAY;
10862                } else {
10863                    name = args[opti];
10864                    opti++;
10865                    newArgs = new String[args.length - opti];
10866                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10867                            args.length - opti);
10868                }
10869                synchronized (this) {
10870                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10871                }
10872            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10873                synchronized (this) {
10874                    dumpOomLocked(fd, pw, args, opti, true);
10875                }
10876            } else if ("provider".equals(cmd)) {
10877                String[] newArgs;
10878                String name;
10879                if (opti >= args.length) {
10880                    name = null;
10881                    newArgs = EMPTY_STRING_ARRAY;
10882                } else {
10883                    name = args[opti];
10884                    opti++;
10885                    newArgs = new String[args.length - opti];
10886                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10887                }
10888                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10889                    pw.println("No providers match: " + name);
10890                    pw.println("Use -h for help.");
10891                }
10892            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10893                synchronized (this) {
10894                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10895                }
10896            } else if ("service".equals(cmd)) {
10897                String[] newArgs;
10898                String name;
10899                if (opti >= args.length) {
10900                    name = null;
10901                    newArgs = EMPTY_STRING_ARRAY;
10902                } else {
10903                    name = args[opti];
10904                    opti++;
10905                    newArgs = new String[args.length - opti];
10906                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10907                            args.length - opti);
10908                }
10909                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10910                    pw.println("No services match: " + name);
10911                    pw.println("Use -h for help.");
10912                }
10913            } else if ("package".equals(cmd)) {
10914                String[] newArgs;
10915                if (opti >= args.length) {
10916                    pw.println("package: no package name specified");
10917                    pw.println("Use -h for help.");
10918                } else {
10919                    dumpPackage = args[opti];
10920                    opti++;
10921                    newArgs = new String[args.length - opti];
10922                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10923                            args.length - opti);
10924                    args = newArgs;
10925                    opti = 0;
10926                    more = true;
10927                }
10928            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10929                synchronized (this) {
10930                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10931                }
10932            } else {
10933                // Dumping a single activity?
10934                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10935                    pw.println("Bad activity command, or no activities match: " + cmd);
10936                    pw.println("Use -h for help.");
10937                }
10938            }
10939            if (!more) {
10940                Binder.restoreCallingIdentity(origId);
10941                return;
10942            }
10943        }
10944
10945        // No piece of data specified, dump everything.
10946        synchronized (this) {
10947            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10948            pw.println();
10949            if (dumpAll) {
10950                pw.println("-------------------------------------------------------------------------------");
10951            }
10952            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10953            pw.println();
10954            if (dumpAll) {
10955                pw.println("-------------------------------------------------------------------------------");
10956            }
10957            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10958            pw.println();
10959            if (dumpAll) {
10960                pw.println("-------------------------------------------------------------------------------");
10961            }
10962            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10963            pw.println();
10964            if (dumpAll) {
10965                pw.println("-------------------------------------------------------------------------------");
10966            }
10967            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10968            pw.println();
10969            if (dumpAll) {
10970                pw.println("-------------------------------------------------------------------------------");
10971            }
10972            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10973        }
10974        Binder.restoreCallingIdentity(origId);
10975    }
10976
10977    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10978            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10979        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10980
10981        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10982                dumpPackage);
10983        boolean needSep = printedAnything;
10984
10985        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10986                dumpPackage, needSep, "  mFocusedActivity: ");
10987        if (printed) {
10988            printedAnything = true;
10989            needSep = false;
10990        }
10991
10992        if (dumpPackage == null) {
10993            if (needSep) {
10994                pw.println();
10995            }
10996            needSep = true;
10997            printedAnything = true;
10998            mStackSupervisor.dump(pw, "  ");
10999        }
11000
11001        if (mRecentTasks.size() > 0) {
11002            boolean printedHeader = false;
11003
11004            final int N = mRecentTasks.size();
11005            for (int i=0; i<N; i++) {
11006                TaskRecord tr = mRecentTasks.get(i);
11007                if (dumpPackage != null) {
11008                    if (tr.realActivity == null ||
11009                            !dumpPackage.equals(tr.realActivity)) {
11010                        continue;
11011                    }
11012                }
11013                if (!printedHeader) {
11014                    if (needSep) {
11015                        pw.println();
11016                    }
11017                    pw.println("  Recent tasks:");
11018                    printedHeader = true;
11019                    printedAnything = true;
11020                }
11021                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11022                        pw.println(tr);
11023                if (dumpAll) {
11024                    mRecentTasks.get(i).dump(pw, "    ");
11025                }
11026            }
11027        }
11028
11029        if (!printedAnything) {
11030            pw.println("  (nothing)");
11031        }
11032    }
11033
11034    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11035            int opti, boolean dumpAll, String dumpPackage) {
11036        boolean needSep = false;
11037        boolean printedAnything = false;
11038        int numPers = 0;
11039
11040        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11041
11042        if (dumpAll) {
11043            final int NP = mProcessNames.getMap().size();
11044            for (int ip=0; ip<NP; ip++) {
11045                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11046                final int NA = procs.size();
11047                for (int ia=0; ia<NA; ia++) {
11048                    ProcessRecord r = procs.valueAt(ia);
11049                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11050                        continue;
11051                    }
11052                    if (!needSep) {
11053                        pw.println("  All known processes:");
11054                        needSep = true;
11055                        printedAnything = true;
11056                    }
11057                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11058                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11059                        pw.print(" "); pw.println(r);
11060                    r.dump(pw, "    ");
11061                    if (r.persistent) {
11062                        numPers++;
11063                    }
11064                }
11065            }
11066        }
11067
11068        if (mIsolatedProcesses.size() > 0) {
11069            boolean printed = false;
11070            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11071                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11072                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11073                    continue;
11074                }
11075                if (!printed) {
11076                    if (needSep) {
11077                        pw.println();
11078                    }
11079                    pw.println("  Isolated process list (sorted by uid):");
11080                    printedAnything = true;
11081                    printed = true;
11082                    needSep = true;
11083                }
11084                pw.println(String.format("%sIsolated #%2d: %s",
11085                        "    ", i, r.toString()));
11086            }
11087        }
11088
11089        if (mLruProcesses.size() > 0) {
11090            if (needSep) {
11091                pw.println();
11092            }
11093            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11094                    pw.print(" total, non-act at ");
11095                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11096                    pw.print(", non-svc at ");
11097                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11098                    pw.println("):");
11099            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11100            needSep = true;
11101            printedAnything = true;
11102        }
11103
11104        if (dumpAll || dumpPackage != null) {
11105            synchronized (mPidsSelfLocked) {
11106                boolean printed = false;
11107                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11108                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11109                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11110                        continue;
11111                    }
11112                    if (!printed) {
11113                        if (needSep) pw.println();
11114                        needSep = true;
11115                        pw.println("  PID mappings:");
11116                        printed = true;
11117                        printedAnything = true;
11118                    }
11119                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11120                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11121                }
11122            }
11123        }
11124
11125        if (mForegroundProcesses.size() > 0) {
11126            synchronized (mPidsSelfLocked) {
11127                boolean printed = false;
11128                for (int i=0; i<mForegroundProcesses.size(); i++) {
11129                    ProcessRecord r = mPidsSelfLocked.get(
11130                            mForegroundProcesses.valueAt(i).pid);
11131                    if (dumpPackage != null && (r == null
11132                            || !r.pkgList.containsKey(dumpPackage))) {
11133                        continue;
11134                    }
11135                    if (!printed) {
11136                        if (needSep) pw.println();
11137                        needSep = true;
11138                        pw.println("  Foreground Processes:");
11139                        printed = true;
11140                        printedAnything = true;
11141                    }
11142                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11143                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11144                }
11145            }
11146        }
11147
11148        if (mPersistentStartingProcesses.size() > 0) {
11149            if (needSep) pw.println();
11150            needSep = true;
11151            printedAnything = true;
11152            pw.println("  Persisent processes that are starting:");
11153            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11154                    "Starting Norm", "Restarting PERS", dumpPackage);
11155        }
11156
11157        if (mRemovedProcesses.size() > 0) {
11158            if (needSep) pw.println();
11159            needSep = true;
11160            printedAnything = true;
11161            pw.println("  Processes that are being removed:");
11162            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11163                    "Removed Norm", "Removed PERS", dumpPackage);
11164        }
11165
11166        if (mProcessesOnHold.size() > 0) {
11167            if (needSep) pw.println();
11168            needSep = true;
11169            printedAnything = true;
11170            pw.println("  Processes that are on old until the system is ready:");
11171            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11172                    "OnHold Norm", "OnHold PERS", dumpPackage);
11173        }
11174
11175        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11176
11177        if (mProcessCrashTimes.getMap().size() > 0) {
11178            boolean printed = false;
11179            long now = SystemClock.uptimeMillis();
11180            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11181            final int NP = pmap.size();
11182            for (int ip=0; ip<NP; ip++) {
11183                String pname = pmap.keyAt(ip);
11184                SparseArray<Long> uids = pmap.valueAt(ip);
11185                final int N = uids.size();
11186                for (int i=0; i<N; i++) {
11187                    int puid = uids.keyAt(i);
11188                    ProcessRecord r = mProcessNames.get(pname, puid);
11189                    if (dumpPackage != null && (r == null
11190                            || !r.pkgList.containsKey(dumpPackage))) {
11191                        continue;
11192                    }
11193                    if (!printed) {
11194                        if (needSep) pw.println();
11195                        needSep = true;
11196                        pw.println("  Time since processes crashed:");
11197                        printed = true;
11198                        printedAnything = true;
11199                    }
11200                    pw.print("    Process "); pw.print(pname);
11201                            pw.print(" uid "); pw.print(puid);
11202                            pw.print(": last crashed ");
11203                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11204                            pw.println(" ago");
11205                }
11206            }
11207        }
11208
11209        if (mBadProcesses.getMap().size() > 0) {
11210            boolean printed = false;
11211            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11212            final int NP = pmap.size();
11213            for (int ip=0; ip<NP; ip++) {
11214                String pname = pmap.keyAt(ip);
11215                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11216                final int N = uids.size();
11217                for (int i=0; i<N; i++) {
11218                    int puid = uids.keyAt(i);
11219                    ProcessRecord r = mProcessNames.get(pname, puid);
11220                    if (dumpPackage != null && (r == null
11221                            || !r.pkgList.containsKey(dumpPackage))) {
11222                        continue;
11223                    }
11224                    if (!printed) {
11225                        if (needSep) pw.println();
11226                        needSep = true;
11227                        pw.println("  Bad processes:");
11228                        printedAnything = true;
11229                    }
11230                    BadProcessInfo info = uids.valueAt(i);
11231                    pw.print("    Bad process "); pw.print(pname);
11232                            pw.print(" uid "); pw.print(puid);
11233                            pw.print(": crashed at time "); pw.println(info.time);
11234                    if (info.shortMsg != null) {
11235                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11236                    }
11237                    if (info.longMsg != null) {
11238                        pw.print("      Long msg: "); pw.println(info.longMsg);
11239                    }
11240                    if (info.stack != null) {
11241                        pw.println("      Stack:");
11242                        int lastPos = 0;
11243                        for (int pos=0; pos<info.stack.length(); pos++) {
11244                            if (info.stack.charAt(pos) == '\n') {
11245                                pw.print("        ");
11246                                pw.write(info.stack, lastPos, pos-lastPos);
11247                                pw.println();
11248                                lastPos = pos+1;
11249                            }
11250                        }
11251                        if (lastPos < info.stack.length()) {
11252                            pw.print("        ");
11253                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11254                            pw.println();
11255                        }
11256                    }
11257                }
11258            }
11259        }
11260
11261        if (dumpPackage == null) {
11262            pw.println();
11263            needSep = false;
11264            pw.println("  mStartedUsers:");
11265            for (int i=0; i<mStartedUsers.size(); i++) {
11266                UserStartedState uss = mStartedUsers.valueAt(i);
11267                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11268                        pw.print(": "); uss.dump("", pw);
11269            }
11270            pw.print("  mStartedUserArray: [");
11271            for (int i=0; i<mStartedUserArray.length; i++) {
11272                if (i > 0) pw.print(", ");
11273                pw.print(mStartedUserArray[i]);
11274            }
11275            pw.println("]");
11276            pw.print("  mUserLru: [");
11277            for (int i=0; i<mUserLru.size(); i++) {
11278                if (i > 0) pw.print(", ");
11279                pw.print(mUserLru.get(i));
11280            }
11281            pw.println("]");
11282            if (dumpAll) {
11283                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11284            }
11285        }
11286        if (mHomeProcess != null && (dumpPackage == null
11287                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11288            if (needSep) {
11289                pw.println();
11290                needSep = false;
11291            }
11292            pw.println("  mHomeProcess: " + mHomeProcess);
11293        }
11294        if (mPreviousProcess != null && (dumpPackage == null
11295                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11296            if (needSep) {
11297                pw.println();
11298                needSep = false;
11299            }
11300            pw.println("  mPreviousProcess: " + mPreviousProcess);
11301        }
11302        if (dumpAll) {
11303            StringBuilder sb = new StringBuilder(128);
11304            sb.append("  mPreviousProcessVisibleTime: ");
11305            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11306            pw.println(sb);
11307        }
11308        if (mHeavyWeightProcess != null && (dumpPackage == null
11309                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11310            if (needSep) {
11311                pw.println();
11312                needSep = false;
11313            }
11314            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11315        }
11316        if (dumpPackage == null) {
11317            pw.println("  mConfiguration: " + mConfiguration);
11318        }
11319        if (dumpAll) {
11320            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11321            if (mCompatModePackages.getPackages().size() > 0) {
11322                boolean printed = false;
11323                for (Map.Entry<String, Integer> entry
11324                        : mCompatModePackages.getPackages().entrySet()) {
11325                    String pkg = entry.getKey();
11326                    int mode = entry.getValue();
11327                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11328                        continue;
11329                    }
11330                    if (!printed) {
11331                        pw.println("  mScreenCompatPackages:");
11332                        printed = true;
11333                    }
11334                    pw.print("    "); pw.print(pkg); pw.print(": ");
11335                            pw.print(mode); pw.println();
11336                }
11337            }
11338        }
11339        if (dumpPackage == null) {
11340            if (mSleeping || mWentToSleep || mLockScreenShown) {
11341                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11342                        + " mLockScreenShown " + mLockScreenShown);
11343            }
11344            if (mShuttingDown || mRunningVoice) {
11345                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11346            }
11347        }
11348        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11349                || mOrigWaitForDebugger) {
11350            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11351                    || dumpPackage.equals(mOrigDebugApp)) {
11352                if (needSep) {
11353                    pw.println();
11354                    needSep = false;
11355                }
11356                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11357                        + " mDebugTransient=" + mDebugTransient
11358                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11359            }
11360        }
11361        if (mOpenGlTraceApp != null) {
11362            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11363                if (needSep) {
11364                    pw.println();
11365                    needSep = false;
11366                }
11367                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11368            }
11369        }
11370        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11371                || mProfileFd != null) {
11372            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11373                if (needSep) {
11374                    pw.println();
11375                    needSep = false;
11376                }
11377                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11378                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11379                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11380                        + mAutoStopProfiler);
11381            }
11382        }
11383        if (dumpPackage == null) {
11384            if (mAlwaysFinishActivities || mController != null) {
11385                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11386                        + " mController=" + mController);
11387            }
11388            if (dumpAll) {
11389                pw.println("  Total persistent processes: " + numPers);
11390                pw.println("  mProcessesReady=" + mProcessesReady
11391                        + " mSystemReady=" + mSystemReady);
11392                pw.println("  mBooting=" + mBooting
11393                        + " mBooted=" + mBooted
11394                        + " mFactoryTest=" + mFactoryTest);
11395                pw.print("  mLastPowerCheckRealtime=");
11396                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11397                        pw.println("");
11398                pw.print("  mLastPowerCheckUptime=");
11399                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11400                        pw.println("");
11401                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11402                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11403                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11404                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11405                        + " (" + mLruProcesses.size() + " total)"
11406                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11407                        + " mNumServiceProcs=" + mNumServiceProcs
11408                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11409                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11410                        + " mLastMemoryLevel" + mLastMemoryLevel
11411                        + " mLastNumProcesses" + mLastNumProcesses);
11412                long now = SystemClock.uptimeMillis();
11413                pw.print("  mLastIdleTime=");
11414                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11415                        pw.print(" mLowRamSinceLastIdle=");
11416                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11417                        pw.println();
11418            }
11419        }
11420
11421        if (!printedAnything) {
11422            pw.println("  (nothing)");
11423        }
11424    }
11425
11426    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11427            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11428        if (mProcessesToGc.size() > 0) {
11429            boolean printed = false;
11430            long now = SystemClock.uptimeMillis();
11431            for (int i=0; i<mProcessesToGc.size(); i++) {
11432                ProcessRecord proc = mProcessesToGc.get(i);
11433                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11434                    continue;
11435                }
11436                if (!printed) {
11437                    if (needSep) pw.println();
11438                    needSep = true;
11439                    pw.println("  Processes that are waiting to GC:");
11440                    printed = true;
11441                }
11442                pw.print("    Process "); pw.println(proc);
11443                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11444                        pw.print(", last gced=");
11445                        pw.print(now-proc.lastRequestedGc);
11446                        pw.print(" ms ago, last lowMem=");
11447                        pw.print(now-proc.lastLowMemory);
11448                        pw.println(" ms ago");
11449
11450            }
11451        }
11452        return needSep;
11453    }
11454
11455    void printOomLevel(PrintWriter pw, String name, int adj) {
11456        pw.print("    ");
11457        if (adj >= 0) {
11458            pw.print(' ');
11459            if (adj < 10) pw.print(' ');
11460        } else {
11461            if (adj > -10) pw.print(' ');
11462        }
11463        pw.print(adj);
11464        pw.print(": ");
11465        pw.print(name);
11466        pw.print(" (");
11467        pw.print(mProcessList.getMemLevel(adj)/1024);
11468        pw.println(" kB)");
11469    }
11470
11471    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11472            int opti, boolean dumpAll) {
11473        boolean needSep = false;
11474
11475        if (mLruProcesses.size() > 0) {
11476            if (needSep) pw.println();
11477            needSep = true;
11478            pw.println("  OOM levels:");
11479            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11480            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11481            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11482            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11483            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11484            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11485            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11486            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11487            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11488            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11489            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11490            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11491            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11492
11493            if (needSep) pw.println();
11494            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11495                    pw.print(" total, non-act at ");
11496                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11497                    pw.print(", non-svc at ");
11498                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11499                    pw.println("):");
11500            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11501            needSep = true;
11502        }
11503
11504        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11505
11506        pw.println();
11507        pw.println("  mHomeProcess: " + mHomeProcess);
11508        pw.println("  mPreviousProcess: " + mPreviousProcess);
11509        if (mHeavyWeightProcess != null) {
11510            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11511        }
11512
11513        return true;
11514    }
11515
11516    /**
11517     * There are three ways to call this:
11518     *  - no provider specified: dump all the providers
11519     *  - a flattened component name that matched an existing provider was specified as the
11520     *    first arg: dump that one provider
11521     *  - the first arg isn't the flattened component name of an existing provider:
11522     *    dump all providers whose component contains the first arg as a substring
11523     */
11524    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11525            int opti, boolean dumpAll) {
11526        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11527    }
11528
11529    static class ItemMatcher {
11530        ArrayList<ComponentName> components;
11531        ArrayList<String> strings;
11532        ArrayList<Integer> objects;
11533        boolean all;
11534
11535        ItemMatcher() {
11536            all = true;
11537        }
11538
11539        void build(String name) {
11540            ComponentName componentName = ComponentName.unflattenFromString(name);
11541            if (componentName != null) {
11542                if (components == null) {
11543                    components = new ArrayList<ComponentName>();
11544                }
11545                components.add(componentName);
11546                all = false;
11547            } else {
11548                int objectId = 0;
11549                // Not a '/' separated full component name; maybe an object ID?
11550                try {
11551                    objectId = Integer.parseInt(name, 16);
11552                    if (objects == null) {
11553                        objects = new ArrayList<Integer>();
11554                    }
11555                    objects.add(objectId);
11556                    all = false;
11557                } catch (RuntimeException e) {
11558                    // Not an integer; just do string match.
11559                    if (strings == null) {
11560                        strings = new ArrayList<String>();
11561                    }
11562                    strings.add(name);
11563                    all = false;
11564                }
11565            }
11566        }
11567
11568        int build(String[] args, int opti) {
11569            for (; opti<args.length; opti++) {
11570                String name = args[opti];
11571                if ("--".equals(name)) {
11572                    return opti+1;
11573                }
11574                build(name);
11575            }
11576            return opti;
11577        }
11578
11579        boolean match(Object object, ComponentName comp) {
11580            if (all) {
11581                return true;
11582            }
11583            if (components != null) {
11584                for (int i=0; i<components.size(); i++) {
11585                    if (components.get(i).equals(comp)) {
11586                        return true;
11587                    }
11588                }
11589            }
11590            if (objects != null) {
11591                for (int i=0; i<objects.size(); i++) {
11592                    if (System.identityHashCode(object) == objects.get(i)) {
11593                        return true;
11594                    }
11595                }
11596            }
11597            if (strings != null) {
11598                String flat = comp.flattenToString();
11599                for (int i=0; i<strings.size(); i++) {
11600                    if (flat.contains(strings.get(i))) {
11601                        return true;
11602                    }
11603                }
11604            }
11605            return false;
11606        }
11607    }
11608
11609    /**
11610     * There are three things that cmd can be:
11611     *  - a flattened component name that matches an existing activity
11612     *  - the cmd arg isn't the flattened component name of an existing activity:
11613     *    dump all activity whose component contains the cmd as a substring
11614     *  - A hex number of the ActivityRecord object instance.
11615     */
11616    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11617            int opti, boolean dumpAll) {
11618        ArrayList<ActivityRecord> activities;
11619
11620        synchronized (this) {
11621            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11622        }
11623
11624        if (activities.size() <= 0) {
11625            return false;
11626        }
11627
11628        String[] newArgs = new String[args.length - opti];
11629        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11630
11631        TaskRecord lastTask = null;
11632        boolean needSep = false;
11633        for (int i=activities.size()-1; i>=0; i--) {
11634            ActivityRecord r = activities.get(i);
11635            if (needSep) {
11636                pw.println();
11637            }
11638            needSep = true;
11639            synchronized (this) {
11640                if (lastTask != r.task) {
11641                    lastTask = r.task;
11642                    pw.print("TASK "); pw.print(lastTask.affinity);
11643                            pw.print(" id="); pw.println(lastTask.taskId);
11644                    if (dumpAll) {
11645                        lastTask.dump(pw, "  ");
11646                    }
11647                }
11648            }
11649            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11650        }
11651        return true;
11652    }
11653
11654    /**
11655     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11656     * there is a thread associated with the activity.
11657     */
11658    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11659            final ActivityRecord r, String[] args, boolean dumpAll) {
11660        String innerPrefix = prefix + "  ";
11661        synchronized (this) {
11662            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11663                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11664                    pw.print(" pid=");
11665                    if (r.app != null) pw.println(r.app.pid);
11666                    else pw.println("(not running)");
11667            if (dumpAll) {
11668                r.dump(pw, innerPrefix);
11669            }
11670        }
11671        if (r.app != null && r.app.thread != null) {
11672            // flush anything that is already in the PrintWriter since the thread is going
11673            // to write to the file descriptor directly
11674            pw.flush();
11675            try {
11676                TransferPipe tp = new TransferPipe();
11677                try {
11678                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11679                            r.appToken, innerPrefix, args);
11680                    tp.go(fd);
11681                } finally {
11682                    tp.kill();
11683                }
11684            } catch (IOException e) {
11685                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11686            } catch (RemoteException e) {
11687                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11688            }
11689        }
11690    }
11691
11692    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11693            int opti, boolean dumpAll, String dumpPackage) {
11694        boolean needSep = false;
11695        boolean onlyHistory = false;
11696        boolean printedAnything = false;
11697
11698        if ("history".equals(dumpPackage)) {
11699            if (opti < args.length && "-s".equals(args[opti])) {
11700                dumpAll = false;
11701            }
11702            onlyHistory = true;
11703            dumpPackage = null;
11704        }
11705
11706        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11707        if (!onlyHistory && dumpAll) {
11708            if (mRegisteredReceivers.size() > 0) {
11709                boolean printed = false;
11710                Iterator it = mRegisteredReceivers.values().iterator();
11711                while (it.hasNext()) {
11712                    ReceiverList r = (ReceiverList)it.next();
11713                    if (dumpPackage != null && (r.app == null ||
11714                            !dumpPackage.equals(r.app.info.packageName))) {
11715                        continue;
11716                    }
11717                    if (!printed) {
11718                        pw.println("  Registered Receivers:");
11719                        needSep = true;
11720                        printed = true;
11721                        printedAnything = true;
11722                    }
11723                    pw.print("  * "); pw.println(r);
11724                    r.dump(pw, "    ");
11725                }
11726            }
11727
11728            if (mReceiverResolver.dump(pw, needSep ?
11729                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11730                    "    ", dumpPackage, false)) {
11731                needSep = true;
11732                printedAnything = true;
11733            }
11734        }
11735
11736        for (BroadcastQueue q : mBroadcastQueues) {
11737            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11738            printedAnything |= needSep;
11739        }
11740
11741        needSep = true;
11742
11743        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11744            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11745                if (needSep) {
11746                    pw.println();
11747                }
11748                needSep = true;
11749                printedAnything = true;
11750                pw.print("  Sticky broadcasts for user ");
11751                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11752                StringBuilder sb = new StringBuilder(128);
11753                for (Map.Entry<String, ArrayList<Intent>> ent
11754                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11755                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11756                    if (dumpAll) {
11757                        pw.println(":");
11758                        ArrayList<Intent> intents = ent.getValue();
11759                        final int N = intents.size();
11760                        for (int i=0; i<N; i++) {
11761                            sb.setLength(0);
11762                            sb.append("    Intent: ");
11763                            intents.get(i).toShortString(sb, false, true, false, false);
11764                            pw.println(sb.toString());
11765                            Bundle bundle = intents.get(i).getExtras();
11766                            if (bundle != null) {
11767                                pw.print("      ");
11768                                pw.println(bundle.toString());
11769                            }
11770                        }
11771                    } else {
11772                        pw.println("");
11773                    }
11774                }
11775            }
11776        }
11777
11778        if (!onlyHistory && dumpAll) {
11779            pw.println();
11780            for (BroadcastQueue queue : mBroadcastQueues) {
11781                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11782                        + queue.mBroadcastsScheduled);
11783            }
11784            pw.println("  mHandler:");
11785            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11786            needSep = true;
11787            printedAnything = true;
11788        }
11789
11790        if (!printedAnything) {
11791            pw.println("  (nothing)");
11792        }
11793    }
11794
11795    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11796            int opti, boolean dumpAll, String dumpPackage) {
11797        boolean needSep;
11798        boolean printedAnything = false;
11799
11800        ItemMatcher matcher = new ItemMatcher();
11801        matcher.build(args, opti);
11802
11803        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11804
11805        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11806        printedAnything |= needSep;
11807
11808        if (mLaunchingProviders.size() > 0) {
11809            boolean printed = false;
11810            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11811                ContentProviderRecord r = mLaunchingProviders.get(i);
11812                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11813                    continue;
11814                }
11815                if (!printed) {
11816                    if (needSep) pw.println();
11817                    needSep = true;
11818                    pw.println("  Launching content providers:");
11819                    printed = true;
11820                    printedAnything = true;
11821                }
11822                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11823                        pw.println(r);
11824            }
11825        }
11826
11827        if (mGrantedUriPermissions.size() > 0) {
11828            boolean printed = false;
11829            int dumpUid = -2;
11830            if (dumpPackage != null) {
11831                try {
11832                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11833                } catch (NameNotFoundException e) {
11834                    dumpUid = -1;
11835                }
11836            }
11837            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11838                int uid = mGrantedUriPermissions.keyAt(i);
11839                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11840                    continue;
11841                }
11842                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11843                if (!printed) {
11844                    if (needSep) pw.println();
11845                    needSep = true;
11846                    pw.println("  Granted Uri Permissions:");
11847                    printed = true;
11848                    printedAnything = true;
11849                }
11850                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11851                for (UriPermission perm : perms.values()) {
11852                    pw.print("    "); pw.println(perm);
11853                    if (dumpAll) {
11854                        perm.dump(pw, "      ");
11855                    }
11856                }
11857            }
11858        }
11859
11860        if (!printedAnything) {
11861            pw.println("  (nothing)");
11862        }
11863    }
11864
11865    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11866            int opti, boolean dumpAll, String dumpPackage) {
11867        boolean printed = false;
11868
11869        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11870
11871        if (mIntentSenderRecords.size() > 0) {
11872            Iterator<WeakReference<PendingIntentRecord>> it
11873                    = mIntentSenderRecords.values().iterator();
11874            while (it.hasNext()) {
11875                WeakReference<PendingIntentRecord> ref = it.next();
11876                PendingIntentRecord rec = ref != null ? ref.get(): null;
11877                if (dumpPackage != null && (rec == null
11878                        || !dumpPackage.equals(rec.key.packageName))) {
11879                    continue;
11880                }
11881                printed = true;
11882                if (rec != null) {
11883                    pw.print("  * "); pw.println(rec);
11884                    if (dumpAll) {
11885                        rec.dump(pw, "    ");
11886                    }
11887                } else {
11888                    pw.print("  * "); pw.println(ref);
11889                }
11890            }
11891        }
11892
11893        if (!printed) {
11894            pw.println("  (nothing)");
11895        }
11896    }
11897
11898    private static final int dumpProcessList(PrintWriter pw,
11899            ActivityManagerService service, List list,
11900            String prefix, String normalLabel, String persistentLabel,
11901            String dumpPackage) {
11902        int numPers = 0;
11903        final int N = list.size()-1;
11904        for (int i=N; i>=0; i--) {
11905            ProcessRecord r = (ProcessRecord)list.get(i);
11906            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11907                continue;
11908            }
11909            pw.println(String.format("%s%s #%2d: %s",
11910                    prefix, (r.persistent ? persistentLabel : normalLabel),
11911                    i, r.toString()));
11912            if (r.persistent) {
11913                numPers++;
11914            }
11915        }
11916        return numPers;
11917    }
11918
11919    private static final boolean dumpProcessOomList(PrintWriter pw,
11920            ActivityManagerService service, List<ProcessRecord> origList,
11921            String prefix, String normalLabel, String persistentLabel,
11922            boolean inclDetails, String dumpPackage) {
11923
11924        ArrayList<Pair<ProcessRecord, Integer>> list
11925                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11926        for (int i=0; i<origList.size(); i++) {
11927            ProcessRecord r = origList.get(i);
11928            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11929                continue;
11930            }
11931            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11932        }
11933
11934        if (list.size() <= 0) {
11935            return false;
11936        }
11937
11938        Comparator<Pair<ProcessRecord, Integer>> comparator
11939                = new Comparator<Pair<ProcessRecord, Integer>>() {
11940            @Override
11941            public int compare(Pair<ProcessRecord, Integer> object1,
11942                    Pair<ProcessRecord, Integer> object2) {
11943                if (object1.first.setAdj != object2.first.setAdj) {
11944                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11945                }
11946                if (object1.second.intValue() != object2.second.intValue()) {
11947                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11948                }
11949                return 0;
11950            }
11951        };
11952
11953        Collections.sort(list, comparator);
11954
11955        final long curRealtime = SystemClock.elapsedRealtime();
11956        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11957        final long curUptime = SystemClock.uptimeMillis();
11958        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11959
11960        for (int i=list.size()-1; i>=0; i--) {
11961            ProcessRecord r = list.get(i).first;
11962            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11963            char schedGroup;
11964            switch (r.setSchedGroup) {
11965                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11966                    schedGroup = 'B';
11967                    break;
11968                case Process.THREAD_GROUP_DEFAULT:
11969                    schedGroup = 'F';
11970                    break;
11971                default:
11972                    schedGroup = '?';
11973                    break;
11974            }
11975            char foreground;
11976            if (r.foregroundActivities) {
11977                foreground = 'A';
11978            } else if (r.foregroundServices) {
11979                foreground = 'S';
11980            } else {
11981                foreground = ' ';
11982            }
11983            String procState = ProcessList.makeProcStateString(r.curProcState);
11984            pw.print(prefix);
11985            pw.print(r.persistent ? persistentLabel : normalLabel);
11986            pw.print(" #");
11987            int num = (origList.size()-1)-list.get(i).second;
11988            if (num < 10) pw.print(' ');
11989            pw.print(num);
11990            pw.print(": ");
11991            pw.print(oomAdj);
11992            pw.print(' ');
11993            pw.print(schedGroup);
11994            pw.print('/');
11995            pw.print(foreground);
11996            pw.print('/');
11997            pw.print(procState);
11998            pw.print(" trm:");
11999            if (r.trimMemoryLevel < 10) pw.print(' ');
12000            pw.print(r.trimMemoryLevel);
12001            pw.print(' ');
12002            pw.print(r.toShortString());
12003            pw.print(" (");
12004            pw.print(r.adjType);
12005            pw.println(')');
12006            if (r.adjSource != null || r.adjTarget != null) {
12007                pw.print(prefix);
12008                pw.print("    ");
12009                if (r.adjTarget instanceof ComponentName) {
12010                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12011                } else if (r.adjTarget != null) {
12012                    pw.print(r.adjTarget.toString());
12013                } else {
12014                    pw.print("{null}");
12015                }
12016                pw.print("<=");
12017                if (r.adjSource instanceof ProcessRecord) {
12018                    pw.print("Proc{");
12019                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12020                    pw.println("}");
12021                } else if (r.adjSource != null) {
12022                    pw.println(r.adjSource.toString());
12023                } else {
12024                    pw.println("{null}");
12025                }
12026            }
12027            if (inclDetails) {
12028                pw.print(prefix);
12029                pw.print("    ");
12030                pw.print("oom: max="); pw.print(r.maxAdj);
12031                pw.print(" curRaw="); pw.print(r.curRawAdj);
12032                pw.print(" setRaw="); pw.print(r.setRawAdj);
12033                pw.print(" cur="); pw.print(r.curAdj);
12034                pw.print(" set="); pw.println(r.setAdj);
12035                pw.print(prefix);
12036                pw.print("    ");
12037                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12038                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12039                pw.print(" lastPss="); pw.print(r.lastPss);
12040                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12041                pw.print(prefix);
12042                pw.print("    ");
12043                pw.print("keeping="); pw.print(r.keeping);
12044                pw.print(" cached="); pw.print(r.cached);
12045                pw.print(" empty="); pw.print(r.empty);
12046                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12047
12048                if (!r.keeping) {
12049                    if (r.lastWakeTime != 0) {
12050                        long wtime;
12051                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12052                        synchronized (stats) {
12053                            wtime = stats.getProcessWakeTime(r.info.uid,
12054                                    r.pid, curRealtime);
12055                        }
12056                        long timeUsed = wtime - r.lastWakeTime;
12057                        pw.print(prefix);
12058                        pw.print("    ");
12059                        pw.print("keep awake over ");
12060                        TimeUtils.formatDuration(realtimeSince, pw);
12061                        pw.print(" used ");
12062                        TimeUtils.formatDuration(timeUsed, pw);
12063                        pw.print(" (");
12064                        pw.print((timeUsed*100)/realtimeSince);
12065                        pw.println("%)");
12066                    }
12067                    if (r.lastCpuTime != 0) {
12068                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12069                        pw.print(prefix);
12070                        pw.print("    ");
12071                        pw.print("run cpu over ");
12072                        TimeUtils.formatDuration(uptimeSince, pw);
12073                        pw.print(" used ");
12074                        TimeUtils.formatDuration(timeUsed, pw);
12075                        pw.print(" (");
12076                        pw.print((timeUsed*100)/uptimeSince);
12077                        pw.println("%)");
12078                    }
12079                }
12080            }
12081        }
12082        return true;
12083    }
12084
12085    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12086        ArrayList<ProcessRecord> procs;
12087        synchronized (this) {
12088            if (args != null && args.length > start
12089                    && args[start].charAt(0) != '-') {
12090                procs = new ArrayList<ProcessRecord>();
12091                int pid = -1;
12092                try {
12093                    pid = Integer.parseInt(args[start]);
12094                } catch (NumberFormatException e) {
12095                }
12096                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12097                    ProcessRecord proc = mLruProcesses.get(i);
12098                    if (proc.pid == pid) {
12099                        procs.add(proc);
12100                    } else if (proc.processName.equals(args[start])) {
12101                        procs.add(proc);
12102                    }
12103                }
12104                if (procs.size() <= 0) {
12105                    return null;
12106                }
12107            } else {
12108                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12109            }
12110        }
12111        return procs;
12112    }
12113
12114    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12115            PrintWriter pw, String[] args) {
12116        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12117        if (procs == null) {
12118            pw.println("No process found for: " + args[0]);
12119            return;
12120        }
12121
12122        long uptime = SystemClock.uptimeMillis();
12123        long realtime = SystemClock.elapsedRealtime();
12124        pw.println("Applications Graphics Acceleration Info:");
12125        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12126
12127        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12128            ProcessRecord r = procs.get(i);
12129            if (r.thread != null) {
12130                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12131                pw.flush();
12132                try {
12133                    TransferPipe tp = new TransferPipe();
12134                    try {
12135                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12136                        tp.go(fd);
12137                    } finally {
12138                        tp.kill();
12139                    }
12140                } catch (IOException e) {
12141                    pw.println("Failure while dumping the app: " + r);
12142                    pw.flush();
12143                } catch (RemoteException e) {
12144                    pw.println("Got a RemoteException while dumping the app " + r);
12145                    pw.flush();
12146                }
12147            }
12148        }
12149    }
12150
12151    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12152        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12153        if (procs == null) {
12154            pw.println("No process found for: " + args[0]);
12155            return;
12156        }
12157
12158        pw.println("Applications Database Info:");
12159
12160        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12161            ProcessRecord r = procs.get(i);
12162            if (r.thread != null) {
12163                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12164                pw.flush();
12165                try {
12166                    TransferPipe tp = new TransferPipe();
12167                    try {
12168                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12169                        tp.go(fd);
12170                    } finally {
12171                        tp.kill();
12172                    }
12173                } catch (IOException e) {
12174                    pw.println("Failure while dumping the app: " + r);
12175                    pw.flush();
12176                } catch (RemoteException e) {
12177                    pw.println("Got a RemoteException while dumping the app " + r);
12178                    pw.flush();
12179                }
12180            }
12181        }
12182    }
12183
12184    final static class MemItem {
12185        final boolean isProc;
12186        final String label;
12187        final String shortLabel;
12188        final long pss;
12189        final int id;
12190        final boolean hasActivities;
12191        ArrayList<MemItem> subitems;
12192
12193        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12194                boolean _hasActivities) {
12195            isProc = true;
12196            label = _label;
12197            shortLabel = _shortLabel;
12198            pss = _pss;
12199            id = _id;
12200            hasActivities = _hasActivities;
12201        }
12202
12203        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12204            isProc = false;
12205            label = _label;
12206            shortLabel = _shortLabel;
12207            pss = _pss;
12208            id = _id;
12209            hasActivities = false;
12210        }
12211    }
12212
12213    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12214            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12215        if (sort && !isCompact) {
12216            Collections.sort(items, new Comparator<MemItem>() {
12217                @Override
12218                public int compare(MemItem lhs, MemItem rhs) {
12219                    if (lhs.pss < rhs.pss) {
12220                        return 1;
12221                    } else if (lhs.pss > rhs.pss) {
12222                        return -1;
12223                    }
12224                    return 0;
12225                }
12226            });
12227        }
12228
12229        for (int i=0; i<items.size(); i++) {
12230            MemItem mi = items.get(i);
12231            if (!isCompact) {
12232                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12233            } else if (mi.isProc) {
12234                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12235                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12236                pw.println(mi.hasActivities ? ",a" : ",e");
12237            } else {
12238                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12239                pw.println(mi.pss);
12240            }
12241            if (mi.subitems != null) {
12242                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12243                        true, isCompact);
12244            }
12245        }
12246    }
12247
12248    // These are in KB.
12249    static final long[] DUMP_MEM_BUCKETS = new long[] {
12250        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12251        120*1024, 160*1024, 200*1024,
12252        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12253        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12254    };
12255
12256    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12257            boolean stackLike) {
12258        int start = label.lastIndexOf('.');
12259        if (start >= 0) start++;
12260        else start = 0;
12261        int end = label.length();
12262        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12263            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12264                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12265                out.append(bucket);
12266                out.append(stackLike ? "MB." : "MB ");
12267                out.append(label, start, end);
12268                return;
12269            }
12270        }
12271        out.append(memKB/1024);
12272        out.append(stackLike ? "MB." : "MB ");
12273        out.append(label, start, end);
12274    }
12275
12276    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12277            ProcessList.NATIVE_ADJ,
12278            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12279            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12280            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12281            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12282            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12283    };
12284    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12285            "Native",
12286            "System", "Persistent", "Foreground",
12287            "Visible", "Perceptible",
12288            "Heavy Weight", "Backup",
12289            "A Services", "Home",
12290            "Previous", "B Services", "Cached"
12291    };
12292    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12293            "native",
12294            "sys", "pers", "fore",
12295            "vis", "percept",
12296            "heavy", "backup",
12297            "servicea", "home",
12298            "prev", "serviceb", "cached"
12299    };
12300
12301    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12302            long realtime, boolean isCheckinRequest, boolean isCompact) {
12303        if (isCheckinRequest || isCompact) {
12304            // short checkin version
12305            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12306        } else {
12307            pw.println("Applications Memory Usage (kB):");
12308            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12309        }
12310    }
12311
12312    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12313            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12314        boolean dumpDetails = false;
12315        boolean dumpFullDetails = false;
12316        boolean dumpDalvik = false;
12317        boolean oomOnly = false;
12318        boolean isCompact = false;
12319        boolean localOnly = false;
12320
12321        int opti = 0;
12322        while (opti < args.length) {
12323            String opt = args[opti];
12324            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12325                break;
12326            }
12327            opti++;
12328            if ("-a".equals(opt)) {
12329                dumpDetails = true;
12330                dumpFullDetails = true;
12331                dumpDalvik = true;
12332            } else if ("-d".equals(opt)) {
12333                dumpDalvik = true;
12334            } else if ("-c".equals(opt)) {
12335                isCompact = true;
12336            } else if ("--oom".equals(opt)) {
12337                oomOnly = true;
12338            } else if ("--local".equals(opt)) {
12339                localOnly = true;
12340            } else if ("-h".equals(opt)) {
12341                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12342                pw.println("  -a: include all available information for each process.");
12343                pw.println("  -d: include dalvik details when dumping process details.");
12344                pw.println("  -c: dump in a compact machine-parseable representation.");
12345                pw.println("  --oom: only show processes organized by oom adj.");
12346                pw.println("  --local: only collect details locally, don't call process.");
12347                pw.println("If [process] is specified it can be the name or ");
12348                pw.println("pid of a specific process to dump.");
12349                return;
12350            } else {
12351                pw.println("Unknown argument: " + opt + "; use -h for help");
12352            }
12353        }
12354
12355        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12356        long uptime = SystemClock.uptimeMillis();
12357        long realtime = SystemClock.elapsedRealtime();
12358        final long[] tmpLong = new long[1];
12359
12360        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12361        if (procs == null) {
12362            // No Java processes.  Maybe they want to print a native process.
12363            if (args != null && args.length > opti
12364                    && args[opti].charAt(0) != '-') {
12365                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12366                        = new ArrayList<ProcessCpuTracker.Stats>();
12367                updateCpuStatsNow();
12368                int findPid = -1;
12369                try {
12370                    findPid = Integer.parseInt(args[opti]);
12371                } catch (NumberFormatException e) {
12372                }
12373                synchronized (mProcessCpuThread) {
12374                    final int N = mProcessCpuTracker.countStats();
12375                    for (int i=0; i<N; i++) {
12376                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12377                        if (st.pid == findPid || (st.baseName != null
12378                                && st.baseName.equals(args[opti]))) {
12379                            nativeProcs.add(st);
12380                        }
12381                    }
12382                }
12383                if (nativeProcs.size() > 0) {
12384                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12385                            isCompact);
12386                    Debug.MemoryInfo mi = null;
12387                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12388                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12389                        final int pid = r.pid;
12390                        if (!isCheckinRequest && dumpDetails) {
12391                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12392                        }
12393                        if (mi == null) {
12394                            mi = new Debug.MemoryInfo();
12395                        }
12396                        if (dumpDetails || (!brief && !oomOnly)) {
12397                            Debug.getMemoryInfo(pid, mi);
12398                        } else {
12399                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12400                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12401                        }
12402                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12403                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12404                        if (isCheckinRequest) {
12405                            pw.println();
12406                        }
12407                    }
12408                    return;
12409                }
12410            }
12411            pw.println("No process found for: " + args[opti]);
12412            return;
12413        }
12414
12415        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12416            dumpDetails = true;
12417        }
12418
12419        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12420
12421        String[] innerArgs = new String[args.length-opti];
12422        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12423
12424        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12425        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12426        long nativePss=0, dalvikPss=0, otherPss=0;
12427        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12428
12429        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12430        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12431                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12432
12433        long totalPss = 0;
12434        long cachedPss = 0;
12435
12436        Debug.MemoryInfo mi = null;
12437        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12438            final ProcessRecord r = procs.get(i);
12439            final IApplicationThread thread;
12440            final int pid;
12441            final int oomAdj;
12442            final boolean hasActivities;
12443            synchronized (this) {
12444                thread = r.thread;
12445                pid = r.pid;
12446                oomAdj = r.getSetAdjWithServices();
12447                hasActivities = r.activities.size() > 0;
12448            }
12449            if (thread != null) {
12450                if (!isCheckinRequest && dumpDetails) {
12451                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12452                }
12453                if (mi == null) {
12454                    mi = new Debug.MemoryInfo();
12455                }
12456                if (dumpDetails || (!brief && !oomOnly)) {
12457                    Debug.getMemoryInfo(pid, mi);
12458                } else {
12459                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12460                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12461                }
12462                if (dumpDetails) {
12463                    if (localOnly) {
12464                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12465                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12466                        if (isCheckinRequest) {
12467                            pw.println();
12468                        }
12469                    } else {
12470                        try {
12471                            pw.flush();
12472                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12473                                    dumpDalvik, innerArgs);
12474                        } catch (RemoteException e) {
12475                            if (!isCheckinRequest) {
12476                                pw.println("Got RemoteException!");
12477                                pw.flush();
12478                            }
12479                        }
12480                    }
12481                }
12482
12483                final long myTotalPss = mi.getTotalPss();
12484                final long myTotalUss = mi.getTotalUss();
12485
12486                synchronized (this) {
12487                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12488                        // Record this for posterity if the process has been stable.
12489                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12490                    }
12491                }
12492
12493                if (!isCheckinRequest && mi != null) {
12494                    totalPss += myTotalPss;
12495                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12496                            (hasActivities ? " / activities)" : ")"),
12497                            r.processName, myTotalPss, pid, hasActivities);
12498                    procMems.add(pssItem);
12499                    procMemsMap.put(pid, pssItem);
12500
12501                    nativePss += mi.nativePss;
12502                    dalvikPss += mi.dalvikPss;
12503                    otherPss += mi.otherPss;
12504                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12505                        long mem = mi.getOtherPss(j);
12506                        miscPss[j] += mem;
12507                        otherPss -= mem;
12508                    }
12509
12510                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12511                        cachedPss += myTotalPss;
12512                    }
12513
12514                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12515                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12516                                || oomIndex == (oomPss.length-1)) {
12517                            oomPss[oomIndex] += myTotalPss;
12518                            if (oomProcs[oomIndex] == null) {
12519                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12520                            }
12521                            oomProcs[oomIndex].add(pssItem);
12522                            break;
12523                        }
12524                    }
12525                }
12526            }
12527        }
12528
12529        if (!isCheckinRequest && procs.size() > 1) {
12530            // If we are showing aggregations, also look for native processes to
12531            // include so that our aggregations are more accurate.
12532            updateCpuStatsNow();
12533            synchronized (mProcessCpuThread) {
12534                final int N = mProcessCpuTracker.countStats();
12535                for (int i=0; i<N; i++) {
12536                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12537                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12538                        if (mi == null) {
12539                            mi = new Debug.MemoryInfo();
12540                        }
12541                        if (!brief && !oomOnly) {
12542                            Debug.getMemoryInfo(st.pid, mi);
12543                        } else {
12544                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12545                            mi.nativePrivateDirty = (int)tmpLong[0];
12546                        }
12547
12548                        final long myTotalPss = mi.getTotalPss();
12549                        totalPss += myTotalPss;
12550
12551                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12552                                st.name, myTotalPss, st.pid, false);
12553                        procMems.add(pssItem);
12554
12555                        nativePss += mi.nativePss;
12556                        dalvikPss += mi.dalvikPss;
12557                        otherPss += mi.otherPss;
12558                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12559                            long mem = mi.getOtherPss(j);
12560                            miscPss[j] += mem;
12561                            otherPss -= mem;
12562                        }
12563                        oomPss[0] += myTotalPss;
12564                        if (oomProcs[0] == null) {
12565                            oomProcs[0] = new ArrayList<MemItem>();
12566                        }
12567                        oomProcs[0].add(pssItem);
12568                    }
12569                }
12570            }
12571
12572            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12573
12574            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12575            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12576            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12577            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12578                String label = Debug.MemoryInfo.getOtherLabel(j);
12579                catMems.add(new MemItem(label, label, miscPss[j], j));
12580            }
12581
12582            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12583            for (int j=0; j<oomPss.length; j++) {
12584                if (oomPss[j] != 0) {
12585                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12586                            : DUMP_MEM_OOM_LABEL[j];
12587                    MemItem item = new MemItem(label, label, oomPss[j],
12588                            DUMP_MEM_OOM_ADJ[j]);
12589                    item.subitems = oomProcs[j];
12590                    oomMems.add(item);
12591                }
12592            }
12593
12594            if (!brief && !oomOnly && !isCompact) {
12595                pw.println();
12596                pw.println("Total PSS by process:");
12597                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12598                pw.println();
12599            }
12600            if (!isCompact) {
12601                pw.println("Total PSS by OOM adjustment:");
12602            }
12603            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12604            if (!brief && !oomOnly) {
12605                PrintWriter out = categoryPw != null ? categoryPw : pw;
12606                if (!isCompact) {
12607                    out.println();
12608                    out.println("Total PSS by category:");
12609                }
12610                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12611            }
12612            if (!isCompact) {
12613                pw.println();
12614            }
12615            MemInfoReader memInfo = new MemInfoReader();
12616            memInfo.readMemInfo();
12617            if (!brief) {
12618                if (!isCompact) {
12619                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12620                    pw.print(" kB (status ");
12621                    switch (mLastMemoryLevel) {
12622                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12623                            pw.println("normal)");
12624                            break;
12625                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12626                            pw.println("moderate)");
12627                            break;
12628                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12629                            pw.println("low)");
12630                            break;
12631                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12632                            pw.println("critical)");
12633                            break;
12634                        default:
12635                            pw.print(mLastMemoryLevel);
12636                            pw.println(")");
12637                            break;
12638                    }
12639                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12640                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12641                            pw.print(cachedPss); pw.print(" cached pss + ");
12642                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12643                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12644                } else {
12645                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12646                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12647                            + memInfo.getFreeSizeKb()); pw.print(",");
12648                    pw.println(totalPss - cachedPss);
12649                }
12650            }
12651            if (!isCompact) {
12652                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12653                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12654                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12655                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12656                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12657                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12658                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12659                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12660                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12661                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12662                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12663            }
12664            if (!brief) {
12665                if (memInfo.getZramTotalSizeKb() != 0) {
12666                    if (!isCompact) {
12667                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12668                                pw.print(" kB physical used for ");
12669                                pw.print(memInfo.getSwapTotalSizeKb()
12670                                        - memInfo.getSwapFreeSizeKb());
12671                                pw.print(" kB in swap (");
12672                                pw.print(memInfo.getSwapTotalSizeKb());
12673                                pw.println(" kB total swap)");
12674                    } else {
12675                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12676                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12677                                pw.println(memInfo.getSwapFreeSizeKb());
12678                    }
12679                }
12680                final int[] SINGLE_LONG_FORMAT = new int[] {
12681                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12682                };
12683                long[] longOut = new long[1];
12684                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12685                        SINGLE_LONG_FORMAT, null, longOut, null);
12686                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12687                longOut[0] = 0;
12688                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12689                        SINGLE_LONG_FORMAT, null, longOut, null);
12690                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12691                longOut[0] = 0;
12692                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12693                        SINGLE_LONG_FORMAT, null, longOut, null);
12694                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12695                longOut[0] = 0;
12696                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12697                        SINGLE_LONG_FORMAT, null, longOut, null);
12698                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12699                if (!isCompact) {
12700                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12701                        pw.print("      KSM: "); pw.print(sharing);
12702                                pw.print(" kB saved from shared ");
12703                                pw.print(shared); pw.println(" kB");
12704                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12705                                pw.print(voltile); pw.println(" kB volatile");
12706                    }
12707                    pw.print("   Tuning: ");
12708                    pw.print(ActivityManager.staticGetMemoryClass());
12709                    pw.print(" (large ");
12710                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12711                    pw.print("), oom ");
12712                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12713                    pw.print(" kB");
12714                    pw.print(", restore limit ");
12715                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12716                    pw.print(" kB");
12717                    if (ActivityManager.isLowRamDeviceStatic()) {
12718                        pw.print(" (low-ram)");
12719                    }
12720                    if (ActivityManager.isHighEndGfx()) {
12721                        pw.print(" (high-end-gfx)");
12722                    }
12723                    pw.println();
12724                } else {
12725                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12726                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12727                    pw.println(voltile);
12728                    pw.print("tuning,");
12729                    pw.print(ActivityManager.staticGetMemoryClass());
12730                    pw.print(',');
12731                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12732                    pw.print(',');
12733                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12734                    if (ActivityManager.isLowRamDeviceStatic()) {
12735                        pw.print(",low-ram");
12736                    }
12737                    if (ActivityManager.isHighEndGfx()) {
12738                        pw.print(",high-end-gfx");
12739                    }
12740                    pw.println();
12741                }
12742            }
12743        }
12744    }
12745
12746    /**
12747     * Searches array of arguments for the specified string
12748     * @param args array of argument strings
12749     * @param value value to search for
12750     * @return true if the value is contained in the array
12751     */
12752    private static boolean scanArgs(String[] args, String value) {
12753        if (args != null) {
12754            for (String arg : args) {
12755                if (value.equals(arg)) {
12756                    return true;
12757                }
12758            }
12759        }
12760        return false;
12761    }
12762
12763    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12764            ContentProviderRecord cpr, boolean always) {
12765        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12766
12767        if (!inLaunching || always) {
12768            synchronized (cpr) {
12769                cpr.launchingApp = null;
12770                cpr.notifyAll();
12771            }
12772            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12773            String names[] = cpr.info.authority.split(";");
12774            for (int j = 0; j < names.length; j++) {
12775                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12776            }
12777        }
12778
12779        for (int i=0; i<cpr.connections.size(); i++) {
12780            ContentProviderConnection conn = cpr.connections.get(i);
12781            if (conn.waiting) {
12782                // If this connection is waiting for the provider, then we don't
12783                // need to mess with its process unless we are always removing
12784                // or for some reason the provider is not currently launching.
12785                if (inLaunching && !always) {
12786                    continue;
12787                }
12788            }
12789            ProcessRecord capp = conn.client;
12790            conn.dead = true;
12791            if (conn.stableCount > 0) {
12792                if (!capp.persistent && capp.thread != null
12793                        && capp.pid != 0
12794                        && capp.pid != MY_PID) {
12795                    killUnneededProcessLocked(capp, "depends on provider "
12796                            + cpr.name.flattenToShortString()
12797                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12798                }
12799            } else if (capp.thread != null && conn.provider.provider != null) {
12800                try {
12801                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12802                } catch (RemoteException e) {
12803                }
12804                // In the protocol here, we don't expect the client to correctly
12805                // clean up this connection, we'll just remove it.
12806                cpr.connections.remove(i);
12807                conn.client.conProviders.remove(conn);
12808            }
12809        }
12810
12811        if (inLaunching && always) {
12812            mLaunchingProviders.remove(cpr);
12813        }
12814        return inLaunching;
12815    }
12816
12817    /**
12818     * Main code for cleaning up a process when it has gone away.  This is
12819     * called both as a result of the process dying, or directly when stopping
12820     * a process when running in single process mode.
12821     */
12822    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12823            boolean restarting, boolean allowRestart, int index) {
12824        if (index >= 0) {
12825            removeLruProcessLocked(app);
12826            ProcessList.remove(app.pid);
12827        }
12828
12829        mProcessesToGc.remove(app);
12830        mPendingPssProcesses.remove(app);
12831
12832        // Dismiss any open dialogs.
12833        if (app.crashDialog != null && !app.forceCrashReport) {
12834            app.crashDialog.dismiss();
12835            app.crashDialog = null;
12836        }
12837        if (app.anrDialog != null) {
12838            app.anrDialog.dismiss();
12839            app.anrDialog = null;
12840        }
12841        if (app.waitDialog != null) {
12842            app.waitDialog.dismiss();
12843            app.waitDialog = null;
12844        }
12845
12846        app.crashing = false;
12847        app.notResponding = false;
12848
12849        app.resetPackageList(mProcessStats);
12850        app.unlinkDeathRecipient();
12851        app.makeInactive(mProcessStats);
12852        app.forcingToForeground = null;
12853        updateProcessForegroundLocked(app, false, false);
12854        app.foregroundActivities = false;
12855        app.hasShownUi = false;
12856        app.treatLikeActivity = false;
12857        app.hasAboveClient = false;
12858        app.hasClientActivities = false;
12859
12860        mServices.killServicesLocked(app, allowRestart);
12861
12862        boolean restart = false;
12863
12864        // Remove published content providers.
12865        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12866            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12867            final boolean always = app.bad || !allowRestart;
12868            if (removeDyingProviderLocked(app, cpr, always) || always) {
12869                // We left the provider in the launching list, need to
12870                // restart it.
12871                restart = true;
12872            }
12873
12874            cpr.provider = null;
12875            cpr.proc = null;
12876        }
12877        app.pubProviders.clear();
12878
12879        // Take care of any launching providers waiting for this process.
12880        if (checkAppInLaunchingProvidersLocked(app, false)) {
12881            restart = true;
12882        }
12883
12884        // Unregister from connected content providers.
12885        if (!app.conProviders.isEmpty()) {
12886            for (int i=0; i<app.conProviders.size(); i++) {
12887                ContentProviderConnection conn = app.conProviders.get(i);
12888                conn.provider.connections.remove(conn);
12889            }
12890            app.conProviders.clear();
12891        }
12892
12893        // At this point there may be remaining entries in mLaunchingProviders
12894        // where we were the only one waiting, so they are no longer of use.
12895        // Look for these and clean up if found.
12896        // XXX Commented out for now.  Trying to figure out a way to reproduce
12897        // the actual situation to identify what is actually going on.
12898        if (false) {
12899            for (int i=0; i<mLaunchingProviders.size(); i++) {
12900                ContentProviderRecord cpr = (ContentProviderRecord)
12901                        mLaunchingProviders.get(i);
12902                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12903                    synchronized (cpr) {
12904                        cpr.launchingApp = null;
12905                        cpr.notifyAll();
12906                    }
12907                }
12908            }
12909        }
12910
12911        skipCurrentReceiverLocked(app);
12912
12913        // Unregister any receivers.
12914        for (int i=app.receivers.size()-1; i>=0; i--) {
12915            removeReceiverLocked(app.receivers.valueAt(i));
12916        }
12917        app.receivers.clear();
12918
12919        // If the app is undergoing backup, tell the backup manager about it
12920        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12921            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12922                    + mBackupTarget.appInfo + " died during backup");
12923            try {
12924                IBackupManager bm = IBackupManager.Stub.asInterface(
12925                        ServiceManager.getService(Context.BACKUP_SERVICE));
12926                bm.agentDisconnected(app.info.packageName);
12927            } catch (RemoteException e) {
12928                // can't happen; backup manager is local
12929            }
12930        }
12931
12932        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12933            ProcessChangeItem item = mPendingProcessChanges.get(i);
12934            if (item.pid == app.pid) {
12935                mPendingProcessChanges.remove(i);
12936                mAvailProcessChanges.add(item);
12937            }
12938        }
12939        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12940
12941        // If the caller is restarting this app, then leave it in its
12942        // current lists and let the caller take care of it.
12943        if (restarting) {
12944            return;
12945        }
12946
12947        if (!app.persistent || app.isolated) {
12948            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12949                    "Removing non-persistent process during cleanup: " + app);
12950            mProcessNames.remove(app.processName, app.uid);
12951            mIsolatedProcesses.remove(app.uid);
12952            if (mHeavyWeightProcess == app) {
12953                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12954                        mHeavyWeightProcess.userId, 0));
12955                mHeavyWeightProcess = null;
12956            }
12957        } else if (!app.removed) {
12958            // This app is persistent, so we need to keep its record around.
12959            // If it is not already on the pending app list, add it there
12960            // and start a new process for it.
12961            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12962                mPersistentStartingProcesses.add(app);
12963                restart = true;
12964            }
12965        }
12966        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12967                "Clean-up removing on hold: " + app);
12968        mProcessesOnHold.remove(app);
12969
12970        if (app == mHomeProcess) {
12971            mHomeProcess = null;
12972        }
12973        if (app == mPreviousProcess) {
12974            mPreviousProcess = null;
12975        }
12976
12977        if (restart && !app.isolated) {
12978            // We have components that still need to be running in the
12979            // process, so re-launch it.
12980            mProcessNames.put(app.processName, app.uid, app);
12981            startProcessLocked(app, "restart", app.processName);
12982        } else if (app.pid > 0 && app.pid != MY_PID) {
12983            // Goodbye!
12984            boolean removed;
12985            synchronized (mPidsSelfLocked) {
12986                mPidsSelfLocked.remove(app.pid);
12987                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12988            }
12989            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12990                    app.processName, app.info.uid);
12991            if (app.isolated) {
12992                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12993            }
12994            app.setPid(0);
12995        }
12996    }
12997
12998    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12999        // Look through the content providers we are waiting to have launched,
13000        // and if any run in this process then either schedule a restart of
13001        // the process or kill the client waiting for it if this process has
13002        // gone bad.
13003        int NL = mLaunchingProviders.size();
13004        boolean restart = false;
13005        for (int i=0; i<NL; i++) {
13006            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13007            if (cpr.launchingApp == app) {
13008                if (!alwaysBad && !app.bad) {
13009                    restart = true;
13010                } else {
13011                    removeDyingProviderLocked(app, cpr, true);
13012                    // cpr should have been removed from mLaunchingProviders
13013                    NL = mLaunchingProviders.size();
13014                    i--;
13015                }
13016            }
13017        }
13018        return restart;
13019    }
13020
13021    // =========================================================
13022    // SERVICES
13023    // =========================================================
13024
13025    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13026            int flags) {
13027        enforceNotIsolatedCaller("getServices");
13028        synchronized (this) {
13029            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13030        }
13031    }
13032
13033    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13034        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13035        synchronized (this) {
13036            return mServices.getRunningServiceControlPanelLocked(name);
13037        }
13038    }
13039
13040    public ComponentName startService(IApplicationThread caller, Intent service,
13041            String resolvedType, int userId) {
13042        enforceNotIsolatedCaller("startService");
13043        // Refuse possible leaked file descriptors
13044        if (service != null && service.hasFileDescriptors() == true) {
13045            throw new IllegalArgumentException("File descriptors passed in Intent");
13046        }
13047
13048        if (DEBUG_SERVICE)
13049            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13050        synchronized(this) {
13051            final int callingPid = Binder.getCallingPid();
13052            final int callingUid = Binder.getCallingUid();
13053            final long origId = Binder.clearCallingIdentity();
13054            ComponentName res = mServices.startServiceLocked(caller, service,
13055                    resolvedType, callingPid, callingUid, userId);
13056            Binder.restoreCallingIdentity(origId);
13057            return res;
13058        }
13059    }
13060
13061    ComponentName startServiceInPackage(int uid,
13062            Intent service, String resolvedType, int userId) {
13063        synchronized(this) {
13064            if (DEBUG_SERVICE)
13065                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13066            final long origId = Binder.clearCallingIdentity();
13067            ComponentName res = mServices.startServiceLocked(null, service,
13068                    resolvedType, -1, uid, userId);
13069            Binder.restoreCallingIdentity(origId);
13070            return res;
13071        }
13072    }
13073
13074    public int stopService(IApplicationThread caller, Intent service,
13075            String resolvedType, int userId) {
13076        enforceNotIsolatedCaller("stopService");
13077        // Refuse possible leaked file descriptors
13078        if (service != null && service.hasFileDescriptors() == true) {
13079            throw new IllegalArgumentException("File descriptors passed in Intent");
13080        }
13081
13082        synchronized(this) {
13083            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13084        }
13085    }
13086
13087    public IBinder peekService(Intent service, String resolvedType) {
13088        enforceNotIsolatedCaller("peekService");
13089        // Refuse possible leaked file descriptors
13090        if (service != null && service.hasFileDescriptors() == true) {
13091            throw new IllegalArgumentException("File descriptors passed in Intent");
13092        }
13093        synchronized(this) {
13094            return mServices.peekServiceLocked(service, resolvedType);
13095        }
13096    }
13097
13098    public boolean stopServiceToken(ComponentName className, IBinder token,
13099            int startId) {
13100        synchronized(this) {
13101            return mServices.stopServiceTokenLocked(className, token, startId);
13102        }
13103    }
13104
13105    public void setServiceForeground(ComponentName className, IBinder token,
13106            int id, Notification notification, boolean removeNotification) {
13107        synchronized(this) {
13108            mServices.setServiceForegroundLocked(className, token, id, notification,
13109                    removeNotification);
13110        }
13111    }
13112
13113    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13114            boolean requireFull, String name, String callerPackage) {
13115        final int callingUserId = UserHandle.getUserId(callingUid);
13116        if (callingUserId != userId) {
13117            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13118                if ((requireFull || checkComponentPermission(
13119                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13120                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13121                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13122                                callingPid, callingUid, -1, true)
13123                                != PackageManager.PERMISSION_GRANTED) {
13124                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13125                        // In this case, they would like to just execute as their
13126                        // owner user instead of failing.
13127                        userId = callingUserId;
13128                    } else {
13129                        StringBuilder builder = new StringBuilder(128);
13130                        builder.append("Permission Denial: ");
13131                        builder.append(name);
13132                        if (callerPackage != null) {
13133                            builder.append(" from ");
13134                            builder.append(callerPackage);
13135                        }
13136                        builder.append(" asks to run as user ");
13137                        builder.append(userId);
13138                        builder.append(" but is calling from user ");
13139                        builder.append(UserHandle.getUserId(callingUid));
13140                        builder.append("; this requires ");
13141                        builder.append(INTERACT_ACROSS_USERS_FULL);
13142                        if (!requireFull) {
13143                            builder.append(" or ");
13144                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13145                        }
13146                        String msg = builder.toString();
13147                        Slog.w(TAG, msg);
13148                        throw new SecurityException(msg);
13149                    }
13150                }
13151            }
13152            if (userId == UserHandle.USER_CURRENT
13153                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13154                // Note that we may be accessing this outside of a lock...
13155                // shouldn't be a big deal, if this is being called outside
13156                // of a locked context there is intrinsically a race with
13157                // the value the caller will receive and someone else changing it.
13158                userId = mCurrentUserId;
13159            }
13160            if (!allowAll && userId < 0) {
13161                throw new IllegalArgumentException(
13162                        "Call does not support special user #" + userId);
13163            }
13164        }
13165        return userId;
13166    }
13167
13168    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13169            String className, int flags) {
13170        boolean result = false;
13171        // For apps that don't have pre-defined UIDs, check for permission
13172        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13173            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13174                if (ActivityManager.checkUidPermission(
13175                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13176                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13177                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13178                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13179                            + " requests FLAG_SINGLE_USER, but app does not hold "
13180                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13181                    Slog.w(TAG, msg);
13182                    throw new SecurityException(msg);
13183                }
13184                // Permission passed
13185                result = true;
13186            }
13187        } else if ("system".equals(componentProcessName)) {
13188            result = true;
13189        } else {
13190            // App with pre-defined UID, check if it's a persistent app
13191            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13192        }
13193        if (DEBUG_MU) {
13194            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13195                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13196        }
13197        return result;
13198    }
13199
13200    /**
13201     * Checks to see if the caller is in the same app as the singleton
13202     * component, or the component is in a special app. It allows special apps
13203     * to export singleton components but prevents exporting singleton
13204     * components for regular apps.
13205     */
13206    boolean isValidSingletonCall(int callingUid, int componentUid) {
13207        int componentAppId = UserHandle.getAppId(componentUid);
13208        return UserHandle.isSameApp(callingUid, componentUid)
13209                || componentAppId == Process.SYSTEM_UID
13210                || componentAppId == Process.PHONE_UID
13211                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13212                        == PackageManager.PERMISSION_GRANTED;
13213    }
13214
13215    public int bindService(IApplicationThread caller, IBinder token,
13216            Intent service, String resolvedType,
13217            IServiceConnection connection, int flags, int userId) {
13218        enforceNotIsolatedCaller("bindService");
13219        // Refuse possible leaked file descriptors
13220        if (service != null && service.hasFileDescriptors() == true) {
13221            throw new IllegalArgumentException("File descriptors passed in Intent");
13222        }
13223
13224        synchronized(this) {
13225            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13226                    connection, flags, userId);
13227        }
13228    }
13229
13230    public boolean unbindService(IServiceConnection connection) {
13231        synchronized (this) {
13232            return mServices.unbindServiceLocked(connection);
13233        }
13234    }
13235
13236    public void publishService(IBinder token, Intent intent, IBinder service) {
13237        // Refuse possible leaked file descriptors
13238        if (intent != null && intent.hasFileDescriptors() == true) {
13239            throw new IllegalArgumentException("File descriptors passed in Intent");
13240        }
13241
13242        synchronized(this) {
13243            if (!(token instanceof ServiceRecord)) {
13244                throw new IllegalArgumentException("Invalid service token");
13245            }
13246            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13247        }
13248    }
13249
13250    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13251        // Refuse possible leaked file descriptors
13252        if (intent != null && intent.hasFileDescriptors() == true) {
13253            throw new IllegalArgumentException("File descriptors passed in Intent");
13254        }
13255
13256        synchronized(this) {
13257            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13258        }
13259    }
13260
13261    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13262        synchronized(this) {
13263            if (!(token instanceof ServiceRecord)) {
13264                throw new IllegalArgumentException("Invalid service token");
13265            }
13266            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13267        }
13268    }
13269
13270    // =========================================================
13271    // BACKUP AND RESTORE
13272    // =========================================================
13273
13274    // Cause the target app to be launched if necessary and its backup agent
13275    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13276    // activity manager to announce its creation.
13277    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13278        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13279        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13280
13281        synchronized(this) {
13282            // !!! TODO: currently no check here that we're already bound
13283            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13284            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13285            synchronized (stats) {
13286                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13287            }
13288
13289            // Backup agent is now in use, its package can't be stopped.
13290            try {
13291                AppGlobals.getPackageManager().setPackageStoppedState(
13292                        app.packageName, false, UserHandle.getUserId(app.uid));
13293            } catch (RemoteException e) {
13294            } catch (IllegalArgumentException e) {
13295                Slog.w(TAG, "Failed trying to unstop package "
13296                        + app.packageName + ": " + e);
13297            }
13298
13299            BackupRecord r = new BackupRecord(ss, app, backupMode);
13300            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13301                    ? new ComponentName(app.packageName, app.backupAgentName)
13302                    : new ComponentName("android", "FullBackupAgent");
13303            // startProcessLocked() returns existing proc's record if it's already running
13304            ProcessRecord proc = startProcessLocked(app.processName, app,
13305                    false, 0, "backup", hostingName, false, false, false);
13306            if (proc == null) {
13307                Slog.e(TAG, "Unable to start backup agent process " + r);
13308                return false;
13309            }
13310
13311            r.app = proc;
13312            mBackupTarget = r;
13313            mBackupAppName = app.packageName;
13314
13315            // Try not to kill the process during backup
13316            updateOomAdjLocked(proc);
13317
13318            // If the process is already attached, schedule the creation of the backup agent now.
13319            // If it is not yet live, this will be done when it attaches to the framework.
13320            if (proc.thread != null) {
13321                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13322                try {
13323                    proc.thread.scheduleCreateBackupAgent(app,
13324                            compatibilityInfoForPackageLocked(app), backupMode);
13325                } catch (RemoteException e) {
13326                    // Will time out on the backup manager side
13327                }
13328            } else {
13329                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13330            }
13331            // Invariants: at this point, the target app process exists and the application
13332            // is either already running or in the process of coming up.  mBackupTarget and
13333            // mBackupAppName describe the app, so that when it binds back to the AM we
13334            // know that it's scheduled for a backup-agent operation.
13335        }
13336
13337        return true;
13338    }
13339
13340    @Override
13341    public void clearPendingBackup() {
13342        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13343        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13344
13345        synchronized (this) {
13346            mBackupTarget = null;
13347            mBackupAppName = null;
13348        }
13349    }
13350
13351    // A backup agent has just come up
13352    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13353        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13354                + " = " + agent);
13355
13356        synchronized(this) {
13357            if (!agentPackageName.equals(mBackupAppName)) {
13358                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13359                return;
13360            }
13361        }
13362
13363        long oldIdent = Binder.clearCallingIdentity();
13364        try {
13365            IBackupManager bm = IBackupManager.Stub.asInterface(
13366                    ServiceManager.getService(Context.BACKUP_SERVICE));
13367            bm.agentConnected(agentPackageName, agent);
13368        } catch (RemoteException e) {
13369            // can't happen; the backup manager service is local
13370        } catch (Exception e) {
13371            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13372            e.printStackTrace();
13373        } finally {
13374            Binder.restoreCallingIdentity(oldIdent);
13375        }
13376    }
13377
13378    // done with this agent
13379    public void unbindBackupAgent(ApplicationInfo appInfo) {
13380        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13381        if (appInfo == null) {
13382            Slog.w(TAG, "unbind backup agent for null app");
13383            return;
13384        }
13385
13386        synchronized(this) {
13387            try {
13388                if (mBackupAppName == null) {
13389                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13390                    return;
13391                }
13392
13393                if (!mBackupAppName.equals(appInfo.packageName)) {
13394                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13395                    return;
13396                }
13397
13398                // Not backing this app up any more; reset its OOM adjustment
13399                final ProcessRecord proc = mBackupTarget.app;
13400                updateOomAdjLocked(proc);
13401
13402                // If the app crashed during backup, 'thread' will be null here
13403                if (proc.thread != null) {
13404                    try {
13405                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13406                                compatibilityInfoForPackageLocked(appInfo));
13407                    } catch (Exception e) {
13408                        Slog.e(TAG, "Exception when unbinding backup agent:");
13409                        e.printStackTrace();
13410                    }
13411                }
13412            } finally {
13413                mBackupTarget = null;
13414                mBackupAppName = null;
13415            }
13416        }
13417    }
13418    // =========================================================
13419    // BROADCASTS
13420    // =========================================================
13421
13422    private final List getStickiesLocked(String action, IntentFilter filter,
13423            List cur, int userId) {
13424        final ContentResolver resolver = mContext.getContentResolver();
13425        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13426        if (stickies == null) {
13427            return cur;
13428        }
13429        final ArrayList<Intent> list = stickies.get(action);
13430        if (list == null) {
13431            return cur;
13432        }
13433        int N = list.size();
13434        for (int i=0; i<N; i++) {
13435            Intent intent = list.get(i);
13436            if (filter.match(resolver, intent, true, TAG) >= 0) {
13437                if (cur == null) {
13438                    cur = new ArrayList<Intent>();
13439                }
13440                cur.add(intent);
13441            }
13442        }
13443        return cur;
13444    }
13445
13446    boolean isPendingBroadcastProcessLocked(int pid) {
13447        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13448                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13449    }
13450
13451    void skipPendingBroadcastLocked(int pid) {
13452            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13453            for (BroadcastQueue queue : mBroadcastQueues) {
13454                queue.skipPendingBroadcastLocked(pid);
13455            }
13456    }
13457
13458    // The app just attached; send any pending broadcasts that it should receive
13459    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13460        boolean didSomething = false;
13461        for (BroadcastQueue queue : mBroadcastQueues) {
13462            didSomething |= queue.sendPendingBroadcastsLocked(app);
13463        }
13464        return didSomething;
13465    }
13466
13467    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13468            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13469        enforceNotIsolatedCaller("registerReceiver");
13470        int callingUid;
13471        int callingPid;
13472        synchronized(this) {
13473            ProcessRecord callerApp = null;
13474            if (caller != null) {
13475                callerApp = getRecordForAppLocked(caller);
13476                if (callerApp == null) {
13477                    throw new SecurityException(
13478                            "Unable to find app for caller " + caller
13479                            + " (pid=" + Binder.getCallingPid()
13480                            + ") when registering receiver " + receiver);
13481                }
13482                if (callerApp.info.uid != Process.SYSTEM_UID &&
13483                        !callerApp.pkgList.containsKey(callerPackage) &&
13484                        !"android".equals(callerPackage)) {
13485                    throw new SecurityException("Given caller package " + callerPackage
13486                            + " is not running in process " + callerApp);
13487                }
13488                callingUid = callerApp.info.uid;
13489                callingPid = callerApp.pid;
13490            } else {
13491                callerPackage = null;
13492                callingUid = Binder.getCallingUid();
13493                callingPid = Binder.getCallingPid();
13494            }
13495
13496            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13497                    true, true, "registerReceiver", callerPackage);
13498
13499            List allSticky = null;
13500
13501            // Look for any matching sticky broadcasts...
13502            Iterator actions = filter.actionsIterator();
13503            if (actions != null) {
13504                while (actions.hasNext()) {
13505                    String action = (String)actions.next();
13506                    allSticky = getStickiesLocked(action, filter, allSticky,
13507                            UserHandle.USER_ALL);
13508                    allSticky = getStickiesLocked(action, filter, allSticky,
13509                            UserHandle.getUserId(callingUid));
13510                }
13511            } else {
13512                allSticky = getStickiesLocked(null, filter, allSticky,
13513                        UserHandle.USER_ALL);
13514                allSticky = getStickiesLocked(null, filter, allSticky,
13515                        UserHandle.getUserId(callingUid));
13516            }
13517
13518            // The first sticky in the list is returned directly back to
13519            // the client.
13520            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13521
13522            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13523                    + ": " + sticky);
13524
13525            if (receiver == null) {
13526                return sticky;
13527            }
13528
13529            ReceiverList rl
13530                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13531            if (rl == null) {
13532                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13533                        userId, receiver);
13534                if (rl.app != null) {
13535                    rl.app.receivers.add(rl);
13536                } else {
13537                    try {
13538                        receiver.asBinder().linkToDeath(rl, 0);
13539                    } catch (RemoteException e) {
13540                        return sticky;
13541                    }
13542                    rl.linkedToDeath = true;
13543                }
13544                mRegisteredReceivers.put(receiver.asBinder(), rl);
13545            } else if (rl.uid != callingUid) {
13546                throw new IllegalArgumentException(
13547                        "Receiver requested to register for uid " + callingUid
13548                        + " was previously registered for uid " + rl.uid);
13549            } else if (rl.pid != callingPid) {
13550                throw new IllegalArgumentException(
13551                        "Receiver requested to register for pid " + callingPid
13552                        + " was previously registered for pid " + rl.pid);
13553            } else if (rl.userId != userId) {
13554                throw new IllegalArgumentException(
13555                        "Receiver requested to register for user " + userId
13556                        + " was previously registered for user " + rl.userId);
13557            }
13558            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13559                    permission, callingUid, userId);
13560            rl.add(bf);
13561            if (!bf.debugCheck()) {
13562                Slog.w(TAG, "==> For Dynamic broadast");
13563            }
13564            mReceiverResolver.addFilter(bf);
13565
13566            // Enqueue broadcasts for all existing stickies that match
13567            // this filter.
13568            if (allSticky != null) {
13569                ArrayList receivers = new ArrayList();
13570                receivers.add(bf);
13571
13572                int N = allSticky.size();
13573                for (int i=0; i<N; i++) {
13574                    Intent intent = (Intent)allSticky.get(i);
13575                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13576                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13577                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13578                            null, null, false, true, true, -1);
13579                    queue.enqueueParallelBroadcastLocked(r);
13580                    queue.scheduleBroadcastsLocked();
13581                }
13582            }
13583
13584            return sticky;
13585        }
13586    }
13587
13588    public void unregisterReceiver(IIntentReceiver receiver) {
13589        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13590
13591        final long origId = Binder.clearCallingIdentity();
13592        try {
13593            boolean doTrim = false;
13594
13595            synchronized(this) {
13596                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13597                if (rl != null) {
13598                    if (rl.curBroadcast != null) {
13599                        BroadcastRecord r = rl.curBroadcast;
13600                        final boolean doNext = finishReceiverLocked(
13601                                receiver.asBinder(), r.resultCode, r.resultData,
13602                                r.resultExtras, r.resultAbort);
13603                        if (doNext) {
13604                            doTrim = true;
13605                            r.queue.processNextBroadcast(false);
13606                        }
13607                    }
13608
13609                    if (rl.app != null) {
13610                        rl.app.receivers.remove(rl);
13611                    }
13612                    removeReceiverLocked(rl);
13613                    if (rl.linkedToDeath) {
13614                        rl.linkedToDeath = false;
13615                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13616                    }
13617                }
13618            }
13619
13620            // If we actually concluded any broadcasts, we might now be able
13621            // to trim the recipients' apps from our working set
13622            if (doTrim) {
13623                trimApplications();
13624                return;
13625            }
13626
13627        } finally {
13628            Binder.restoreCallingIdentity(origId);
13629        }
13630    }
13631
13632    void removeReceiverLocked(ReceiverList rl) {
13633        mRegisteredReceivers.remove(rl.receiver.asBinder());
13634        int N = rl.size();
13635        for (int i=0; i<N; i++) {
13636            mReceiverResolver.removeFilter(rl.get(i));
13637        }
13638    }
13639
13640    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13641        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13642            ProcessRecord r = mLruProcesses.get(i);
13643            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13644                try {
13645                    r.thread.dispatchPackageBroadcast(cmd, packages);
13646                } catch (RemoteException ex) {
13647                }
13648            }
13649        }
13650    }
13651
13652    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13653            int[] users) {
13654        List<ResolveInfo> receivers = null;
13655        try {
13656            HashSet<ComponentName> singleUserReceivers = null;
13657            boolean scannedFirstReceivers = false;
13658            for (int user : users) {
13659                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13660                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13661                if (user != 0 && newReceivers != null) {
13662                    // If this is not the primary user, we need to check for
13663                    // any receivers that should be filtered out.
13664                    for (int i=0; i<newReceivers.size(); i++) {
13665                        ResolveInfo ri = newReceivers.get(i);
13666                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13667                            newReceivers.remove(i);
13668                            i--;
13669                        }
13670                    }
13671                }
13672                if (newReceivers != null && newReceivers.size() == 0) {
13673                    newReceivers = null;
13674                }
13675                if (receivers == null) {
13676                    receivers = newReceivers;
13677                } else if (newReceivers != null) {
13678                    // We need to concatenate the additional receivers
13679                    // found with what we have do far.  This would be easy,
13680                    // but we also need to de-dup any receivers that are
13681                    // singleUser.
13682                    if (!scannedFirstReceivers) {
13683                        // Collect any single user receivers we had already retrieved.
13684                        scannedFirstReceivers = true;
13685                        for (int i=0; i<receivers.size(); i++) {
13686                            ResolveInfo ri = receivers.get(i);
13687                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13688                                ComponentName cn = new ComponentName(
13689                                        ri.activityInfo.packageName, ri.activityInfo.name);
13690                                if (singleUserReceivers == null) {
13691                                    singleUserReceivers = new HashSet<ComponentName>();
13692                                }
13693                                singleUserReceivers.add(cn);
13694                            }
13695                        }
13696                    }
13697                    // Add the new results to the existing results, tracking
13698                    // and de-dupping single user receivers.
13699                    for (int i=0; i<newReceivers.size(); i++) {
13700                        ResolveInfo ri = newReceivers.get(i);
13701                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13702                            ComponentName cn = new ComponentName(
13703                                    ri.activityInfo.packageName, ri.activityInfo.name);
13704                            if (singleUserReceivers == null) {
13705                                singleUserReceivers = new HashSet<ComponentName>();
13706                            }
13707                            if (!singleUserReceivers.contains(cn)) {
13708                                singleUserReceivers.add(cn);
13709                                receivers.add(ri);
13710                            }
13711                        } else {
13712                            receivers.add(ri);
13713                        }
13714                    }
13715                }
13716            }
13717        } catch (RemoteException ex) {
13718            // pm is in same process, this will never happen.
13719        }
13720        return receivers;
13721    }
13722
13723    private final int broadcastIntentLocked(ProcessRecord callerApp,
13724            String callerPackage, Intent intent, String resolvedType,
13725            IIntentReceiver resultTo, int resultCode, String resultData,
13726            Bundle map, String requiredPermission, int appOp,
13727            boolean ordered, boolean sticky, int callingPid, int callingUid,
13728            int userId) {
13729        intent = new Intent(intent);
13730
13731        // By default broadcasts do not go to stopped apps.
13732        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13733
13734        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13735            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13736            + " ordered=" + ordered + " userid=" + userId);
13737        if ((resultTo != null) && !ordered) {
13738            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13739        }
13740
13741        userId = handleIncomingUser(callingPid, callingUid, userId,
13742                true, false, "broadcast", callerPackage);
13743
13744        // Make sure that the user who is receiving this broadcast is started.
13745        // If not, we will just skip it.
13746        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13747            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13748                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13749                Slog.w(TAG, "Skipping broadcast of " + intent
13750                        + ": user " + userId + " is stopped");
13751                return ActivityManager.BROADCAST_SUCCESS;
13752            }
13753        }
13754
13755        /*
13756         * Prevent non-system code (defined here to be non-persistent
13757         * processes) from sending protected broadcasts.
13758         */
13759        int callingAppId = UserHandle.getAppId(callingUid);
13760        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13761                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13762                || callingUid == 0) {
13763            // Always okay.
13764        } else if (callerApp == null || !callerApp.persistent) {
13765            try {
13766                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13767                        intent.getAction())) {
13768                    String msg = "Permission Denial: not allowed to send broadcast "
13769                            + intent.getAction() + " from pid="
13770                            + callingPid + ", uid=" + callingUid;
13771                    Slog.w(TAG, msg);
13772                    throw new SecurityException(msg);
13773                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13774                    // Special case for compatibility: we don't want apps to send this,
13775                    // but historically it has not been protected and apps may be using it
13776                    // to poke their own app widget.  So, instead of making it protected,
13777                    // just limit it to the caller.
13778                    if (callerApp == null) {
13779                        String msg = "Permission Denial: not allowed to send broadcast "
13780                                + intent.getAction() + " from unknown caller.";
13781                        Slog.w(TAG, msg);
13782                        throw new SecurityException(msg);
13783                    } else if (intent.getComponent() != null) {
13784                        // They are good enough to send to an explicit component...  verify
13785                        // it is being sent to the calling app.
13786                        if (!intent.getComponent().getPackageName().equals(
13787                                callerApp.info.packageName)) {
13788                            String msg = "Permission Denial: not allowed to send broadcast "
13789                                    + intent.getAction() + " to "
13790                                    + intent.getComponent().getPackageName() + " from "
13791                                    + callerApp.info.packageName;
13792                            Slog.w(TAG, msg);
13793                            throw new SecurityException(msg);
13794                        }
13795                    } else {
13796                        // Limit broadcast to their own package.
13797                        intent.setPackage(callerApp.info.packageName);
13798                    }
13799                }
13800            } catch (RemoteException e) {
13801                Slog.w(TAG, "Remote exception", e);
13802                return ActivityManager.BROADCAST_SUCCESS;
13803            }
13804        }
13805
13806        // Handle special intents: if this broadcast is from the package
13807        // manager about a package being removed, we need to remove all of
13808        // its activities from the history stack.
13809        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13810                intent.getAction());
13811        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13812                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13813                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13814                || uidRemoved) {
13815            if (checkComponentPermission(
13816                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13817                    callingPid, callingUid, -1, true)
13818                    == PackageManager.PERMISSION_GRANTED) {
13819                if (uidRemoved) {
13820                    final Bundle intentExtras = intent.getExtras();
13821                    final int uid = intentExtras != null
13822                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13823                    if (uid >= 0) {
13824                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13825                        synchronized (bs) {
13826                            bs.removeUidStatsLocked(uid);
13827                        }
13828                        mAppOpsService.uidRemoved(uid);
13829                    }
13830                } else {
13831                    // If resources are unavailable just force stop all
13832                    // those packages and flush the attribute cache as well.
13833                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13834                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13835                        if (list != null && (list.length > 0)) {
13836                            for (String pkg : list) {
13837                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13838                                        "storage unmount");
13839                            }
13840                            sendPackageBroadcastLocked(
13841                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13842                        }
13843                    } else {
13844                        Uri data = intent.getData();
13845                        String ssp;
13846                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13847                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13848                                    intent.getAction());
13849                            boolean fullUninstall = removed &&
13850                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13851                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13852                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13853                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13854                                        false, fullUninstall, userId,
13855                                        removed ? "pkg removed" : "pkg changed");
13856                            }
13857                            if (removed) {
13858                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13859                                        new String[] {ssp}, userId);
13860                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13861                                    mAppOpsService.packageRemoved(
13862                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13863
13864                                    // Remove all permissions granted from/to this package
13865                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13866                                }
13867                            }
13868                        }
13869                    }
13870                }
13871            } else {
13872                String msg = "Permission Denial: " + intent.getAction()
13873                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13874                        + ", uid=" + callingUid + ")"
13875                        + " requires "
13876                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13877                Slog.w(TAG, msg);
13878                throw new SecurityException(msg);
13879            }
13880
13881        // Special case for adding a package: by default turn on compatibility
13882        // mode.
13883        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13884            Uri data = intent.getData();
13885            String ssp;
13886            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13887                mCompatModePackages.handlePackageAddedLocked(ssp,
13888                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13889            }
13890        }
13891
13892        /*
13893         * If this is the time zone changed action, queue up a message that will reset the timezone
13894         * of all currently running processes. This message will get queued up before the broadcast
13895         * happens.
13896         */
13897        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13898            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13899        }
13900
13901        /*
13902         * If the user set the time, let all running processes know.
13903         */
13904        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13905            final int is24Hour = intent.getBooleanExtra(
13906                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13907            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13908        }
13909
13910        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13911            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13912        }
13913
13914        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13915            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13916            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13917        }
13918
13919        // Add to the sticky list if requested.
13920        if (sticky) {
13921            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13922                    callingPid, callingUid)
13923                    != PackageManager.PERMISSION_GRANTED) {
13924                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13925                        + callingPid + ", uid=" + callingUid
13926                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13927                Slog.w(TAG, msg);
13928                throw new SecurityException(msg);
13929            }
13930            if (requiredPermission != null) {
13931                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13932                        + " and enforce permission " + requiredPermission);
13933                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13934            }
13935            if (intent.getComponent() != null) {
13936                throw new SecurityException(
13937                        "Sticky broadcasts can't target a specific component");
13938            }
13939            // We use userId directly here, since the "all" target is maintained
13940            // as a separate set of sticky broadcasts.
13941            if (userId != UserHandle.USER_ALL) {
13942                // But first, if this is not a broadcast to all users, then
13943                // make sure it doesn't conflict with an existing broadcast to
13944                // all users.
13945                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13946                        UserHandle.USER_ALL);
13947                if (stickies != null) {
13948                    ArrayList<Intent> list = stickies.get(intent.getAction());
13949                    if (list != null) {
13950                        int N = list.size();
13951                        int i;
13952                        for (i=0; i<N; i++) {
13953                            if (intent.filterEquals(list.get(i))) {
13954                                throw new IllegalArgumentException(
13955                                        "Sticky broadcast " + intent + " for user "
13956                                        + userId + " conflicts with existing global broadcast");
13957                            }
13958                        }
13959                    }
13960                }
13961            }
13962            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13963            if (stickies == null) {
13964                stickies = new ArrayMap<String, ArrayList<Intent>>();
13965                mStickyBroadcasts.put(userId, stickies);
13966            }
13967            ArrayList<Intent> list = stickies.get(intent.getAction());
13968            if (list == null) {
13969                list = new ArrayList<Intent>();
13970                stickies.put(intent.getAction(), list);
13971            }
13972            int N = list.size();
13973            int i;
13974            for (i=0; i<N; i++) {
13975                if (intent.filterEquals(list.get(i))) {
13976                    // This sticky already exists, replace it.
13977                    list.set(i, new Intent(intent));
13978                    break;
13979                }
13980            }
13981            if (i >= N) {
13982                list.add(new Intent(intent));
13983            }
13984        }
13985
13986        int[] users;
13987        if (userId == UserHandle.USER_ALL) {
13988            // Caller wants broadcast to go to all started users.
13989            users = mStartedUserArray;
13990        } else {
13991            // Caller wants broadcast to go to one specific user.
13992            users = new int[] {userId};
13993        }
13994
13995        // Figure out who all will receive this broadcast.
13996        List receivers = null;
13997        List<BroadcastFilter> registeredReceivers = null;
13998        // Need to resolve the intent to interested receivers...
13999        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14000                 == 0) {
14001            receivers = collectReceiverComponents(intent, resolvedType, users);
14002        }
14003        if (intent.getComponent() == null) {
14004            registeredReceivers = mReceiverResolver.queryIntent(intent,
14005                    resolvedType, false, userId);
14006        }
14007
14008        final boolean replacePending =
14009                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14010
14011        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14012                + " replacePending=" + replacePending);
14013
14014        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14015        if (!ordered && NR > 0) {
14016            // If we are not serializing this broadcast, then send the
14017            // registered receivers separately so they don't wait for the
14018            // components to be launched.
14019            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14020            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14021                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14022                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14023                    ordered, sticky, false, userId);
14024            if (DEBUG_BROADCAST) Slog.v(
14025                    TAG, "Enqueueing parallel broadcast " + r);
14026            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14027            if (!replaced) {
14028                queue.enqueueParallelBroadcastLocked(r);
14029                queue.scheduleBroadcastsLocked();
14030            }
14031            registeredReceivers = null;
14032            NR = 0;
14033        }
14034
14035        // Merge into one list.
14036        int ir = 0;
14037        if (receivers != null) {
14038            // A special case for PACKAGE_ADDED: do not allow the package
14039            // being added to see this broadcast.  This prevents them from
14040            // using this as a back door to get run as soon as they are
14041            // installed.  Maybe in the future we want to have a special install
14042            // broadcast or such for apps, but we'd like to deliberately make
14043            // this decision.
14044            String skipPackages[] = null;
14045            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14046                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14047                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14048                Uri data = intent.getData();
14049                if (data != null) {
14050                    String pkgName = data.getSchemeSpecificPart();
14051                    if (pkgName != null) {
14052                        skipPackages = new String[] { pkgName };
14053                    }
14054                }
14055            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14056                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14057            }
14058            if (skipPackages != null && (skipPackages.length > 0)) {
14059                for (String skipPackage : skipPackages) {
14060                    if (skipPackage != null) {
14061                        int NT = receivers.size();
14062                        for (int it=0; it<NT; it++) {
14063                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14064                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14065                                receivers.remove(it);
14066                                it--;
14067                                NT--;
14068                            }
14069                        }
14070                    }
14071                }
14072            }
14073
14074            int NT = receivers != null ? receivers.size() : 0;
14075            int it = 0;
14076            ResolveInfo curt = null;
14077            BroadcastFilter curr = null;
14078            while (it < NT && ir < NR) {
14079                if (curt == null) {
14080                    curt = (ResolveInfo)receivers.get(it);
14081                }
14082                if (curr == null) {
14083                    curr = registeredReceivers.get(ir);
14084                }
14085                if (curr.getPriority() >= curt.priority) {
14086                    // Insert this broadcast record into the final list.
14087                    receivers.add(it, curr);
14088                    ir++;
14089                    curr = null;
14090                    it++;
14091                    NT++;
14092                } else {
14093                    // Skip to the next ResolveInfo in the final list.
14094                    it++;
14095                    curt = null;
14096                }
14097            }
14098        }
14099        while (ir < NR) {
14100            if (receivers == null) {
14101                receivers = new ArrayList();
14102            }
14103            receivers.add(registeredReceivers.get(ir));
14104            ir++;
14105        }
14106
14107        if ((receivers != null && receivers.size() > 0)
14108                || resultTo != null) {
14109            BroadcastQueue queue = broadcastQueueForIntent(intent);
14110            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14111                    callerPackage, callingPid, callingUid, resolvedType,
14112                    requiredPermission, appOp, receivers, resultTo, resultCode,
14113                    resultData, map, ordered, sticky, false, userId);
14114            if (DEBUG_BROADCAST) Slog.v(
14115                    TAG, "Enqueueing ordered broadcast " + r
14116                    + ": prev had " + queue.mOrderedBroadcasts.size());
14117            if (DEBUG_BROADCAST) {
14118                int seq = r.intent.getIntExtra("seq", -1);
14119                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14120            }
14121            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14122            if (!replaced) {
14123                queue.enqueueOrderedBroadcastLocked(r);
14124                queue.scheduleBroadcastsLocked();
14125            }
14126        }
14127
14128        return ActivityManager.BROADCAST_SUCCESS;
14129    }
14130
14131    final Intent verifyBroadcastLocked(Intent intent) {
14132        // Refuse possible leaked file descriptors
14133        if (intent != null && intent.hasFileDescriptors() == true) {
14134            throw new IllegalArgumentException("File descriptors passed in Intent");
14135        }
14136
14137        int flags = intent.getFlags();
14138
14139        if (!mProcessesReady) {
14140            // if the caller really truly claims to know what they're doing, go
14141            // ahead and allow the broadcast without launching any receivers
14142            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14143                intent = new Intent(intent);
14144                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14145            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14146                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14147                        + " before boot completion");
14148                throw new IllegalStateException("Cannot broadcast before boot completed");
14149            }
14150        }
14151
14152        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14153            throw new IllegalArgumentException(
14154                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14155        }
14156
14157        return intent;
14158    }
14159
14160    public final int broadcastIntent(IApplicationThread caller,
14161            Intent intent, String resolvedType, IIntentReceiver resultTo,
14162            int resultCode, String resultData, Bundle map,
14163            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14164        enforceNotIsolatedCaller("broadcastIntent");
14165        synchronized(this) {
14166            intent = verifyBroadcastLocked(intent);
14167
14168            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14169            final int callingPid = Binder.getCallingPid();
14170            final int callingUid = Binder.getCallingUid();
14171            final long origId = Binder.clearCallingIdentity();
14172            int res = broadcastIntentLocked(callerApp,
14173                    callerApp != null ? callerApp.info.packageName : null,
14174                    intent, resolvedType, resultTo,
14175                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14176                    callingPid, callingUid, userId);
14177            Binder.restoreCallingIdentity(origId);
14178            return res;
14179        }
14180    }
14181
14182    int broadcastIntentInPackage(String packageName, int uid,
14183            Intent intent, String resolvedType, IIntentReceiver resultTo,
14184            int resultCode, String resultData, Bundle map,
14185            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14186        synchronized(this) {
14187            intent = verifyBroadcastLocked(intent);
14188
14189            final long origId = Binder.clearCallingIdentity();
14190            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14191                    resultTo, resultCode, resultData, map, requiredPermission,
14192                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14193            Binder.restoreCallingIdentity(origId);
14194            return res;
14195        }
14196    }
14197
14198    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14199        // Refuse possible leaked file descriptors
14200        if (intent != null && intent.hasFileDescriptors() == true) {
14201            throw new IllegalArgumentException("File descriptors passed in Intent");
14202        }
14203
14204        userId = handleIncomingUser(Binder.getCallingPid(),
14205                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14206
14207        synchronized(this) {
14208            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14209                    != PackageManager.PERMISSION_GRANTED) {
14210                String msg = "Permission Denial: unbroadcastIntent() from pid="
14211                        + Binder.getCallingPid()
14212                        + ", uid=" + Binder.getCallingUid()
14213                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14214                Slog.w(TAG, msg);
14215                throw new SecurityException(msg);
14216            }
14217            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14218            if (stickies != null) {
14219                ArrayList<Intent> list = stickies.get(intent.getAction());
14220                if (list != null) {
14221                    int N = list.size();
14222                    int i;
14223                    for (i=0; i<N; i++) {
14224                        if (intent.filterEquals(list.get(i))) {
14225                            list.remove(i);
14226                            break;
14227                        }
14228                    }
14229                    if (list.size() <= 0) {
14230                        stickies.remove(intent.getAction());
14231                    }
14232                }
14233                if (stickies.size() <= 0) {
14234                    mStickyBroadcasts.remove(userId);
14235                }
14236            }
14237        }
14238    }
14239
14240    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14241            String resultData, Bundle resultExtras, boolean resultAbort) {
14242        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14243        if (r == null) {
14244            Slog.w(TAG, "finishReceiver called but not found on queue");
14245            return false;
14246        }
14247
14248        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14249    }
14250
14251    void backgroundServicesFinishedLocked(int userId) {
14252        for (BroadcastQueue queue : mBroadcastQueues) {
14253            queue.backgroundServicesFinishedLocked(userId);
14254        }
14255    }
14256
14257    public void finishReceiver(IBinder who, int resultCode, String resultData,
14258            Bundle resultExtras, boolean resultAbort) {
14259        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14260
14261        // Refuse possible leaked file descriptors
14262        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14263            throw new IllegalArgumentException("File descriptors passed in Bundle");
14264        }
14265
14266        final long origId = Binder.clearCallingIdentity();
14267        try {
14268            boolean doNext = false;
14269            BroadcastRecord r;
14270
14271            synchronized(this) {
14272                r = broadcastRecordForReceiverLocked(who);
14273                if (r != null) {
14274                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14275                        resultData, resultExtras, resultAbort, true);
14276                }
14277            }
14278
14279            if (doNext) {
14280                r.queue.processNextBroadcast(false);
14281            }
14282            trimApplications();
14283        } finally {
14284            Binder.restoreCallingIdentity(origId);
14285        }
14286    }
14287
14288    // =========================================================
14289    // INSTRUMENTATION
14290    // =========================================================
14291
14292    public boolean startInstrumentation(ComponentName className,
14293            String profileFile, int flags, Bundle arguments,
14294            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14295            int userId) {
14296        enforceNotIsolatedCaller("startInstrumentation");
14297        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14298                userId, false, true, "startInstrumentation", null);
14299        // Refuse possible leaked file descriptors
14300        if (arguments != null && arguments.hasFileDescriptors()) {
14301            throw new IllegalArgumentException("File descriptors passed in Bundle");
14302        }
14303
14304        synchronized(this) {
14305            InstrumentationInfo ii = null;
14306            ApplicationInfo ai = null;
14307            try {
14308                ii = mContext.getPackageManager().getInstrumentationInfo(
14309                    className, STOCK_PM_FLAGS);
14310                ai = AppGlobals.getPackageManager().getApplicationInfo(
14311                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14312            } catch (PackageManager.NameNotFoundException e) {
14313            } catch (RemoteException e) {
14314            }
14315            if (ii == null) {
14316                reportStartInstrumentationFailure(watcher, className,
14317                        "Unable to find instrumentation info for: " + className);
14318                return false;
14319            }
14320            if (ai == null) {
14321                reportStartInstrumentationFailure(watcher, className,
14322                        "Unable to find instrumentation target package: " + ii.targetPackage);
14323                return false;
14324            }
14325
14326            int match = mContext.getPackageManager().checkSignatures(
14327                    ii.targetPackage, ii.packageName);
14328            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14329                String msg = "Permission Denial: starting instrumentation "
14330                        + className + " from pid="
14331                        + Binder.getCallingPid()
14332                        + ", uid=" + Binder.getCallingPid()
14333                        + " not allowed because package " + ii.packageName
14334                        + " does not have a signature matching the target "
14335                        + ii.targetPackage;
14336                reportStartInstrumentationFailure(watcher, className, msg);
14337                throw new SecurityException(msg);
14338            }
14339
14340            final long origId = Binder.clearCallingIdentity();
14341            // Instrumentation can kill and relaunch even persistent processes
14342            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14343                    "start instr");
14344            ProcessRecord app = addAppLocked(ai, false);
14345            app.instrumentationClass = className;
14346            app.instrumentationInfo = ai;
14347            app.instrumentationProfileFile = profileFile;
14348            app.instrumentationArguments = arguments;
14349            app.instrumentationWatcher = watcher;
14350            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14351            app.instrumentationResultClass = className;
14352            Binder.restoreCallingIdentity(origId);
14353        }
14354
14355        return true;
14356    }
14357
14358    /**
14359     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14360     * error to the logs, but if somebody is watching, send the report there too.  This enables
14361     * the "am" command to report errors with more information.
14362     *
14363     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14364     * @param cn The component name of the instrumentation.
14365     * @param report The error report.
14366     */
14367    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14368            ComponentName cn, String report) {
14369        Slog.w(TAG, report);
14370        try {
14371            if (watcher != null) {
14372                Bundle results = new Bundle();
14373                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14374                results.putString("Error", report);
14375                watcher.instrumentationStatus(cn, -1, results);
14376            }
14377        } catch (RemoteException e) {
14378            Slog.w(TAG, e);
14379        }
14380    }
14381
14382    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14383        if (app.instrumentationWatcher != null) {
14384            try {
14385                // NOTE:  IInstrumentationWatcher *must* be oneway here
14386                app.instrumentationWatcher.instrumentationFinished(
14387                    app.instrumentationClass,
14388                    resultCode,
14389                    results);
14390            } catch (RemoteException e) {
14391            }
14392        }
14393        if (app.instrumentationUiAutomationConnection != null) {
14394            try {
14395                app.instrumentationUiAutomationConnection.shutdown();
14396            } catch (RemoteException re) {
14397                /* ignore */
14398            }
14399            // Only a UiAutomation can set this flag and now that
14400            // it is finished we make sure it is reset to its default.
14401            mUserIsMonkey = false;
14402        }
14403        app.instrumentationWatcher = null;
14404        app.instrumentationUiAutomationConnection = null;
14405        app.instrumentationClass = null;
14406        app.instrumentationInfo = null;
14407        app.instrumentationProfileFile = null;
14408        app.instrumentationArguments = null;
14409
14410        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14411                "finished inst");
14412    }
14413
14414    public void finishInstrumentation(IApplicationThread target,
14415            int resultCode, Bundle results) {
14416        int userId = UserHandle.getCallingUserId();
14417        // Refuse possible leaked file descriptors
14418        if (results != null && results.hasFileDescriptors()) {
14419            throw new IllegalArgumentException("File descriptors passed in Intent");
14420        }
14421
14422        synchronized(this) {
14423            ProcessRecord app = getRecordForAppLocked(target);
14424            if (app == null) {
14425                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14426                return;
14427            }
14428            final long origId = Binder.clearCallingIdentity();
14429            finishInstrumentationLocked(app, resultCode, results);
14430            Binder.restoreCallingIdentity(origId);
14431        }
14432    }
14433
14434    // =========================================================
14435    // CONFIGURATION
14436    // =========================================================
14437
14438    public ConfigurationInfo getDeviceConfigurationInfo() {
14439        ConfigurationInfo config = new ConfigurationInfo();
14440        synchronized (this) {
14441            config.reqTouchScreen = mConfiguration.touchscreen;
14442            config.reqKeyboardType = mConfiguration.keyboard;
14443            config.reqNavigation = mConfiguration.navigation;
14444            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14445                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14446                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14447            }
14448            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14449                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14450                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14451            }
14452            config.reqGlEsVersion = GL_ES_VERSION;
14453        }
14454        return config;
14455    }
14456
14457    ActivityStack getFocusedStack() {
14458        return mStackSupervisor.getFocusedStack();
14459    }
14460
14461    public Configuration getConfiguration() {
14462        Configuration ci;
14463        synchronized(this) {
14464            ci = new Configuration(mConfiguration);
14465        }
14466        return ci;
14467    }
14468
14469    public void updatePersistentConfiguration(Configuration values) {
14470        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14471                "updateConfiguration()");
14472        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14473                "updateConfiguration()");
14474        if (values == null) {
14475            throw new NullPointerException("Configuration must not be null");
14476        }
14477
14478        synchronized(this) {
14479            final long origId = Binder.clearCallingIdentity();
14480            updateConfigurationLocked(values, null, true, false);
14481            Binder.restoreCallingIdentity(origId);
14482        }
14483    }
14484
14485    public void updateConfiguration(Configuration values) {
14486        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14487                "updateConfiguration()");
14488
14489        synchronized(this) {
14490            if (values == null && mWindowManager != null) {
14491                // sentinel: fetch the current configuration from the window manager
14492                values = mWindowManager.computeNewConfiguration();
14493            }
14494
14495            if (mWindowManager != null) {
14496                mProcessList.applyDisplaySize(mWindowManager);
14497            }
14498
14499            final long origId = Binder.clearCallingIdentity();
14500            if (values != null) {
14501                Settings.System.clearConfiguration(values);
14502            }
14503            updateConfigurationLocked(values, null, false, false);
14504            Binder.restoreCallingIdentity(origId);
14505        }
14506    }
14507
14508    /**
14509     * Do either or both things: (1) change the current configuration, and (2)
14510     * make sure the given activity is running with the (now) current
14511     * configuration.  Returns true if the activity has been left running, or
14512     * false if <var>starting</var> is being destroyed to match the new
14513     * configuration.
14514     * @param persistent TODO
14515     */
14516    boolean updateConfigurationLocked(Configuration values,
14517            ActivityRecord starting, boolean persistent, boolean initLocale) {
14518        int changes = 0;
14519
14520        if (values != null) {
14521            Configuration newConfig = new Configuration(mConfiguration);
14522            changes = newConfig.updateFrom(values);
14523            if (changes != 0) {
14524                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14525                    Slog.i(TAG, "Updating configuration to: " + values);
14526                }
14527
14528                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14529
14530                if (values.locale != null && !initLocale) {
14531                    saveLocaleLocked(values.locale,
14532                                     !values.locale.equals(mConfiguration.locale),
14533                                     values.userSetLocale);
14534                }
14535
14536                mConfigurationSeq++;
14537                if (mConfigurationSeq <= 0) {
14538                    mConfigurationSeq = 1;
14539                }
14540                newConfig.seq = mConfigurationSeq;
14541                mConfiguration = newConfig;
14542                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14543                mUsageStatsService.noteStartConfig(newConfig);
14544
14545                final Configuration configCopy = new Configuration(mConfiguration);
14546
14547                // TODO: If our config changes, should we auto dismiss any currently
14548                // showing dialogs?
14549                mShowDialogs = shouldShowDialogs(newConfig);
14550
14551                AttributeCache ac = AttributeCache.instance();
14552                if (ac != null) {
14553                    ac.updateConfiguration(configCopy);
14554                }
14555
14556                // Make sure all resources in our process are updated
14557                // right now, so that anyone who is going to retrieve
14558                // resource values after we return will be sure to get
14559                // the new ones.  This is especially important during
14560                // boot, where the first config change needs to guarantee
14561                // all resources have that config before following boot
14562                // code is executed.
14563                mSystemThread.applyConfigurationToResources(configCopy);
14564
14565                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14566                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14567                    msg.obj = new Configuration(configCopy);
14568                    mHandler.sendMessage(msg);
14569                }
14570
14571                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14572                    ProcessRecord app = mLruProcesses.get(i);
14573                    try {
14574                        if (app.thread != null) {
14575                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14576                                    + app.processName + " new config " + mConfiguration);
14577                            app.thread.scheduleConfigurationChanged(configCopy);
14578                        }
14579                    } catch (Exception e) {
14580                    }
14581                }
14582                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14583                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14584                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14585                        | Intent.FLAG_RECEIVER_FOREGROUND);
14586                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14587                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14588                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14589                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14590                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14591                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14592                    broadcastIntentLocked(null, null, intent,
14593                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14594                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14595                }
14596            }
14597        }
14598
14599        boolean kept = true;
14600        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14601        // mainStack is null during startup.
14602        if (mainStack != null) {
14603            if (changes != 0 && starting == null) {
14604                // If the configuration changed, and the caller is not already
14605                // in the process of starting an activity, then find the top
14606                // activity to check if its configuration needs to change.
14607                starting = mainStack.topRunningActivityLocked(null);
14608            }
14609
14610            if (starting != null) {
14611                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14612                // And we need to make sure at this point that all other activities
14613                // are made visible with the correct configuration.
14614                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14615            }
14616        }
14617
14618        if (values != null && mWindowManager != null) {
14619            mWindowManager.setNewConfiguration(mConfiguration);
14620        }
14621
14622        return kept;
14623    }
14624
14625    /**
14626     * Decide based on the configuration whether we should shouw the ANR,
14627     * crash, etc dialogs.  The idea is that if there is no affordnace to
14628     * press the on-screen buttons, we shouldn't show the dialog.
14629     *
14630     * A thought: SystemUI might also want to get told about this, the Power
14631     * dialog / global actions also might want different behaviors.
14632     */
14633    private static final boolean shouldShowDialogs(Configuration config) {
14634        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14635                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14636    }
14637
14638    /**
14639     * Save the locale.  You must be inside a synchronized (this) block.
14640     */
14641    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14642        if(isDiff) {
14643            SystemProperties.set("user.language", l.getLanguage());
14644            SystemProperties.set("user.region", l.getCountry());
14645        }
14646
14647        if(isPersist) {
14648            SystemProperties.set("persist.sys.language", l.getLanguage());
14649            SystemProperties.set("persist.sys.country", l.getCountry());
14650            SystemProperties.set("persist.sys.localevar", l.getVariant());
14651        }
14652    }
14653
14654    @Override
14655    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14656        ActivityRecord srec = ActivityRecord.forToken(token);
14657        return srec != null && srec.task.affinity != null &&
14658                srec.task.affinity.equals(destAffinity);
14659    }
14660
14661    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14662            Intent resultData) {
14663
14664        synchronized (this) {
14665            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14666            if (stack != null) {
14667                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14668            }
14669            return false;
14670        }
14671    }
14672
14673    public int getLaunchedFromUid(IBinder activityToken) {
14674        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14675        if (srec == null) {
14676            return -1;
14677        }
14678        return srec.launchedFromUid;
14679    }
14680
14681    public String getLaunchedFromPackage(IBinder activityToken) {
14682        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14683        if (srec == null) {
14684            return null;
14685        }
14686        return srec.launchedFromPackage;
14687    }
14688
14689    // =========================================================
14690    // LIFETIME MANAGEMENT
14691    // =========================================================
14692
14693    // Returns which broadcast queue the app is the current [or imminent] receiver
14694    // on, or 'null' if the app is not an active broadcast recipient.
14695    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14696        BroadcastRecord r = app.curReceiver;
14697        if (r != null) {
14698            return r.queue;
14699        }
14700
14701        // It's not the current receiver, but it might be starting up to become one
14702        synchronized (this) {
14703            for (BroadcastQueue queue : mBroadcastQueues) {
14704                r = queue.mPendingBroadcast;
14705                if (r != null && r.curApp == app) {
14706                    // found it; report which queue it's in
14707                    return queue;
14708                }
14709            }
14710        }
14711
14712        return null;
14713    }
14714
14715    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14716            boolean doingAll, long now) {
14717        if (mAdjSeq == app.adjSeq) {
14718            // This adjustment has already been computed.
14719            return app.curRawAdj;
14720        }
14721
14722        if (app.thread == null) {
14723            app.adjSeq = mAdjSeq;
14724            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14725            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14726            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14727        }
14728
14729        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14730        app.adjSource = null;
14731        app.adjTarget = null;
14732        app.empty = false;
14733        app.cached = false;
14734
14735        final int activitiesSize = app.activities.size();
14736
14737        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14738            // The max adjustment doesn't allow this app to be anything
14739            // below foreground, so it is not worth doing work for it.
14740            app.adjType = "fixed";
14741            app.adjSeq = mAdjSeq;
14742            app.curRawAdj = app.maxAdj;
14743            app.foregroundActivities = false;
14744            app.keeping = true;
14745            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14746            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14747            // System processes can do UI, and when they do we want to have
14748            // them trim their memory after the user leaves the UI.  To
14749            // facilitate this, here we need to determine whether or not it
14750            // is currently showing UI.
14751            app.systemNoUi = true;
14752            if (app == TOP_APP) {
14753                app.systemNoUi = false;
14754            } else if (activitiesSize > 0) {
14755                for (int j = 0; j < activitiesSize; j++) {
14756                    final ActivityRecord r = app.activities.get(j);
14757                    if (r.visible) {
14758                        app.systemNoUi = false;
14759                    }
14760                }
14761            }
14762            if (!app.systemNoUi) {
14763                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14764            }
14765            return (app.curAdj=app.maxAdj);
14766        }
14767
14768        app.keeping = false;
14769        app.systemNoUi = false;
14770
14771        // Determine the importance of the process, starting with most
14772        // important to least, and assign an appropriate OOM adjustment.
14773        int adj;
14774        int schedGroup;
14775        int procState;
14776        boolean foregroundActivities = false;
14777        boolean interesting = false;
14778        BroadcastQueue queue;
14779        if (app == TOP_APP) {
14780            // The last app on the list is the foreground app.
14781            adj = ProcessList.FOREGROUND_APP_ADJ;
14782            schedGroup = Process.THREAD_GROUP_DEFAULT;
14783            app.adjType = "top-activity";
14784            foregroundActivities = true;
14785            interesting = true;
14786            procState = ActivityManager.PROCESS_STATE_TOP;
14787        } else if (app.instrumentationClass != null) {
14788            // Don't want to kill running instrumentation.
14789            adj = ProcessList.FOREGROUND_APP_ADJ;
14790            schedGroup = Process.THREAD_GROUP_DEFAULT;
14791            app.adjType = "instrumentation";
14792            interesting = true;
14793            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14794        } else if ((queue = isReceivingBroadcast(app)) != null) {
14795            // An app that is currently receiving a broadcast also
14796            // counts as being in the foreground for OOM killer purposes.
14797            // It's placed in a sched group based on the nature of the
14798            // broadcast as reflected by which queue it's active in.
14799            adj = ProcessList.FOREGROUND_APP_ADJ;
14800            schedGroup = (queue == mFgBroadcastQueue)
14801                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14802            app.adjType = "broadcast";
14803            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14804        } else if (app.executingServices.size() > 0) {
14805            // An app that is currently executing a service callback also
14806            // counts as being in the foreground.
14807            adj = ProcessList.FOREGROUND_APP_ADJ;
14808            schedGroup = app.execServicesFg ?
14809                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14810            app.adjType = "exec-service";
14811            procState = ActivityManager.PROCESS_STATE_SERVICE;
14812            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14813        } else {
14814            // As far as we know the process is empty.  We may change our mind later.
14815            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14816            // At this point we don't actually know the adjustment.  Use the cached adj
14817            // value that the caller wants us to.
14818            adj = cachedAdj;
14819            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14820            app.cached = true;
14821            app.empty = true;
14822            app.adjType = "cch-empty";
14823        }
14824
14825        // Examine all activities if not already foreground.
14826        if (!foregroundActivities && activitiesSize > 0) {
14827            for (int j = 0; j < activitiesSize; j++) {
14828                final ActivityRecord r = app.activities.get(j);
14829                if (r.app != app) {
14830                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14831                            + app + "?!?");
14832                    continue;
14833                }
14834                if (r.visible) {
14835                    // App has a visible activity; only upgrade adjustment.
14836                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14837                        adj = ProcessList.VISIBLE_APP_ADJ;
14838                        app.adjType = "visible";
14839                    }
14840                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14841                        procState = ActivityManager.PROCESS_STATE_TOP;
14842                    }
14843                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14844                    app.cached = false;
14845                    app.empty = false;
14846                    foregroundActivities = true;
14847                    break;
14848                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14849                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14850                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14851                        app.adjType = "pausing";
14852                    }
14853                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14854                        procState = ActivityManager.PROCESS_STATE_TOP;
14855                    }
14856                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14857                    app.cached = false;
14858                    app.empty = false;
14859                    foregroundActivities = true;
14860                } else if (r.state == ActivityState.STOPPING) {
14861                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14862                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14863                        app.adjType = "stopping";
14864                    }
14865                    // For the process state, we will at this point consider the
14866                    // process to be cached.  It will be cached either as an activity
14867                    // or empty depending on whether the activity is finishing.  We do
14868                    // this so that we can treat the process as cached for purposes of
14869                    // memory trimming (determing current memory level, trim command to
14870                    // send to process) since there can be an arbitrary number of stopping
14871                    // processes and they should soon all go into the cached state.
14872                    if (!r.finishing) {
14873                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14874                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14875                        }
14876                    }
14877                    app.cached = false;
14878                    app.empty = false;
14879                    foregroundActivities = true;
14880                } else {
14881                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14882                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14883                        app.adjType = "cch-act";
14884                    }
14885                }
14886            }
14887        }
14888
14889        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14890            if (app.foregroundServices) {
14891                // The user is aware of this app, so make it visible.
14892                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14893                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14894                app.cached = false;
14895                app.adjType = "fg-service";
14896                schedGroup = Process.THREAD_GROUP_DEFAULT;
14897            } else if (app.forcingToForeground != null) {
14898                // The user is aware of this app, so make it visible.
14899                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14900                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14901                app.cached = false;
14902                app.adjType = "force-fg";
14903                app.adjSource = app.forcingToForeground;
14904                schedGroup = Process.THREAD_GROUP_DEFAULT;
14905            }
14906        }
14907
14908        if (app.foregroundServices) {
14909            interesting = true;
14910        }
14911
14912        if (app == mHeavyWeightProcess) {
14913            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14914                // We don't want to kill the current heavy-weight process.
14915                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14916                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14917                app.cached = false;
14918                app.adjType = "heavy";
14919            }
14920            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14921                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14922            }
14923        }
14924
14925        if (app == mHomeProcess) {
14926            if (adj > ProcessList.HOME_APP_ADJ) {
14927                // This process is hosting what we currently consider to be the
14928                // home app, so we don't want to let it go into the background.
14929                adj = ProcessList.HOME_APP_ADJ;
14930                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14931                app.cached = false;
14932                app.adjType = "home";
14933            }
14934            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14935                procState = ActivityManager.PROCESS_STATE_HOME;
14936            }
14937        }
14938
14939        if (app == mPreviousProcess && app.activities.size() > 0) {
14940            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14941                // This was the previous process that showed UI to the user.
14942                // We want to try to keep it around more aggressively, to give
14943                // a good experience around switching between two apps.
14944                adj = ProcessList.PREVIOUS_APP_ADJ;
14945                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14946                app.cached = false;
14947                app.adjType = "previous";
14948            }
14949            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14950                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14951            }
14952        }
14953
14954        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14955                + " reason=" + app.adjType);
14956
14957        // By default, we use the computed adjustment.  It may be changed if
14958        // there are applications dependent on our services or providers, but
14959        // this gives us a baseline and makes sure we don't get into an
14960        // infinite recursion.
14961        app.adjSeq = mAdjSeq;
14962        app.curRawAdj = adj;
14963        app.hasStartedServices = false;
14964
14965        if (mBackupTarget != null && app == mBackupTarget.app) {
14966            // If possible we want to avoid killing apps while they're being backed up
14967            if (adj > ProcessList.BACKUP_APP_ADJ) {
14968                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14969                adj = ProcessList.BACKUP_APP_ADJ;
14970                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14971                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14972                }
14973                app.adjType = "backup";
14974                app.cached = false;
14975            }
14976            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14977                procState = ActivityManager.PROCESS_STATE_BACKUP;
14978            }
14979        }
14980
14981        boolean mayBeTop = false;
14982
14983        for (int is = app.services.size()-1;
14984                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14985                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14986                        || procState > ActivityManager.PROCESS_STATE_TOP);
14987                is--) {
14988            ServiceRecord s = app.services.valueAt(is);
14989            if (s.startRequested) {
14990                app.hasStartedServices = true;
14991                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14992                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14993                }
14994                if (app.hasShownUi && app != mHomeProcess) {
14995                    // If this process has shown some UI, let it immediately
14996                    // go to the LRU list because it may be pretty heavy with
14997                    // UI stuff.  We'll tag it with a label just to help
14998                    // debug and understand what is going on.
14999                    if (adj > ProcessList.SERVICE_ADJ) {
15000                        app.adjType = "cch-started-ui-services";
15001                    }
15002                } else {
15003                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15004                        // This service has seen some activity within
15005                        // recent memory, so we will keep its process ahead
15006                        // of the background processes.
15007                        if (adj > ProcessList.SERVICE_ADJ) {
15008                            adj = ProcessList.SERVICE_ADJ;
15009                            app.adjType = "started-services";
15010                            app.cached = false;
15011                        }
15012                    }
15013                    // If we have let the service slide into the background
15014                    // state, still have some text describing what it is doing
15015                    // even though the service no longer has an impact.
15016                    if (adj > ProcessList.SERVICE_ADJ) {
15017                        app.adjType = "cch-started-services";
15018                    }
15019                }
15020                // Don't kill this process because it is doing work; it
15021                // has said it is doing work.
15022                app.keeping = true;
15023            }
15024            for (int conni = s.connections.size()-1;
15025                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15026                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15027                            || procState > ActivityManager.PROCESS_STATE_TOP);
15028                    conni--) {
15029                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15030                for (int i = 0;
15031                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15032                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15033                                || procState > ActivityManager.PROCESS_STATE_TOP);
15034                        i++) {
15035                    // XXX should compute this based on the max of
15036                    // all connected clients.
15037                    ConnectionRecord cr = clist.get(i);
15038                    if (cr.binding.client == app) {
15039                        // Binding to ourself is not interesting.
15040                        continue;
15041                    }
15042                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15043                        ProcessRecord client = cr.binding.client;
15044                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15045                                TOP_APP, doingAll, now);
15046                        int clientProcState = client.curProcState;
15047                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15048                            // If the other app is cached for any reason, for purposes here
15049                            // we are going to consider it empty.  The specific cached state
15050                            // doesn't propagate except under certain conditions.
15051                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15052                        }
15053                        String adjType = null;
15054                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15055                            // Not doing bind OOM management, so treat
15056                            // this guy more like a started service.
15057                            if (app.hasShownUi && app != mHomeProcess) {
15058                                // If this process has shown some UI, let it immediately
15059                                // go to the LRU list because it may be pretty heavy with
15060                                // UI stuff.  We'll tag it with a label just to help
15061                                // debug and understand what is going on.
15062                                if (adj > clientAdj) {
15063                                    adjType = "cch-bound-ui-services";
15064                                }
15065                                app.cached = false;
15066                                clientAdj = adj;
15067                                clientProcState = procState;
15068                            } else {
15069                                if (now >= (s.lastActivity
15070                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15071                                    // This service has not seen activity within
15072                                    // recent memory, so allow it to drop to the
15073                                    // LRU list if there is no other reason to keep
15074                                    // it around.  We'll also tag it with a label just
15075                                    // to help debug and undertand what is going on.
15076                                    if (adj > clientAdj) {
15077                                        adjType = "cch-bound-services";
15078                                    }
15079                                    clientAdj = adj;
15080                                }
15081                            }
15082                        }
15083                        if (adj > clientAdj) {
15084                            // If this process has recently shown UI, and
15085                            // the process that is binding to it is less
15086                            // important than being visible, then we don't
15087                            // care about the binding as much as we care
15088                            // about letting this process get into the LRU
15089                            // list to be killed and restarted if needed for
15090                            // memory.
15091                            if (app.hasShownUi && app != mHomeProcess
15092                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15093                                adjType = "cch-bound-ui-services";
15094                            } else {
15095                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15096                                        |Context.BIND_IMPORTANT)) != 0) {
15097                                    adj = clientAdj;
15098                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15099                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15100                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15101                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15102                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15103                                    adj = clientAdj;
15104                                } else {
15105                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15106                                        adj = ProcessList.VISIBLE_APP_ADJ;
15107                                    }
15108                                }
15109                                if (!client.cached) {
15110                                    app.cached = false;
15111                                }
15112                                if (client.keeping) {
15113                                    app.keeping = true;
15114                                }
15115                                adjType = "service";
15116                            }
15117                        }
15118                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15119                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15120                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15121                            }
15122                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15123                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15124                                    // Special handling of clients who are in the top state.
15125                                    // We *may* want to consider this process to be in the
15126                                    // top state as well, but only if there is not another
15127                                    // reason for it to be running.  Being on the top is a
15128                                    // special state, meaning you are specifically running
15129                                    // for the current top app.  If the process is already
15130                                    // running in the background for some other reason, it
15131                                    // is more important to continue considering it to be
15132                                    // in the background state.
15133                                    mayBeTop = true;
15134                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15135                                } else {
15136                                    // Special handling for above-top states (persistent
15137                                    // processes).  These should not bring the current process
15138                                    // into the top state, since they are not on top.  Instead
15139                                    // give them the best state after that.
15140                                    clientProcState =
15141                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15142                                }
15143                            }
15144                        } else {
15145                            if (clientProcState <
15146                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15147                                clientProcState =
15148                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15149                            }
15150                        }
15151                        if (procState > clientProcState) {
15152                            procState = clientProcState;
15153                        }
15154                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15155                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15156                            app.pendingUiClean = true;
15157                        }
15158                        if (adjType != null) {
15159                            app.adjType = adjType;
15160                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15161                                    .REASON_SERVICE_IN_USE;
15162                            app.adjSource = cr.binding.client;
15163                            app.adjSourceOom = clientAdj;
15164                            app.adjTarget = s.name;
15165                        }
15166                    }
15167                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15168                        app.treatLikeActivity = true;
15169                    }
15170                    final ActivityRecord a = cr.activity;
15171                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15172                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15173                                (a.visible || a.state == ActivityState.RESUMED
15174                                 || a.state == ActivityState.PAUSING)) {
15175                            adj = ProcessList.FOREGROUND_APP_ADJ;
15176                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15177                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15178                            }
15179                            app.cached = false;
15180                            app.adjType = "service";
15181                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15182                                    .REASON_SERVICE_IN_USE;
15183                            app.adjSource = a;
15184                            app.adjSourceOom = adj;
15185                            app.adjTarget = s.name;
15186                        }
15187                    }
15188                }
15189            }
15190        }
15191
15192        for (int provi = app.pubProviders.size()-1;
15193                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15194                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15195                        || procState > ActivityManager.PROCESS_STATE_TOP);
15196                provi--) {
15197            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15198            for (int i = cpr.connections.size()-1;
15199                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15200                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15201                            || procState > ActivityManager.PROCESS_STATE_TOP);
15202                    i--) {
15203                ContentProviderConnection conn = cpr.connections.get(i);
15204                ProcessRecord client = conn.client;
15205                if (client == app) {
15206                    // Being our own client is not interesting.
15207                    continue;
15208                }
15209                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15210                int clientProcState = client.curProcState;
15211                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15212                    // If the other app is cached for any reason, for purposes here
15213                    // we are going to consider it empty.
15214                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15215                }
15216                if (adj > clientAdj) {
15217                    if (app.hasShownUi && app != mHomeProcess
15218                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15219                        app.adjType = "cch-ui-provider";
15220                    } else {
15221                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15222                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15223                        app.adjType = "provider";
15224                    }
15225                    app.cached &= client.cached;
15226                    app.keeping |= client.keeping;
15227                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15228                            .REASON_PROVIDER_IN_USE;
15229                    app.adjSource = client;
15230                    app.adjSourceOom = clientAdj;
15231                    app.adjTarget = cpr.name;
15232                }
15233                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15234                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15235                        // Special handling of clients who are in the top state.
15236                        // We *may* want to consider this process to be in the
15237                        // top state as well, but only if there is not another
15238                        // reason for it to be running.  Being on the top is a
15239                        // special state, meaning you are specifically running
15240                        // for the current top app.  If the process is already
15241                        // running in the background for some other reason, it
15242                        // is more important to continue considering it to be
15243                        // in the background state.
15244                        mayBeTop = true;
15245                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15246                    } else {
15247                        // Special handling for above-top states (persistent
15248                        // processes).  These should not bring the current process
15249                        // into the top state, since they are not on top.  Instead
15250                        // give them the best state after that.
15251                        clientProcState =
15252                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15253                    }
15254                }
15255                if (procState > clientProcState) {
15256                    procState = clientProcState;
15257                }
15258                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15259                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15260                }
15261            }
15262            // If the provider has external (non-framework) process
15263            // dependencies, ensure that its adjustment is at least
15264            // FOREGROUND_APP_ADJ.
15265            if (cpr.hasExternalProcessHandles()) {
15266                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15267                    adj = ProcessList.FOREGROUND_APP_ADJ;
15268                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15269                    app.cached = false;
15270                    app.keeping = true;
15271                    app.adjType = "provider";
15272                    app.adjTarget = cpr.name;
15273                }
15274                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15275                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15276                }
15277            }
15278        }
15279
15280        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15281            // A client of one of our services or providers is in the top state.  We
15282            // *may* want to be in the top state, but not if we are already running in
15283            // the background for some other reason.  For the decision here, we are going
15284            // to pick out a few specific states that we want to remain in when a client
15285            // is top (states that tend to be longer-term) and otherwise allow it to go
15286            // to the top state.
15287            switch (procState) {
15288                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15289                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15290                case ActivityManager.PROCESS_STATE_SERVICE:
15291                    // These all are longer-term states, so pull them up to the top
15292                    // of the background states, but not all the way to the top state.
15293                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15294                    break;
15295                default:
15296                    // Otherwise, top is a better choice, so take it.
15297                    procState = ActivityManager.PROCESS_STATE_TOP;
15298                    break;
15299            }
15300        }
15301
15302        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15303            if (app.hasClientActivities) {
15304                // This is a cached process, but with client activities.  Mark it so.
15305                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15306                app.adjType = "cch-client-act";
15307            } else if (app.treatLikeActivity) {
15308                // This is a cached process, but somebody wants us to treat it like it has
15309                // an activity, okay!
15310                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15311                app.adjType = "cch-as-act";
15312            }
15313        }
15314
15315        if (adj == ProcessList.SERVICE_ADJ) {
15316            if (doingAll) {
15317                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15318                mNewNumServiceProcs++;
15319                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15320                if (!app.serviceb) {
15321                    // This service isn't far enough down on the LRU list to
15322                    // normally be a B service, but if we are low on RAM and it
15323                    // is large we want to force it down since we would prefer to
15324                    // keep launcher over it.
15325                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15326                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15327                        app.serviceHighRam = true;
15328                        app.serviceb = true;
15329                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15330                    } else {
15331                        mNewNumAServiceProcs++;
15332                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15333                    }
15334                } else {
15335                    app.serviceHighRam = false;
15336                }
15337            }
15338            if (app.serviceb) {
15339                adj = ProcessList.SERVICE_B_ADJ;
15340            }
15341        }
15342
15343        app.curRawAdj = adj;
15344
15345        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15346        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15347        if (adj > app.maxAdj) {
15348            adj = app.maxAdj;
15349            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15350                schedGroup = Process.THREAD_GROUP_DEFAULT;
15351            }
15352        }
15353        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15354            app.keeping = true;
15355        }
15356
15357        // Do final modification to adj.  Everything we do between here and applying
15358        // the final setAdj must be done in this function, because we will also use
15359        // it when computing the final cached adj later.  Note that we don't need to
15360        // worry about this for max adj above, since max adj will always be used to
15361        // keep it out of the cached vaues.
15362        app.curAdj = app.modifyRawOomAdj(adj);
15363        app.curSchedGroup = schedGroup;
15364        app.curProcState = procState;
15365        app.foregroundActivities = foregroundActivities;
15366
15367        return app.curRawAdj;
15368    }
15369
15370    /**
15371     * Schedule PSS collection of a process.
15372     */
15373    void requestPssLocked(ProcessRecord proc, int procState) {
15374        if (mPendingPssProcesses.contains(proc)) {
15375            return;
15376        }
15377        if (mPendingPssProcesses.size() == 0) {
15378            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15379        }
15380        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15381        proc.pssProcState = procState;
15382        mPendingPssProcesses.add(proc);
15383    }
15384
15385    /**
15386     * Schedule PSS collection of all processes.
15387     */
15388    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15389        if (!always) {
15390            if (now < (mLastFullPssTime +
15391                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15392                return;
15393            }
15394        }
15395        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15396        mLastFullPssTime = now;
15397        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15398        mPendingPssProcesses.clear();
15399        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15400            ProcessRecord app = mLruProcesses.get(i);
15401            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15402                app.pssProcState = app.setProcState;
15403                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15404                        isSleeping(), now);
15405                mPendingPssProcesses.add(app);
15406            }
15407        }
15408        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15409    }
15410
15411    /**
15412     * Ask a given process to GC right now.
15413     */
15414    final void performAppGcLocked(ProcessRecord app) {
15415        try {
15416            app.lastRequestedGc = SystemClock.uptimeMillis();
15417            if (app.thread != null) {
15418                if (app.reportLowMemory) {
15419                    app.reportLowMemory = false;
15420                    app.thread.scheduleLowMemory();
15421                } else {
15422                    app.thread.processInBackground();
15423                }
15424            }
15425        } catch (Exception e) {
15426            // whatever.
15427        }
15428    }
15429
15430    /**
15431     * Returns true if things are idle enough to perform GCs.
15432     */
15433    private final boolean canGcNowLocked() {
15434        boolean processingBroadcasts = false;
15435        for (BroadcastQueue q : mBroadcastQueues) {
15436            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15437                processingBroadcasts = true;
15438            }
15439        }
15440        return !processingBroadcasts
15441                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15442    }
15443
15444    /**
15445     * Perform GCs on all processes that are waiting for it, but only
15446     * if things are idle.
15447     */
15448    final void performAppGcsLocked() {
15449        final int N = mProcessesToGc.size();
15450        if (N <= 0) {
15451            return;
15452        }
15453        if (canGcNowLocked()) {
15454            while (mProcessesToGc.size() > 0) {
15455                ProcessRecord proc = mProcessesToGc.remove(0);
15456                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15457                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15458                            <= SystemClock.uptimeMillis()) {
15459                        // To avoid spamming the system, we will GC processes one
15460                        // at a time, waiting a few seconds between each.
15461                        performAppGcLocked(proc);
15462                        scheduleAppGcsLocked();
15463                        return;
15464                    } else {
15465                        // It hasn't been long enough since we last GCed this
15466                        // process...  put it in the list to wait for its time.
15467                        addProcessToGcListLocked(proc);
15468                        break;
15469                    }
15470                }
15471            }
15472
15473            scheduleAppGcsLocked();
15474        }
15475    }
15476
15477    /**
15478     * If all looks good, perform GCs on all processes waiting for them.
15479     */
15480    final void performAppGcsIfAppropriateLocked() {
15481        if (canGcNowLocked()) {
15482            performAppGcsLocked();
15483            return;
15484        }
15485        // Still not idle, wait some more.
15486        scheduleAppGcsLocked();
15487    }
15488
15489    /**
15490     * Schedule the execution of all pending app GCs.
15491     */
15492    final void scheduleAppGcsLocked() {
15493        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15494
15495        if (mProcessesToGc.size() > 0) {
15496            // Schedule a GC for the time to the next process.
15497            ProcessRecord proc = mProcessesToGc.get(0);
15498            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15499
15500            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15501            long now = SystemClock.uptimeMillis();
15502            if (when < (now+GC_TIMEOUT)) {
15503                when = now + GC_TIMEOUT;
15504            }
15505            mHandler.sendMessageAtTime(msg, when);
15506        }
15507    }
15508
15509    /**
15510     * Add a process to the array of processes waiting to be GCed.  Keeps the
15511     * list in sorted order by the last GC time.  The process can't already be
15512     * on the list.
15513     */
15514    final void addProcessToGcListLocked(ProcessRecord proc) {
15515        boolean added = false;
15516        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15517            if (mProcessesToGc.get(i).lastRequestedGc <
15518                    proc.lastRequestedGc) {
15519                added = true;
15520                mProcessesToGc.add(i+1, proc);
15521                break;
15522            }
15523        }
15524        if (!added) {
15525            mProcessesToGc.add(0, proc);
15526        }
15527    }
15528
15529    /**
15530     * Set up to ask a process to GC itself.  This will either do it
15531     * immediately, or put it on the list of processes to gc the next
15532     * time things are idle.
15533     */
15534    final void scheduleAppGcLocked(ProcessRecord app) {
15535        long now = SystemClock.uptimeMillis();
15536        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15537            return;
15538        }
15539        if (!mProcessesToGc.contains(app)) {
15540            addProcessToGcListLocked(app);
15541            scheduleAppGcsLocked();
15542        }
15543    }
15544
15545    final void checkExcessivePowerUsageLocked(boolean doKills) {
15546        updateCpuStatsNow();
15547
15548        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15549        boolean doWakeKills = doKills;
15550        boolean doCpuKills = doKills;
15551        if (mLastPowerCheckRealtime == 0) {
15552            doWakeKills = false;
15553        }
15554        if (mLastPowerCheckUptime == 0) {
15555            doCpuKills = false;
15556        }
15557        if (stats.isScreenOn()) {
15558            doWakeKills = false;
15559        }
15560        final long curRealtime = SystemClock.elapsedRealtime();
15561        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15562        final long curUptime = SystemClock.uptimeMillis();
15563        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15564        mLastPowerCheckRealtime = curRealtime;
15565        mLastPowerCheckUptime = curUptime;
15566        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15567            doWakeKills = false;
15568        }
15569        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15570            doCpuKills = false;
15571        }
15572        int i = mLruProcesses.size();
15573        while (i > 0) {
15574            i--;
15575            ProcessRecord app = mLruProcesses.get(i);
15576            if (!app.keeping) {
15577                long wtime;
15578                synchronized (stats) {
15579                    wtime = stats.getProcessWakeTime(app.info.uid,
15580                            app.pid, curRealtime);
15581                }
15582                long wtimeUsed = wtime - app.lastWakeTime;
15583                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15584                if (DEBUG_POWER) {
15585                    StringBuilder sb = new StringBuilder(128);
15586                    sb.append("Wake for ");
15587                    app.toShortString(sb);
15588                    sb.append(": over ");
15589                    TimeUtils.formatDuration(realtimeSince, sb);
15590                    sb.append(" used ");
15591                    TimeUtils.formatDuration(wtimeUsed, sb);
15592                    sb.append(" (");
15593                    sb.append((wtimeUsed*100)/realtimeSince);
15594                    sb.append("%)");
15595                    Slog.i(TAG, sb.toString());
15596                    sb.setLength(0);
15597                    sb.append("CPU for ");
15598                    app.toShortString(sb);
15599                    sb.append(": over ");
15600                    TimeUtils.formatDuration(uptimeSince, sb);
15601                    sb.append(" used ");
15602                    TimeUtils.formatDuration(cputimeUsed, sb);
15603                    sb.append(" (");
15604                    sb.append((cputimeUsed*100)/uptimeSince);
15605                    sb.append("%)");
15606                    Slog.i(TAG, sb.toString());
15607                }
15608                // If a process has held a wake lock for more
15609                // than 50% of the time during this period,
15610                // that sounds bad.  Kill!
15611                if (doWakeKills && realtimeSince > 0
15612                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15613                    synchronized (stats) {
15614                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15615                                realtimeSince, wtimeUsed);
15616                    }
15617                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15618                            + " during " + realtimeSince);
15619                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15620                } else if (doCpuKills && uptimeSince > 0
15621                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15622                    synchronized (stats) {
15623                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15624                                uptimeSince, cputimeUsed);
15625                    }
15626                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15627                            + " during " + uptimeSince);
15628                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15629                } else {
15630                    app.lastWakeTime = wtime;
15631                    app.lastCpuTime = app.curCpuTime;
15632                }
15633            }
15634        }
15635    }
15636
15637    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15638            ProcessRecord TOP_APP, boolean doingAll, long now) {
15639        boolean success = true;
15640
15641        if (app.curRawAdj != app.setRawAdj) {
15642            if (wasKeeping && !app.keeping) {
15643                // This app is no longer something we want to keep.  Note
15644                // its current wake lock time to later know to kill it if
15645                // it is not behaving well.
15646                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15647                synchronized (stats) {
15648                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15649                            app.pid, SystemClock.elapsedRealtime());
15650                }
15651                app.lastCpuTime = app.curCpuTime;
15652            }
15653
15654            app.setRawAdj = app.curRawAdj;
15655        }
15656
15657        int changes = 0;
15658
15659        if (app.curAdj != app.setAdj) {
15660            ProcessList.setOomAdj(app.pid, app.curAdj);
15661            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15662                TAG, "Set " + app.pid + " " + app.processName +
15663                " adj " + app.curAdj + ": " + app.adjType);
15664            app.setAdj = app.curAdj;
15665        }
15666
15667        if (app.setSchedGroup != app.curSchedGroup) {
15668            app.setSchedGroup = app.curSchedGroup;
15669            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15670                    "Setting process group of " + app.processName
15671                    + " to " + app.curSchedGroup);
15672            if (app.waitingToKill != null &&
15673                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15674                killUnneededProcessLocked(app, app.waitingToKill);
15675                success = false;
15676            } else {
15677                if (true) {
15678                    long oldId = Binder.clearCallingIdentity();
15679                    try {
15680                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15681                    } catch (Exception e) {
15682                        Slog.w(TAG, "Failed setting process group of " + app.pid
15683                                + " to " + app.curSchedGroup);
15684                        e.printStackTrace();
15685                    } finally {
15686                        Binder.restoreCallingIdentity(oldId);
15687                    }
15688                } else {
15689                    if (app.thread != null) {
15690                        try {
15691                            app.thread.setSchedulingGroup(app.curSchedGroup);
15692                        } catch (RemoteException e) {
15693                        }
15694                    }
15695                }
15696                Process.setSwappiness(app.pid,
15697                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15698            }
15699        }
15700        if (app.repForegroundActivities != app.foregroundActivities) {
15701            app.repForegroundActivities = app.foregroundActivities;
15702            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15703        }
15704        if (app.repProcState != app.curProcState) {
15705            app.repProcState = app.curProcState;
15706            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15707            if (app.thread != null) {
15708                try {
15709                    if (false) {
15710                        //RuntimeException h = new RuntimeException("here");
15711                        Slog.i(TAG, "Sending new process state " + app.repProcState
15712                                + " to " + app /*, h*/);
15713                    }
15714                    app.thread.setProcessState(app.repProcState);
15715                } catch (RemoteException e) {
15716                }
15717            }
15718        }
15719        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15720                app.setProcState)) {
15721            app.lastStateTime = now;
15722            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15723                    isSleeping(), now);
15724            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15725                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15726                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15727                    + (app.nextPssTime-now) + ": " + app);
15728        } else {
15729            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15730                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15731                requestPssLocked(app, app.setProcState);
15732                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15733                        isSleeping(), now);
15734            } else if (false && DEBUG_PSS) {
15735                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15736            }
15737        }
15738        if (app.setProcState != app.curProcState) {
15739            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15740                    "Proc state change of " + app.processName
15741                    + " to " + app.curProcState);
15742            app.setProcState = app.curProcState;
15743            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15744                app.notCachedSinceIdle = false;
15745            }
15746            if (!doingAll) {
15747                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15748            } else {
15749                app.procStateChanged = true;
15750            }
15751        }
15752
15753        if (changes != 0) {
15754            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15755            int i = mPendingProcessChanges.size()-1;
15756            ProcessChangeItem item = null;
15757            while (i >= 0) {
15758                item = mPendingProcessChanges.get(i);
15759                if (item.pid == app.pid) {
15760                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15761                    break;
15762                }
15763                i--;
15764            }
15765            if (i < 0) {
15766                // No existing item in pending changes; need a new one.
15767                final int NA = mAvailProcessChanges.size();
15768                if (NA > 0) {
15769                    item = mAvailProcessChanges.remove(NA-1);
15770                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15771                } else {
15772                    item = new ProcessChangeItem();
15773                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15774                }
15775                item.changes = 0;
15776                item.pid = app.pid;
15777                item.uid = app.info.uid;
15778                if (mPendingProcessChanges.size() == 0) {
15779                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15780                            "*** Enqueueing dispatch processes changed!");
15781                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15782                }
15783                mPendingProcessChanges.add(item);
15784            }
15785            item.changes |= changes;
15786            item.processState = app.repProcState;
15787            item.foregroundActivities = app.repForegroundActivities;
15788            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15789                    + Integer.toHexString(System.identityHashCode(item))
15790                    + " " + app.toShortString() + ": changes=" + item.changes
15791                    + " procState=" + item.processState
15792                    + " foreground=" + item.foregroundActivities
15793                    + " type=" + app.adjType + " source=" + app.adjSource
15794                    + " target=" + app.adjTarget);
15795        }
15796
15797        return success;
15798    }
15799
15800    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15801        if (proc.thread != null && proc.baseProcessTracker != null) {
15802            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15803        }
15804    }
15805
15806    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15807            ProcessRecord TOP_APP, boolean doingAll, long now) {
15808        if (app.thread == null) {
15809            return false;
15810        }
15811
15812        final boolean wasKeeping = app.keeping;
15813
15814        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15815
15816        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15817    }
15818
15819    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15820            boolean oomAdj) {
15821        if (isForeground != proc.foregroundServices) {
15822            proc.foregroundServices = isForeground;
15823            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15824                    proc.info.uid);
15825            if (isForeground) {
15826                if (curProcs == null) {
15827                    curProcs = new ArrayList<ProcessRecord>();
15828                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15829                }
15830                if (!curProcs.contains(proc)) {
15831                    curProcs.add(proc);
15832                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15833                            proc.info.packageName, proc.info.uid);
15834                }
15835            } else {
15836                if (curProcs != null) {
15837                    if (curProcs.remove(proc)) {
15838                        mBatteryStatsService.noteEvent(
15839                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15840                                proc.info.packageName, proc.info.uid);
15841                        if (curProcs.size() <= 0) {
15842                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15843                        }
15844                    }
15845                }
15846            }
15847            if (oomAdj) {
15848                updateOomAdjLocked();
15849            }
15850        }
15851    }
15852
15853    private final ActivityRecord resumedAppLocked() {
15854        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15855        String pkg;
15856        int uid;
15857        if (act != null && !act.sleeping) {
15858            pkg = act.packageName;
15859            uid = act.info.applicationInfo.uid;
15860        } else {
15861            pkg = null;
15862            uid = -1;
15863        }
15864        // Has the UID or resumed package name changed?
15865        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15866                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15867            if (mCurResumedPackage != null) {
15868                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15869                        mCurResumedPackage, mCurResumedUid);
15870            }
15871            mCurResumedPackage = pkg;
15872            mCurResumedUid = uid;
15873            if (mCurResumedPackage != null) {
15874                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15875                        mCurResumedPackage, mCurResumedUid);
15876            }
15877        }
15878        return act;
15879    }
15880
15881    final boolean updateOomAdjLocked(ProcessRecord app) {
15882        final ActivityRecord TOP_ACT = resumedAppLocked();
15883        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15884        final boolean wasCached = app.cached;
15885
15886        mAdjSeq++;
15887
15888        // This is the desired cached adjusment we want to tell it to use.
15889        // If our app is currently cached, we know it, and that is it.  Otherwise,
15890        // we don't know it yet, and it needs to now be cached we will then
15891        // need to do a complete oom adj.
15892        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15893                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15894        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15895                SystemClock.uptimeMillis());
15896        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15897            // Changed to/from cached state, so apps after it in the LRU
15898            // list may also be changed.
15899            updateOomAdjLocked();
15900        }
15901        return success;
15902    }
15903
15904    final void updateOomAdjLocked() {
15905        final ActivityRecord TOP_ACT = resumedAppLocked();
15906        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15907        final long now = SystemClock.uptimeMillis();
15908        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15909        final int N = mLruProcesses.size();
15910
15911        if (false) {
15912            RuntimeException e = new RuntimeException();
15913            e.fillInStackTrace();
15914            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15915        }
15916
15917        mAdjSeq++;
15918        mNewNumServiceProcs = 0;
15919        mNewNumAServiceProcs = 0;
15920
15921        final int emptyProcessLimit;
15922        final int cachedProcessLimit;
15923        if (mProcessLimit <= 0) {
15924            emptyProcessLimit = cachedProcessLimit = 0;
15925        } else if (mProcessLimit == 1) {
15926            emptyProcessLimit = 1;
15927            cachedProcessLimit = 0;
15928        } else {
15929            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15930            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15931        }
15932
15933        // Let's determine how many processes we have running vs.
15934        // how many slots we have for background processes; we may want
15935        // to put multiple processes in a slot of there are enough of
15936        // them.
15937        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15938                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15939        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15940        if (numEmptyProcs > cachedProcessLimit) {
15941            // If there are more empty processes than our limit on cached
15942            // processes, then use the cached process limit for the factor.
15943            // This ensures that the really old empty processes get pushed
15944            // down to the bottom, so if we are running low on memory we will
15945            // have a better chance at keeping around more cached processes
15946            // instead of a gazillion empty processes.
15947            numEmptyProcs = cachedProcessLimit;
15948        }
15949        int emptyFactor = numEmptyProcs/numSlots;
15950        if (emptyFactor < 1) emptyFactor = 1;
15951        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15952        if (cachedFactor < 1) cachedFactor = 1;
15953        int stepCached = 0;
15954        int stepEmpty = 0;
15955        int numCached = 0;
15956        int numEmpty = 0;
15957        int numTrimming = 0;
15958
15959        mNumNonCachedProcs = 0;
15960        mNumCachedHiddenProcs = 0;
15961
15962        // First update the OOM adjustment for each of the
15963        // application processes based on their current state.
15964        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15965        int nextCachedAdj = curCachedAdj+1;
15966        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15967        int nextEmptyAdj = curEmptyAdj+2;
15968        for (int i=N-1; i>=0; i--) {
15969            ProcessRecord app = mLruProcesses.get(i);
15970            if (!app.killedByAm && app.thread != null) {
15971                app.procStateChanged = false;
15972                final boolean wasKeeping = app.keeping;
15973                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15974
15975                // If we haven't yet assigned the final cached adj
15976                // to the process, do that now.
15977                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15978                    switch (app.curProcState) {
15979                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15980                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15981                            // This process is a cached process holding activities...
15982                            // assign it the next cached value for that type, and then
15983                            // step that cached level.
15984                            app.curRawAdj = curCachedAdj;
15985                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15986                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15987                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15988                                    + ")");
15989                            if (curCachedAdj != nextCachedAdj) {
15990                                stepCached++;
15991                                if (stepCached >= cachedFactor) {
15992                                    stepCached = 0;
15993                                    curCachedAdj = nextCachedAdj;
15994                                    nextCachedAdj += 2;
15995                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15996                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15997                                    }
15998                                }
15999                            }
16000                            break;
16001                        default:
16002                            // For everything else, assign next empty cached process
16003                            // level and bump that up.  Note that this means that
16004                            // long-running services that have dropped down to the
16005                            // cached level will be treated as empty (since their process
16006                            // state is still as a service), which is what we want.
16007                            app.curRawAdj = curEmptyAdj;
16008                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16009                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16010                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16011                                    + ")");
16012                            if (curEmptyAdj != nextEmptyAdj) {
16013                                stepEmpty++;
16014                                if (stepEmpty >= emptyFactor) {
16015                                    stepEmpty = 0;
16016                                    curEmptyAdj = nextEmptyAdj;
16017                                    nextEmptyAdj += 2;
16018                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16019                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16020                                    }
16021                                }
16022                            }
16023                            break;
16024                    }
16025                }
16026
16027                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16028
16029                // Count the number of process types.
16030                switch (app.curProcState) {
16031                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16032                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16033                        mNumCachedHiddenProcs++;
16034                        numCached++;
16035                        if (numCached > cachedProcessLimit) {
16036                            killUnneededProcessLocked(app, "cached #" + numCached);
16037                        }
16038                        break;
16039                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16040                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16041                                && app.lastActivityTime < oldTime) {
16042                            killUnneededProcessLocked(app, "empty for "
16043                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16044                                    / 1000) + "s");
16045                        } else {
16046                            numEmpty++;
16047                            if (numEmpty > emptyProcessLimit) {
16048                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16049                            }
16050                        }
16051                        break;
16052                    default:
16053                        mNumNonCachedProcs++;
16054                        break;
16055                }
16056
16057                if (app.isolated && app.services.size() <= 0) {
16058                    // If this is an isolated process, and there are no
16059                    // services running in it, then the process is no longer
16060                    // needed.  We agressively kill these because we can by
16061                    // definition not re-use the same process again, and it is
16062                    // good to avoid having whatever code was running in them
16063                    // left sitting around after no longer needed.
16064                    killUnneededProcessLocked(app, "isolated not needed");
16065                }
16066
16067                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16068                        && !app.killedByAm) {
16069                    numTrimming++;
16070                }
16071            }
16072        }
16073
16074        mNumServiceProcs = mNewNumServiceProcs;
16075
16076        // Now determine the memory trimming level of background processes.
16077        // Unfortunately we need to start at the back of the list to do this
16078        // properly.  We only do this if the number of background apps we
16079        // are managing to keep around is less than half the maximum we desire;
16080        // if we are keeping a good number around, we'll let them use whatever
16081        // memory they want.
16082        final int numCachedAndEmpty = numCached + numEmpty;
16083        int memFactor;
16084        if (numCached <= ProcessList.TRIM_CACHED_APPS
16085                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16086            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16087                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16088            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16089                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16090            } else {
16091                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16092            }
16093        } else {
16094            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16095        }
16096        // We always allow the memory level to go up (better).  We only allow it to go
16097        // down if we are in a state where that is allowed, *and* the total number of processes
16098        // has gone down since last time.
16099        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16100                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16101                + " last=" + mLastNumProcesses);
16102        if (memFactor > mLastMemoryLevel) {
16103            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16104                memFactor = mLastMemoryLevel;
16105                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16106            }
16107        }
16108        mLastMemoryLevel = memFactor;
16109        mLastNumProcesses = mLruProcesses.size();
16110        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16111        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16112        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16113            if (mLowRamStartTime == 0) {
16114                mLowRamStartTime = now;
16115            }
16116            int step = 0;
16117            int fgTrimLevel;
16118            switch (memFactor) {
16119                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16120                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16121                    break;
16122                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16123                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16124                    break;
16125                default:
16126                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16127                    break;
16128            }
16129            int factor = numTrimming/3;
16130            int minFactor = 2;
16131            if (mHomeProcess != null) minFactor++;
16132            if (mPreviousProcess != null) minFactor++;
16133            if (factor < minFactor) factor = minFactor;
16134            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16135            for (int i=N-1; i>=0; i--) {
16136                ProcessRecord app = mLruProcesses.get(i);
16137                if (allChanged || app.procStateChanged) {
16138                    setProcessTrackerState(app, trackerMemFactor, now);
16139                    app.procStateChanged = false;
16140                }
16141                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16142                        && !app.killedByAm) {
16143                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16144                        try {
16145                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16146                                    "Trimming memory of " + app.processName
16147                                    + " to " + curLevel);
16148                            app.thread.scheduleTrimMemory(curLevel);
16149                        } catch (RemoteException e) {
16150                        }
16151                        if (false) {
16152                            // For now we won't do this; our memory trimming seems
16153                            // to be good enough at this point that destroying
16154                            // activities causes more harm than good.
16155                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16156                                    && app != mHomeProcess && app != mPreviousProcess) {
16157                                // Need to do this on its own message because the stack may not
16158                                // be in a consistent state at this point.
16159                                // For these apps we will also finish their activities
16160                                // to help them free memory.
16161                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16162                            }
16163                        }
16164                    }
16165                    app.trimMemoryLevel = curLevel;
16166                    step++;
16167                    if (step >= factor) {
16168                        step = 0;
16169                        switch (curLevel) {
16170                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16171                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16172                                break;
16173                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16174                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16175                                break;
16176                        }
16177                    }
16178                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16179                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16180                            && app.thread != null) {
16181                        try {
16182                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16183                                    "Trimming memory of heavy-weight " + app.processName
16184                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16185                            app.thread.scheduleTrimMemory(
16186                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16187                        } catch (RemoteException e) {
16188                        }
16189                    }
16190                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16191                } else {
16192                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16193                            || app.systemNoUi) && app.pendingUiClean) {
16194                        // If this application is now in the background and it
16195                        // had done UI, then give it the special trim level to
16196                        // have it free UI resources.
16197                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16198                        if (app.trimMemoryLevel < level && app.thread != null) {
16199                            try {
16200                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16201                                        "Trimming memory of bg-ui " + app.processName
16202                                        + " to " + level);
16203                                app.thread.scheduleTrimMemory(level);
16204                            } catch (RemoteException e) {
16205                            }
16206                        }
16207                        app.pendingUiClean = false;
16208                    }
16209                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16210                        try {
16211                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16212                                    "Trimming memory of fg " + app.processName
16213                                    + " to " + fgTrimLevel);
16214                            app.thread.scheduleTrimMemory(fgTrimLevel);
16215                        } catch (RemoteException e) {
16216                        }
16217                    }
16218                    app.trimMemoryLevel = fgTrimLevel;
16219                }
16220            }
16221        } else {
16222            if (mLowRamStartTime != 0) {
16223                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16224                mLowRamStartTime = 0;
16225            }
16226            for (int i=N-1; i>=0; i--) {
16227                ProcessRecord app = mLruProcesses.get(i);
16228                if (allChanged || app.procStateChanged) {
16229                    setProcessTrackerState(app, trackerMemFactor, now);
16230                    app.procStateChanged = false;
16231                }
16232                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16233                        || app.systemNoUi) && app.pendingUiClean) {
16234                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16235                            && app.thread != null) {
16236                        try {
16237                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16238                                    "Trimming memory of ui hidden " + app.processName
16239                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16240                            app.thread.scheduleTrimMemory(
16241                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16242                        } catch (RemoteException e) {
16243                        }
16244                    }
16245                    app.pendingUiClean = false;
16246                }
16247                app.trimMemoryLevel = 0;
16248            }
16249        }
16250
16251        if (mAlwaysFinishActivities) {
16252            // Need to do this on its own message because the stack may not
16253            // be in a consistent state at this point.
16254            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16255        }
16256
16257        if (allChanged) {
16258            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16259        }
16260
16261        if (mProcessStats.shouldWriteNowLocked(now)) {
16262            mHandler.post(new Runnable() {
16263                @Override public void run() {
16264                    synchronized (ActivityManagerService.this) {
16265                        mProcessStats.writeStateAsyncLocked();
16266                    }
16267                }
16268            });
16269        }
16270
16271        if (DEBUG_OOM_ADJ) {
16272            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16273        }
16274    }
16275
16276    final void trimApplications() {
16277        synchronized (this) {
16278            int i;
16279
16280            // First remove any unused application processes whose package
16281            // has been removed.
16282            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16283                final ProcessRecord app = mRemovedProcesses.get(i);
16284                if (app.activities.size() == 0
16285                        && app.curReceiver == null && app.services.size() == 0) {
16286                    Slog.i(
16287                        TAG, "Exiting empty application process "
16288                        + app.processName + " ("
16289                        + (app.thread != null ? app.thread.asBinder() : null)
16290                        + ")\n");
16291                    if (app.pid > 0 && app.pid != MY_PID) {
16292                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16293                                app.processName, app.setAdj, "empty");
16294                        app.killedByAm = true;
16295                        Process.killProcessQuiet(app.pid);
16296                    } else {
16297                        try {
16298                            app.thread.scheduleExit();
16299                        } catch (Exception e) {
16300                            // Ignore exceptions.
16301                        }
16302                    }
16303                    cleanUpApplicationRecordLocked(app, false, true, -1);
16304                    mRemovedProcesses.remove(i);
16305
16306                    if (app.persistent) {
16307                        if (app.persistent) {
16308                            addAppLocked(app.info, false);
16309                        }
16310                    }
16311                }
16312            }
16313
16314            // Now update the oom adj for all processes.
16315            updateOomAdjLocked();
16316        }
16317    }
16318
16319    /** This method sends the specified signal to each of the persistent apps */
16320    public void signalPersistentProcesses(int sig) throws RemoteException {
16321        if (sig != Process.SIGNAL_USR1) {
16322            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16323        }
16324
16325        synchronized (this) {
16326            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16327                    != PackageManager.PERMISSION_GRANTED) {
16328                throw new SecurityException("Requires permission "
16329                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16330            }
16331
16332            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16333                ProcessRecord r = mLruProcesses.get(i);
16334                if (r.thread != null && r.persistent) {
16335                    Process.sendSignal(r.pid, sig);
16336                }
16337            }
16338        }
16339    }
16340
16341    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16342        if (proc == null || proc == mProfileProc) {
16343            proc = mProfileProc;
16344            path = mProfileFile;
16345            profileType = mProfileType;
16346            clearProfilerLocked();
16347        }
16348        if (proc == null) {
16349            return;
16350        }
16351        try {
16352            proc.thread.profilerControl(false, path, null, profileType);
16353        } catch (RemoteException e) {
16354            throw new IllegalStateException("Process disappeared");
16355        }
16356    }
16357
16358    private void clearProfilerLocked() {
16359        if (mProfileFd != null) {
16360            try {
16361                mProfileFd.close();
16362            } catch (IOException e) {
16363            }
16364        }
16365        mProfileApp = null;
16366        mProfileProc = null;
16367        mProfileFile = null;
16368        mProfileType = 0;
16369        mAutoStopProfiler = false;
16370    }
16371
16372    public boolean profileControl(String process, int userId, boolean start,
16373            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16374
16375        try {
16376            synchronized (this) {
16377                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16378                // its own permission.
16379                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16380                        != PackageManager.PERMISSION_GRANTED) {
16381                    throw new SecurityException("Requires permission "
16382                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16383                }
16384
16385                if (start && fd == null) {
16386                    throw new IllegalArgumentException("null fd");
16387                }
16388
16389                ProcessRecord proc = null;
16390                if (process != null) {
16391                    proc = findProcessLocked(process, userId, "profileControl");
16392                }
16393
16394                if (start && (proc == null || proc.thread == null)) {
16395                    throw new IllegalArgumentException("Unknown process: " + process);
16396                }
16397
16398                if (start) {
16399                    stopProfilerLocked(null, null, 0);
16400                    setProfileApp(proc.info, proc.processName, path, fd, false);
16401                    mProfileProc = proc;
16402                    mProfileType = profileType;
16403                    try {
16404                        fd = fd.dup();
16405                    } catch (IOException e) {
16406                        fd = null;
16407                    }
16408                    proc.thread.profilerControl(start, path, fd, profileType);
16409                    fd = null;
16410                    mProfileFd = null;
16411                } else {
16412                    stopProfilerLocked(proc, path, profileType);
16413                    if (fd != null) {
16414                        try {
16415                            fd.close();
16416                        } catch (IOException e) {
16417                        }
16418                    }
16419                }
16420
16421                return true;
16422            }
16423        } catch (RemoteException e) {
16424            throw new IllegalStateException("Process disappeared");
16425        } finally {
16426            if (fd != null) {
16427                try {
16428                    fd.close();
16429                } catch (IOException e) {
16430                }
16431            }
16432        }
16433    }
16434
16435    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16436        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16437                userId, true, true, callName, null);
16438        ProcessRecord proc = null;
16439        try {
16440            int pid = Integer.parseInt(process);
16441            synchronized (mPidsSelfLocked) {
16442                proc = mPidsSelfLocked.get(pid);
16443            }
16444        } catch (NumberFormatException e) {
16445        }
16446
16447        if (proc == null) {
16448            ArrayMap<String, SparseArray<ProcessRecord>> all
16449                    = mProcessNames.getMap();
16450            SparseArray<ProcessRecord> procs = all.get(process);
16451            if (procs != null && procs.size() > 0) {
16452                proc = procs.valueAt(0);
16453                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16454                    for (int i=1; i<procs.size(); i++) {
16455                        ProcessRecord thisProc = procs.valueAt(i);
16456                        if (thisProc.userId == userId) {
16457                            proc = thisProc;
16458                            break;
16459                        }
16460                    }
16461                }
16462            }
16463        }
16464
16465        return proc;
16466    }
16467
16468    public boolean dumpHeap(String process, int userId, boolean managed,
16469            String path, ParcelFileDescriptor fd) throws RemoteException {
16470
16471        try {
16472            synchronized (this) {
16473                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16474                // its own permission (same as profileControl).
16475                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16476                        != PackageManager.PERMISSION_GRANTED) {
16477                    throw new SecurityException("Requires permission "
16478                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16479                }
16480
16481                if (fd == null) {
16482                    throw new IllegalArgumentException("null fd");
16483                }
16484
16485                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16486                if (proc == null || proc.thread == null) {
16487                    throw new IllegalArgumentException("Unknown process: " + process);
16488                }
16489
16490                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16491                if (!isDebuggable) {
16492                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16493                        throw new SecurityException("Process not debuggable: " + proc);
16494                    }
16495                }
16496
16497                proc.thread.dumpHeap(managed, path, fd);
16498                fd = null;
16499                return true;
16500            }
16501        } catch (RemoteException e) {
16502            throw new IllegalStateException("Process disappeared");
16503        } finally {
16504            if (fd != null) {
16505                try {
16506                    fd.close();
16507                } catch (IOException e) {
16508                }
16509            }
16510        }
16511    }
16512
16513    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16514    public void monitor() {
16515        synchronized (this) { }
16516    }
16517
16518    void onCoreSettingsChange(Bundle settings) {
16519        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16520            ProcessRecord processRecord = mLruProcesses.get(i);
16521            try {
16522                if (processRecord.thread != null) {
16523                    processRecord.thread.setCoreSettings(settings);
16524                }
16525            } catch (RemoteException re) {
16526                /* ignore */
16527            }
16528        }
16529    }
16530
16531    // Multi-user methods
16532
16533    /**
16534     * Start user, if its not already running, but don't bring it to foreground.
16535     */
16536    @Override
16537    public boolean startUserInBackground(final int userId) {
16538        return startUser(userId, /* foreground */ false);
16539    }
16540
16541    /**
16542     * Refreshes the list of users related to the current user when either a
16543     * user switch happens or when a new related user is started in the
16544     * background.
16545     */
16546    private void updateCurrentProfileIdsLocked() {
16547        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16548                mCurrentUserId, false /* enabledOnly */);
16549        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16550        for (int i = 0; i < currentProfileIds.length; i++) {
16551            currentProfileIds[i] = profiles.get(i).id;
16552        }
16553        mCurrentProfileIds = currentProfileIds;
16554    }
16555
16556    private Set getProfileIdsLocked(int userId) {
16557        Set userIds = new HashSet<Integer>();
16558        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16559                userId, false /* enabledOnly */);
16560        for (UserInfo user : profiles) {
16561            userIds.add(Integer.valueOf(user.id));
16562        }
16563        return userIds;
16564    }
16565
16566    @Override
16567    public boolean switchUser(final int userId) {
16568        return startUser(userId, /* foregound */ true);
16569    }
16570
16571    private boolean startUser(final int userId, boolean foreground) {
16572        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16573                != PackageManager.PERMISSION_GRANTED) {
16574            String msg = "Permission Denial: switchUser() from pid="
16575                    + Binder.getCallingPid()
16576                    + ", uid=" + Binder.getCallingUid()
16577                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16578            Slog.w(TAG, msg);
16579            throw new SecurityException(msg);
16580        }
16581
16582        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16583
16584        final long ident = Binder.clearCallingIdentity();
16585        try {
16586            synchronized (this) {
16587                final int oldUserId = mCurrentUserId;
16588                if (oldUserId == userId) {
16589                    return true;
16590                }
16591
16592                mStackSupervisor.setLockTaskModeLocked(null);
16593
16594                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16595                if (userInfo == null) {
16596                    Slog.w(TAG, "No user info for user #" + userId);
16597                    return false;
16598                }
16599
16600                if (foreground) {
16601                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16602                            R.anim.screen_user_enter);
16603                }
16604
16605                boolean needStart = false;
16606
16607                // If the user we are switching to is not currently started, then
16608                // we need to start it now.
16609                if (mStartedUsers.get(userId) == null) {
16610                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16611                    updateStartedUserArrayLocked();
16612                    needStart = true;
16613                }
16614
16615                final Integer userIdInt = Integer.valueOf(userId);
16616                mUserLru.remove(userIdInt);
16617                mUserLru.add(userIdInt);
16618
16619                if (foreground) {
16620                    mCurrentUserId = userId;
16621                    updateCurrentProfileIdsLocked();
16622                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16623                    // Once the internal notion of the active user has switched, we lock the device
16624                    // with the option to show the user switcher on the keyguard.
16625                    mWindowManager.lockNow(null);
16626                } else {
16627                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16628                    updateCurrentProfileIdsLocked();
16629                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16630                    mUserLru.remove(currentUserIdInt);
16631                    mUserLru.add(currentUserIdInt);
16632                }
16633
16634                final UserStartedState uss = mStartedUsers.get(userId);
16635
16636                // Make sure user is in the started state.  If it is currently
16637                // stopping, we need to knock that off.
16638                if (uss.mState == UserStartedState.STATE_STOPPING) {
16639                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16640                    // so we can just fairly silently bring the user back from
16641                    // the almost-dead.
16642                    uss.mState = UserStartedState.STATE_RUNNING;
16643                    updateStartedUserArrayLocked();
16644                    needStart = true;
16645                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16646                    // This means ACTION_SHUTDOWN has been sent, so we will
16647                    // need to treat this as a new boot of the user.
16648                    uss.mState = UserStartedState.STATE_BOOTING;
16649                    updateStartedUserArrayLocked();
16650                    needStart = true;
16651                }
16652
16653                if (uss.mState == UserStartedState.STATE_BOOTING) {
16654                    // Booting up a new user, need to tell system services about it.
16655                    // Note that this is on the same handler as scheduling of broadcasts,
16656                    // which is important because it needs to go first.
16657                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16658                }
16659
16660                if (foreground) {
16661                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16662                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16663                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16664                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16665                            oldUserId, userId, uss));
16666                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16667                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16668                }
16669
16670                if (needStart) {
16671                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16672                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16673                            | Intent.FLAG_RECEIVER_FOREGROUND);
16674                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16675                    broadcastIntentLocked(null, null, intent,
16676                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16677                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16678                }
16679
16680                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16681                    if (userId != UserHandle.USER_OWNER) {
16682                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16683                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16684                        broadcastIntentLocked(null, null, intent, null,
16685                                new IIntentReceiver.Stub() {
16686                                    public void performReceive(Intent intent, int resultCode,
16687                                            String data, Bundle extras, boolean ordered,
16688                                            boolean sticky, int sendingUser) {
16689                                        userInitialized(uss, userId);
16690                                    }
16691                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16692                                true, false, MY_PID, Process.SYSTEM_UID,
16693                                userId);
16694                        uss.initializing = true;
16695                    } else {
16696                        getUserManagerLocked().makeInitialized(userInfo.id);
16697                    }
16698                }
16699
16700                if (foreground) {
16701                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16702                    if (homeInFront) {
16703                        startHomeActivityLocked(userId);
16704                    } else {
16705                        mStackSupervisor.resumeTopActivitiesLocked();
16706                    }
16707                    EventLogTags.writeAmSwitchUser(userId);
16708                    getUserManagerLocked().userForeground(userId);
16709                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16710                } else {
16711                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16712                }
16713
16714                if (needStart) {
16715                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16716                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16717                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16718                    broadcastIntentLocked(null, null, intent,
16719                            null, new IIntentReceiver.Stub() {
16720                                @Override
16721                                public void performReceive(Intent intent, int resultCode, String data,
16722                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16723                                        throws RemoteException {
16724                                }
16725                            }, 0, null, null,
16726                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16727                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16728                }
16729            }
16730        } finally {
16731            Binder.restoreCallingIdentity(ident);
16732        }
16733
16734        return true;
16735    }
16736
16737    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16738        long ident = Binder.clearCallingIdentity();
16739        try {
16740            Intent intent;
16741            if (oldUserId >= 0) {
16742                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16743                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16744                        | Intent.FLAG_RECEIVER_FOREGROUND);
16745                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16746                broadcastIntentLocked(null, null, intent,
16747                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16748                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16749            }
16750            if (newUserId >= 0) {
16751                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16752                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16753                        | Intent.FLAG_RECEIVER_FOREGROUND);
16754                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16755                broadcastIntentLocked(null, null, intent,
16756                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16757                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16758                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16759                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16760                        | Intent.FLAG_RECEIVER_FOREGROUND);
16761                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16762                broadcastIntentLocked(null, null, intent,
16763                        null, null, 0, null, null,
16764                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16765                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16766            }
16767        } finally {
16768            Binder.restoreCallingIdentity(ident);
16769        }
16770    }
16771
16772    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16773            final int newUserId) {
16774        final int N = mUserSwitchObservers.beginBroadcast();
16775        if (N > 0) {
16776            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16777                int mCount = 0;
16778                @Override
16779                public void sendResult(Bundle data) throws RemoteException {
16780                    synchronized (ActivityManagerService.this) {
16781                        if (mCurUserSwitchCallback == this) {
16782                            mCount++;
16783                            if (mCount == N) {
16784                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16785                            }
16786                        }
16787                    }
16788                }
16789            };
16790            synchronized (this) {
16791                uss.switching = true;
16792                mCurUserSwitchCallback = callback;
16793            }
16794            for (int i=0; i<N; i++) {
16795                try {
16796                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16797                            newUserId, callback);
16798                } catch (RemoteException e) {
16799                }
16800            }
16801        } else {
16802            synchronized (this) {
16803                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16804            }
16805        }
16806        mUserSwitchObservers.finishBroadcast();
16807    }
16808
16809    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16810        synchronized (this) {
16811            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16812            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16813        }
16814    }
16815
16816    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16817        mCurUserSwitchCallback = null;
16818        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16819        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16820                oldUserId, newUserId, uss));
16821    }
16822
16823    void userInitialized(UserStartedState uss, int newUserId) {
16824        completeSwitchAndInitalize(uss, newUserId, true, false);
16825    }
16826
16827    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16828        completeSwitchAndInitalize(uss, newUserId, false, true);
16829    }
16830
16831    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16832            boolean clearInitializing, boolean clearSwitching) {
16833        boolean unfrozen = false;
16834        synchronized (this) {
16835            if (clearInitializing) {
16836                uss.initializing = false;
16837                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16838            }
16839            if (clearSwitching) {
16840                uss.switching = false;
16841            }
16842            if (!uss.switching && !uss.initializing) {
16843                mWindowManager.stopFreezingScreen();
16844                unfrozen = true;
16845            }
16846        }
16847        if (unfrozen) {
16848            final int N = mUserSwitchObservers.beginBroadcast();
16849            for (int i=0; i<N; i++) {
16850                try {
16851                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16852                } catch (RemoteException e) {
16853                }
16854            }
16855            mUserSwitchObservers.finishBroadcast();
16856        }
16857    }
16858
16859    void scheduleStartProfilesLocked() {
16860        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16861            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16862                    DateUtils.SECOND_IN_MILLIS);
16863        }
16864    }
16865
16866    void startProfilesLocked() {
16867        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16868        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16869                mCurrentUserId, false /* enabledOnly */);
16870        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16871        for (UserInfo user : profiles) {
16872            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16873                    && user.id != mCurrentUserId) {
16874                toStart.add(user);
16875            }
16876        }
16877        final int n = toStart.size();
16878        int i = 0;
16879        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16880            startUserInBackground(toStart.get(i).id);
16881        }
16882        if (i < n) {
16883            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16884        }
16885    }
16886
16887    void finishUserBoot(UserStartedState uss) {
16888        synchronized (this) {
16889            if (uss.mState == UserStartedState.STATE_BOOTING
16890                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16891                uss.mState = UserStartedState.STATE_RUNNING;
16892                final int userId = uss.mHandle.getIdentifier();
16893                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16894                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16895                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16896                broadcastIntentLocked(null, null, intent,
16897                        null, null, 0, null, null,
16898                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16899                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16900            }
16901        }
16902    }
16903
16904    void finishUserSwitch(UserStartedState uss) {
16905        synchronized (this) {
16906            finishUserBoot(uss);
16907
16908            startProfilesLocked();
16909
16910            int num = mUserLru.size();
16911            int i = 0;
16912            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16913                Integer oldUserId = mUserLru.get(i);
16914                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16915                if (oldUss == null) {
16916                    // Shouldn't happen, but be sane if it does.
16917                    mUserLru.remove(i);
16918                    num--;
16919                    continue;
16920                }
16921                if (oldUss.mState == UserStartedState.STATE_STOPPING
16922                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16923                    // This user is already stopping, doesn't count.
16924                    num--;
16925                    i++;
16926                    continue;
16927                }
16928                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16929                    // Owner and current can't be stopped, but count as running.
16930                    i++;
16931                    continue;
16932                }
16933                // This is a user to be stopped.
16934                stopUserLocked(oldUserId, null);
16935                num--;
16936                i++;
16937            }
16938        }
16939    }
16940
16941    @Override
16942    public int stopUser(final int userId, final IStopUserCallback callback) {
16943        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16944                != PackageManager.PERMISSION_GRANTED) {
16945            String msg = "Permission Denial: switchUser() from pid="
16946                    + Binder.getCallingPid()
16947                    + ", uid=" + Binder.getCallingUid()
16948                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16949            Slog.w(TAG, msg);
16950            throw new SecurityException(msg);
16951        }
16952        if (userId <= 0) {
16953            throw new IllegalArgumentException("Can't stop primary user " + userId);
16954        }
16955        synchronized (this) {
16956            return stopUserLocked(userId, callback);
16957        }
16958    }
16959
16960    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16961        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16962        if (mCurrentUserId == userId) {
16963            return ActivityManager.USER_OP_IS_CURRENT;
16964        }
16965
16966        final UserStartedState uss = mStartedUsers.get(userId);
16967        if (uss == null) {
16968            // User is not started, nothing to do...  but we do need to
16969            // callback if requested.
16970            if (callback != null) {
16971                mHandler.post(new Runnable() {
16972                    @Override
16973                    public void run() {
16974                        try {
16975                            callback.userStopped(userId);
16976                        } catch (RemoteException e) {
16977                        }
16978                    }
16979                });
16980            }
16981            return ActivityManager.USER_OP_SUCCESS;
16982        }
16983
16984        if (callback != null) {
16985            uss.mStopCallbacks.add(callback);
16986        }
16987
16988        if (uss.mState != UserStartedState.STATE_STOPPING
16989                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16990            uss.mState = UserStartedState.STATE_STOPPING;
16991            updateStartedUserArrayLocked();
16992
16993            long ident = Binder.clearCallingIdentity();
16994            try {
16995                // We are going to broadcast ACTION_USER_STOPPING and then
16996                // once that is done send a final ACTION_SHUTDOWN and then
16997                // stop the user.
16998                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16999                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17000                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17001                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17002                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17003                // This is the result receiver for the final shutdown broadcast.
17004                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17005                    @Override
17006                    public void performReceive(Intent intent, int resultCode, String data,
17007                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17008                        finishUserStop(uss);
17009                    }
17010                };
17011                // This is the result receiver for the initial stopping broadcast.
17012                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17013                    @Override
17014                    public void performReceive(Intent intent, int resultCode, String data,
17015                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17016                        // On to the next.
17017                        synchronized (ActivityManagerService.this) {
17018                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17019                                // Whoops, we are being started back up.  Abort, abort!
17020                                return;
17021                            }
17022                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17023                        }
17024                        mSystemServiceManager.stopUser(userId);
17025                        broadcastIntentLocked(null, null, shutdownIntent,
17026                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17027                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17028                    }
17029                };
17030                // Kick things off.
17031                broadcastIntentLocked(null, null, stoppingIntent,
17032                        null, stoppingReceiver, 0, null, null,
17033                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17034                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17035            } finally {
17036                Binder.restoreCallingIdentity(ident);
17037            }
17038        }
17039
17040        return ActivityManager.USER_OP_SUCCESS;
17041    }
17042
17043    void finishUserStop(UserStartedState uss) {
17044        final int userId = uss.mHandle.getIdentifier();
17045        boolean stopped;
17046        ArrayList<IStopUserCallback> callbacks;
17047        synchronized (this) {
17048            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17049            if (mStartedUsers.get(userId) != uss) {
17050                stopped = false;
17051            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17052                stopped = false;
17053            } else {
17054                stopped = true;
17055                // User can no longer run.
17056                mStartedUsers.remove(userId);
17057                mUserLru.remove(Integer.valueOf(userId));
17058                updateStartedUserArrayLocked();
17059
17060                // Clean up all state and processes associated with the user.
17061                // Kill all the processes for the user.
17062                forceStopUserLocked(userId, "finish user");
17063            }
17064        }
17065
17066        for (int i=0; i<callbacks.size(); i++) {
17067            try {
17068                if (stopped) callbacks.get(i).userStopped(userId);
17069                else callbacks.get(i).userStopAborted(userId);
17070            } catch (RemoteException e) {
17071            }
17072        }
17073
17074        if (stopped) {
17075            mSystemServiceManager.cleanupUser(userId);
17076            synchronized (this) {
17077                mStackSupervisor.removeUserLocked(userId);
17078            }
17079        }
17080    }
17081
17082    @Override
17083    public UserInfo getCurrentUser() {
17084        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17085                != PackageManager.PERMISSION_GRANTED) && (
17086                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17087                != PackageManager.PERMISSION_GRANTED)) {
17088            String msg = "Permission Denial: getCurrentUser() from pid="
17089                    + Binder.getCallingPid()
17090                    + ", uid=" + Binder.getCallingUid()
17091                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17092            Slog.w(TAG, msg);
17093            throw new SecurityException(msg);
17094        }
17095        synchronized (this) {
17096            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17097        }
17098    }
17099
17100    int getCurrentUserIdLocked() {
17101        return mCurrentUserId;
17102    }
17103
17104    @Override
17105    public boolean isUserRunning(int userId, boolean orStopped) {
17106        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17107                != PackageManager.PERMISSION_GRANTED) {
17108            String msg = "Permission Denial: isUserRunning() from pid="
17109                    + Binder.getCallingPid()
17110                    + ", uid=" + Binder.getCallingUid()
17111                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17112            Slog.w(TAG, msg);
17113            throw new SecurityException(msg);
17114        }
17115        synchronized (this) {
17116            return isUserRunningLocked(userId, orStopped);
17117        }
17118    }
17119
17120    boolean isUserRunningLocked(int userId, boolean orStopped) {
17121        UserStartedState state = mStartedUsers.get(userId);
17122        if (state == null) {
17123            return false;
17124        }
17125        if (orStopped) {
17126            return true;
17127        }
17128        return state.mState != UserStartedState.STATE_STOPPING
17129                && state.mState != UserStartedState.STATE_SHUTDOWN;
17130    }
17131
17132    @Override
17133    public int[] getRunningUserIds() {
17134        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17135                != PackageManager.PERMISSION_GRANTED) {
17136            String msg = "Permission Denial: isUserRunning() from pid="
17137                    + Binder.getCallingPid()
17138                    + ", uid=" + Binder.getCallingUid()
17139                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17140            Slog.w(TAG, msg);
17141            throw new SecurityException(msg);
17142        }
17143        synchronized (this) {
17144            return mStartedUserArray;
17145        }
17146    }
17147
17148    private void updateStartedUserArrayLocked() {
17149        int num = 0;
17150        for (int i=0; i<mStartedUsers.size();  i++) {
17151            UserStartedState uss = mStartedUsers.valueAt(i);
17152            // This list does not include stopping users.
17153            if (uss.mState != UserStartedState.STATE_STOPPING
17154                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17155                num++;
17156            }
17157        }
17158        mStartedUserArray = new int[num];
17159        num = 0;
17160        for (int i=0; i<mStartedUsers.size();  i++) {
17161            UserStartedState uss = mStartedUsers.valueAt(i);
17162            if (uss.mState != UserStartedState.STATE_STOPPING
17163                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17164                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17165                num++;
17166            }
17167        }
17168    }
17169
17170    @Override
17171    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17172        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17173                != PackageManager.PERMISSION_GRANTED) {
17174            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17175                    + Binder.getCallingPid()
17176                    + ", uid=" + Binder.getCallingUid()
17177                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17178            Slog.w(TAG, msg);
17179            throw new SecurityException(msg);
17180        }
17181
17182        mUserSwitchObservers.register(observer);
17183    }
17184
17185    @Override
17186    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17187        mUserSwitchObservers.unregister(observer);
17188    }
17189
17190    private boolean userExists(int userId) {
17191        if (userId == 0) {
17192            return true;
17193        }
17194        UserManagerService ums = getUserManagerLocked();
17195        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17196    }
17197
17198    int[] getUsersLocked() {
17199        UserManagerService ums = getUserManagerLocked();
17200        return ums != null ? ums.getUserIds() : new int[] { 0 };
17201    }
17202
17203    UserManagerService getUserManagerLocked() {
17204        if (mUserManager == null) {
17205            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17206            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17207        }
17208        return mUserManager;
17209    }
17210
17211    private int applyUserId(int uid, int userId) {
17212        return UserHandle.getUid(userId, uid);
17213    }
17214
17215    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17216        if (info == null) return null;
17217        ApplicationInfo newInfo = new ApplicationInfo(info);
17218        newInfo.uid = applyUserId(info.uid, userId);
17219        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17220                + info.packageName;
17221        return newInfo;
17222    }
17223
17224    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17225        if (aInfo == null
17226                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17227            return aInfo;
17228        }
17229
17230        ActivityInfo info = new ActivityInfo(aInfo);
17231        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17232        return info;
17233    }
17234
17235    private final class LocalService extends ActivityManagerInternal {
17236        @Override
17237        public void goingToSleep() {
17238            ActivityManagerService.this.goingToSleep();
17239        }
17240
17241        @Override
17242        public void wakingUp() {
17243            ActivityManagerService.this.wakingUp();
17244        }
17245    }
17246
17247    /**
17248     * An implementation of IAppTask, that allows an app to manage its own tasks via
17249     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17250     * only the process that calls getAppTasks() can call the AppTask methods.
17251     */
17252    class AppTaskImpl extends IAppTask.Stub {
17253        private int mTaskId;
17254        private int mCallingUid;
17255
17256        public AppTaskImpl(int taskId, int callingUid) {
17257            mTaskId = taskId;
17258            mCallingUid = callingUid;
17259        }
17260
17261        @Override
17262        public void finishAndRemoveTask() {
17263            // Ensure that we are called from the same process that created this AppTask
17264            if (mCallingUid != Binder.getCallingUid()) {
17265                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17266                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17267                return;
17268            }
17269
17270            synchronized (ActivityManagerService.this) {
17271                long origId = Binder.clearCallingIdentity();
17272                try {
17273                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17274                    if (tr != null) {
17275                        // Only kill the process if we are not a new document
17276                        int flags = tr.getBaseIntent().getFlags();
17277                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17278                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17279                        removeTaskByIdLocked(mTaskId,
17280                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17281                    }
17282                } finally {
17283                    Binder.restoreCallingIdentity(origId);
17284                }
17285            }
17286        }
17287
17288        @Override
17289        public ActivityManager.RecentTaskInfo getTaskInfo() {
17290            // Ensure that we are called from the same process that created this AppTask
17291            if (mCallingUid != Binder.getCallingUid()) {
17292                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17293                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17294                return null;
17295            }
17296
17297            synchronized (ActivityManagerService.this) {
17298                long origId = Binder.clearCallingIdentity();
17299                try {
17300                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17301                    if (tr != null) {
17302                        return createRecentTaskInfoFromTaskRecord(tr);
17303                    }
17304                } finally {
17305                    Binder.restoreCallingIdentity(origId);
17306                }
17307                return null;
17308            }
17309        }
17310    }
17311}
17312